From badc1a2fb65dba23d1454720c5f6054ac1b3baed Mon Sep 17 00:00:00 2001 From: sagilaufer1992 Date: Wed, 16 Mar 2022 10:33:36 +0200 Subject: [PATCH] Feature terragrunt version for templates (#261) * added TG version to wherever TF is declared and used, without enforcements * require the presence of TG version in TG blueprints and ONLY in TG blueprints * tested red paths in unit tests for tg version * added integration test for creating a tg-template + minor issues with setting tg-version * update readme * rebased on main Co-authored-by: update generated docs action --- client/model.go | 2 + client/template.go | 12 +++++ client/template_test.go | 53 +++++++++++++++++++ docs/data-sources/template.md | 1 + docs/resources/template.md | 1 + env0/data_template.go | 9 ++++ env0/resource_template.go | 12 ++++- .../004_template/expected_outputs.json | 3 +- tests/integration/004_template/main.tf | 18 +++++++ tests/integration/012_environment/main.tf | 1 - 10 files changed, 109 insertions(+), 3 deletions(-) diff --git a/client/model.go b/client/model.go index 966652a6..55fed9ee 100644 --- a/client/model.go +++ b/client/model.go @@ -218,6 +218,7 @@ type TemplateCreatePayload struct { Revision string `json:"revision"` OrganizationId string `json:"organizationId"` TerraformVersion string `json:"terraformVersion"` + TerragruntVersion string `json:"terragruntVersion,omitempty"` IsGitlabEnterprise bool `json:"isGitLabEnterprise"` BitbucketClientKey string `json:"bitbucketClientKey,omitempty"` } @@ -269,6 +270,7 @@ type Template struct { GitlabProjectId int `json:"gitlabProjectId,omitempty"` UpdatedAt string `json:"updatedAt"` TerraformVersion string `json:"terraformVersion"` + TerragruntVersion string `json:"terragruntVersion,omitempty"` IsDeleted bool `json:"isDeleted,omitempty"` BitbucketClientKey string `json:"bitbucketClientKey"` } diff --git a/client/template.go b/client/template.go index 08c5ae3d..0ccda4b7 100644 --- a/client/template.go +++ b/client/template.go @@ -15,6 +15,12 @@ func (self *ApiClient) TemplateCreate(payload TemplateCreatePayload) (Template, if payload.OrganizationId != "" { return Template{}, errors.New("Must not specify organizationId") } + if payload.Type != "terragrunt" && payload.TerragruntVersion != "" { + return Template{}, errors.New("Can't define terragrunt version for non-terragrunt blueprint") + } + if payload.Type == "terragrunt" && payload.TerragruntVersion == "" { + return Template{}, errors.New("Must supply Terragrunt version") + } organizationId, err := self.organizationId() if err != nil { return Template{}, nil @@ -49,6 +55,12 @@ func (self *ApiClient) TemplateUpdate(id string, payload TemplateCreatePayload) if payload.OrganizationId != "" { return Template{}, errors.New("Must not specify organizationId") } + if payload.Type != "terragrunt" && payload.TerragruntVersion != "" { + return Template{}, errors.New("Can't define terragrunt version for non-terragrunt blueprint") + } + if payload.Type == "terragrunt" && payload.TerragruntVersion == "" { + return Template{}, errors.New("Must supply Terragrunt version") + } organizationId, err := self.organizationId() if err != nil { return Template{}, err diff --git a/client/template_test.go b/client/template_test.go index d3742006..93eb17c8 100644 --- a/client/template_test.go +++ b/client/template_test.go @@ -199,4 +199,57 @@ var _ = Describe("Templates Client", func() { httpCall.Times(1) }) }) + + Describe("Terragrunt version errors", func() { + var err error + + Describe("type is tg and no tg version supplied", func() { + It("Should fail on create", func() { + createTemplatePayload := TemplateCreatePayload{} + copier.Copy(&createTemplatePayload, &mockTemplate) + + createTemplatePayload.Type = "terragrunt" + + _, err = apiClient.TemplateCreate(createTemplatePayload) + + Expect(err).To(Not(BeNil())) + }) + + It("Should fail on update", func() { + createTemplatePayload := TemplateCreatePayload{} + copier.Copy(&createTemplatePayload, &mockTemplate) + + createTemplatePayload.Type = "terragrunt" + + _, err = apiClient.TemplateUpdate(mockTemplate.Id, createTemplatePayload) + + Expect(err).To(Not(BeNil())) + }) + }) + + Describe("type is NOT tg and tg version IS supplied", func() { + It("Should fail on create", func() { + createTemplatePayload := TemplateCreatePayload{} + copier.Copy(&createTemplatePayload, &mockTemplate) + + createTemplatePayload.Type = "terraform" + createTemplatePayload.TerragruntVersion = "0.29.0" + + _, err = apiClient.TemplateCreate(createTemplatePayload) + + Expect(err).To(Not(BeNil())) + }) + + It("Should fail on update", func() { + createTemplatePayload := TemplateCreatePayload{} + copier.Copy(&createTemplatePayload, &mockTemplate) + + createTemplatePayload.Type = "terragrunt" + + _, err = apiClient.TemplateUpdate(mockTemplate.Id, createTemplatePayload) + + Expect(err).To(Not(BeNil())) + }) + }) + }) }) diff --git a/docs/data-sources/template.md b/docs/data-sources/template.md index a6def21f..6cc29dd9 100644 --- a/docs/data-sources/template.md +++ b/docs/data-sources/template.md @@ -28,6 +28,7 @@ data "env0_template" "example" { - **id** (String) id of the template - **is_gitlab_enterprise** (Boolean) Does this template use gitlab enterprise repository? - **name** (String) the name of the template +- **terragrunt_version** (String) terragrunt version to use - **token_id** (String) The token id used for private git repos or for integration with GitLab ### Read-Only diff --git a/docs/resources/template.md b/docs/resources/template.md index ae580fd5..dc5e89f7 100644 --- a/docs/resources/template.md +++ b/docs/resources/template.md @@ -59,6 +59,7 @@ resource "env0_template_project_assignment" "assignment" { - **revision** (String) source code revision (branch / tag) to use - **ssh_keys** (List of Map of String) an array of references to 'data_ssh_key' to use when accessing git over ssh - **terraform_version** (String) Terraform version to use +- **terragrunt_version** (String) Terragrunt version to use - **token_id** (String) The token id used for private git repos or for integration with GitLab, you can get this value by using a data resource of an existing Gitlab template or contact our support team - **type** (String) 'terraform' or 'terragrunt' diff --git a/env0/data_template.go b/env0/data_template.go index 9f1c8fa2..b597b5d7 100644 --- a/env0/data_template.go +++ b/env0/data_template.go @@ -94,6 +94,12 @@ func dataTemplate() *schema.Resource { Description: "terraform version to use", Computed: true, }, + "terragrunt_version": { + Type: schema.TypeString, + Description: "terragrunt version to use", + Computed: true, + Optional: true, + }, "is_gitlab_enterprise": { Type: schema.TypeBool, Description: "Does this template use gitlab enterprise repository?", @@ -128,6 +134,9 @@ func dataTemplateRead(ctx context.Context, d *schema.ResourceData, meta interfac d.Set("type", template.Type) d.Set("project_ids", template.ProjectIds) d.Set("terraform_version", template.TerraformVersion) + if template.TerragruntVersion != "" { + d.Set("terragrunt_version", template.TerragruntVersion) + } if template.Retry.OnDeploy != nil { d.Set("retries_on_deploy", template.Retry.OnDeploy.Times) d.Set("retry_on_deploy_only_when_matches_regex", template.Retry.OnDeploy.ErrorRegex) diff --git a/env0/resource_template.go b/env0/resource_template.go index 9eaa376a..2bfe06b4 100644 --- a/env0/resource_template.go +++ b/env0/resource_template.go @@ -119,6 +119,11 @@ func resourceTemplate() *schema.Resource { Optional: true, Default: "0.15.1", }, + "terragrunt_version": { + Type: schema.TypeString, + Description: "Terragrunt version to use", + Optional: true, + }, "is_gitlab_enterprise": { Type: schema.TypeBool, Description: "Does this template use gitlab enterprise repository?", @@ -220,11 +225,16 @@ func templateCreatePayloadFromParameters(d *schema.ResourceData) (client.Templat if terraformVersion, ok := d.GetOk("terraform_version"); ok { result.TerraformVersion = terraformVersion.(string) } - + if terragruntVersion, ok := d.GetOk("terragrunt_version"); ok { + result.TerragruntVersion = terragruntVersion.(string) + } if bitbucketClientKey, ok := d.GetOk("bitbucket_client_key"); ok { result.BitbucketClientKey = bitbucketClientKey.(string) } + if terragruntVersion, ok := d.GetOk("terragrunt_version"); ok { + result.TerragruntVersion = terragruntVersion.(string) + } return result, nil } diff --git a/tests/integration/004_template/expected_outputs.json b/tests/integration/004_template/expected_outputs.json index de83e307..0477a1e0 100644 --- a/tests/integration/004_template/expected_outputs.json +++ b/tests/integration/004_template/expected_outputs.json @@ -3,5 +3,6 @@ "tested2_template_name": "tested1-", "tested2_template_repository": "https://github.com/env0/templates", "tested1_template_repository": "https://gitlab.com/env0/gitlab-vcs-integration-tests.git", - "tested2_template_path": "second" + "tested2_template_path": "second", + "tg_tg_version" : "0.35.0" } diff --git a/tests/integration/004_template/main.tf b/tests/integration/004_template/main.tf index 19aba0a6..7dd8bbfa 100644 --- a/tests/integration/004_template/main.tf +++ b/tests/integration/004_template/main.tf @@ -45,6 +45,15 @@ resource "env0_template" "tested2" { terraform_version = "0.15.1" } +resource "env0_template" "template_tg" { + name = "Template for environment resource - tg" + type = "terragrunt" + repository = "https://github.com/env0/templates" + path = "terragrunt/misc/null-resource" + terraform_version = "0.15.1" + terragrunt_version = "0.35.0" +} + resource "env0_configuration_variable" "in_a_template" { name = "fake_key" value = "fake value" @@ -68,6 +77,12 @@ data "env0_template" "tested1" { env0_template.tested2] name = "GitLab Test-${random_string.random.result}" } +data "env0_template" "template_tg" { + depends_on = [ + env0_template.template_tg] + name = "Template for environment resource - tg" +} + output "tested2_template_id" { value = data.env0_template.tested2.id } @@ -86,6 +101,9 @@ output "tested1_template_repository" { output "tested2_template_path" { value = data.env0_template.tested2.path } +output "tg_tg_version" { + value = data.env0_template.template_tg.terragrunt_version +} data "env0_template" "tested3" { id = env0_template.tested1.id diff --git a/tests/integration/012_environment/main.tf b/tests/integration/012_environment/main.tf index 1149d7a5..3b1c9da8 100644 --- a/tests/integration/012_environment/main.tf +++ b/tests/integration/012_environment/main.tf @@ -31,4 +31,3 @@ output "revision" { value = data.env0_environment.test.revision } -