From a147c3512925b5555fc18f8d72f01a4b18974e43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Hern=C3=A1ndez?= Date: Wed, 26 Oct 2022 13:27:34 +0200 Subject: [PATCH 1/7] create and update no-code module --- tfe/resource_tfe_registry_module.go | 43 ++++++++++++++ tfe/resource_tfe_registry_module_test.go | 73 ++++++++++++++++++++++++ 2 files changed, 116 insertions(+) diff --git a/tfe/resource_tfe_registry_module.go b/tfe/resource_tfe_registry_module.go index d8f0e9605..8dfd47471 100644 --- a/tfe/resource_tfe_registry_module.go +++ b/tfe/resource_tfe_registry_module.go @@ -16,6 +16,7 @@ func resourceTFERegistryModule() *schema.Resource { return &schema.Resource{ Create: resourceTFERegistryModuleCreate, Read: resourceTFERegistryModuleRead, + Update: resourceTFERegistryModuleUpdate, Delete: resourceTFERegistryModuleDelete, Importer: &schema.ResourceImporter{ State: resourceTFERegistryModuleImporter, @@ -75,6 +76,12 @@ func resourceTFERegistryModule() *schema.Resource { ForceNew: true, RequiredWith: []string{"registry_name"}, }, + "no_code": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + ForceNew: false, + }, "registry_name": { Type: schema.TypeString, Optional: true, @@ -117,6 +124,7 @@ func resourceTFERegistryModuleCreateWithoutVCS(meta interface{}, d *schema.Resou options := tfe.RegistryModuleCreateOptions{ Name: tfe.String(d.Get("name").(string)), Provider: tfe.String(d.Get("module_provider").(string)), + NoCode: d.Get("no_code").(bool), } if registryName, ok := d.GetOk("registry_name"); ok { @@ -189,6 +197,41 @@ func resourceTFERegistryModuleCreate(d *schema.ResourceData, meta interface{}) e return resourceTFERegistryModuleRead(d, meta) } +func resourceTFERegistryModuleUpdate(d *schema.ResourceData, meta interface{}) error { + tfeClient := meta.(*tfe.Client) + + options := tfe.RegistryModuleUpdateOptions{ + NoCode: tfe.Bool(d.Get("no_code").(bool)), + } + var registryModule *tfe.RegistryModule + var err error + + rmID := tfe.RegistryModuleID{ + Organization: d.Get("organization").(string), + Name: d.Get("name").(string), + Provider: d.Get("module_provider").(string), + Namespace: d.Get("namespace").(string), + RegistryName: tfe.RegistryName(d.Get("registry_name").(string)), + } + + err = resource.Retry(time.Duration(5)*time.Minute, func() *resource.RetryError { + registryModule, err = tfeClient.RegistryModules.Update(ctx, rmID, options) + if err != nil { + return resource.RetryableError(err) + } + return nil + }) + + if err != nil { + return fmt.Errorf("Error while waiting for module %s/%s to be ingested: %w", registryModule.Organization.Name, registryModule.Name, err) + } + + d.SetId(registryModule.ID) + d.Set("no_code", registryModule.NoCode) + + return nil +} + func resourceTFERegistryModuleRead(d *schema.ResourceData, meta interface{}) error { tfeClient := meta.(*tfe.Client) diff --git a/tfe/resource_tfe_registry_module_test.go b/tfe/resource_tfe_registry_module_test.go index 2453da3b4..7a2f1f44b 100644 --- a/tfe/resource_tfe_registry_module_test.go +++ b/tfe/resource_tfe_registry_module_test.go @@ -230,6 +230,61 @@ func TestAccTFERegistryModule_publicRegistryModule(t *testing.T) { "tfe_registry_module.foobar", "namespace", expectedRegistryModuleAttributes.Namespace), resource.TestCheckResourceAttr( "tfe_registry_module.foobar", "registry_name", string(expectedRegistryModuleAttributes.RegistryName)), + resource.TestCheckResourceAttr( + "tfe_registry_module.foobar", "no_code", "false"), + ), + }, + }, + }) +} + +func TestAccTFERegistryModule_noCodeModule(t *testing.T) { + registryModule := &tfe.RegistryModule{} + rInt := rand.New(rand.NewSource(time.Now().UnixNano())).Int() + orgName := fmt.Sprintf("tst-terraform-%d", rInt) + + expectedRegistryModuleAttributes := &tfe.RegistryModule{ + Name: "vpc", + Provider: "aws", + RegistryName: tfe.PublicRegistry, + Namespace: "terraform-aws-modules", + Organization: &tfe.Organization{Name: orgName}, + NoCode: true, + } + + resource.Test(t, resource.TestCase{ + IsUnitTest: true, + PreCheck: func() { + testAccPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testAccCheckTFERegistryModuleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccTFERegistryModule_NoCode(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckTFERegistryModuleExists( + "tfe_registry_module.foobar", + tfe.RegistryModuleID{ + Organization: orgName, + Name: expectedRegistryModuleAttributes.Name, + Provider: expectedRegistryModuleAttributes.Provider, + RegistryName: expectedRegistryModuleAttributes.RegistryName, + Namespace: expectedRegistryModuleAttributes.Namespace, + }, registryModule), + testAccCheckTFERegistryModuleAttributes(registryModule, expectedRegistryModuleAttributes), + resource.TestCheckResourceAttr( + "tfe_registry_module.foobar", "organization", orgName), + resource.TestCheckResourceAttr( + "tfe_registry_module.foobar", "name", expectedRegistryModuleAttributes.Name), + resource.TestCheckResourceAttr( + "tfe_registry_module.foobar", "module_provider", expectedRegistryModuleAttributes.Provider), + resource.TestCheckResourceAttr( + "tfe_registry_module.foobar", "namespace", expectedRegistryModuleAttributes.Namespace), + resource.TestCheckResourceAttr( + "tfe_registry_module.foobar", "registry_name", string(expectedRegistryModuleAttributes.RegistryName)), + resource.TestCheckResourceAttr( + "tfe_registry_module.foobar", "no_code", fmt.Sprint(expectedRegistryModuleAttributes.NoCode)), ), }, }, @@ -674,6 +729,24 @@ resource "tfe_registry_module" "foobar" { rInt) } +func testAccTFERegistryModule_NoCode(rInt int) string { + return fmt.Sprintf(` +resource "tfe_organization" "foobar" { + name = "tst-terraform-%d" + email = "admin@company.com" +} + +resource "tfe_registry_module" "foobar" { + organization = tfe_organization.foobar.id + namespace = "terraform-aws-modules" + module_provider = "aws" + name = "vpc" + registry_name = "public" + no_code = true + }`, + rInt) +} + func testAccTFERegistryModule_invalidWithBothVCSRepoAndModuleProvider() string { return ` resource "tfe_registry_module" "foobar" { From 4b991bfb59517ebb660ca3cc328601b26ae4bf29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Hern=C3=A1ndez?= Date: Wed, 26 Oct 2022 14:00:11 +0200 Subject: [PATCH 2/7] update documentation with no_code attribute --- website/docs/r/registry_module.html.markdown | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/docs/r/registry_module.html.markdown b/website/docs/r/registry_module.html.markdown index c9dfed58d..28fb981f9 100644 --- a/website/docs/r/registry_module.html.markdown +++ b/website/docs/r/registry_module.html.markdown @@ -81,6 +81,7 @@ The following arguments are supported: * `organization` - (Optional) The name of the organization associated with the registry module. It must be set if `module_provider` is used. * `namespace` - (Optional) The namespace of a public registry module. It can be used if `module_provider` is set and `registry_name` is public. * `registry_name` - (Optional) Whether the registry module is private or public. It can be used if `module_provider` is set. +* `no_code` - (Optional) Whether the registry module is enabled for [no-code provisioning](https://learn.hashicorp.com/tutorials/terraform/no-code-provisioning). The `vcs_repo` block supports: @@ -101,6 +102,7 @@ The `vcs_repo` block supports: * `organization` - The name of the organization associated with the registry module. * `namespace` - The namespace of the module. For private modules this is the name of the organization that owns the module. * `registry_name` - The registry name of the registry module depicting whether the registry module is private or public. +* `no_code` - The property that will enable or disable a module as no-code provisioning ready. ## Import From cc9ee321512987efcec9aeb596f8c7b474777213 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Hern=C3=A1ndez?= Date: Wed, 26 Oct 2022 14:02:46 +0200 Subject: [PATCH 3/7] update CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f03c48596..b7a2d2619 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## Unreleased +FEATURES: +* r/registry_module: Adds `no_code` field. ([#673](https://github.com/hashicorp/terraform-provider-tfe/pull/673)) + ## v0.38.0 (October 24, 2022) FEATURES: From 48e3e62abd7700b8dc80ca70aabd8c31e2da125c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Hern=C3=A1ndez?= Date: Tue, 15 Nov 2022 20:35:48 +0100 Subject: [PATCH 4/7] upgrade go-tfe to v1.13.0 --- go.mod | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 16af40a06..937bd1245 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-retryablehttp v0.7.1 // indirect github.com/hashicorp/go-slug v0.10.0 - github.com/hashicorp/go-tfe v1.11.0 + github.com/hashicorp/go-tfe v1.13.0 github.com/hashicorp/go-version v1.6.0 github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce github.com/hashicorp/hcl/v2 v2.14.0 // indirect @@ -66,3 +66,5 @@ require ( github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect github.com/vmihailenco/tagparser v0.1.1 // indirect ) + +replace github.com/hashicorp/go-tfe => ../go-tfe From e54dd6fa0a4fb8ee0ccb9504e36a2c88fc573f09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Hern=C3=A1ndez?= Date: Tue, 15 Nov 2022 20:40:31 +0100 Subject: [PATCH 5/7] update go.sum --- go.sum | 2 -- 1 file changed, 2 deletions(-) diff --git a/go.sum b/go.sum index f16d31ba1..7d2a38e1c 100644 --- a/go.sum +++ b/go.sum @@ -163,8 +163,6 @@ github.com/hashicorp/go-retryablehttp v0.7.1 h1:sUiuQAnLlbvmExtFQs72iFW/HXeUn8Z1 github.com/hashicorp/go-retryablehttp v0.7.1/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-slug v0.10.0 h1:mh4DDkBJTh9BuEjY/cv8PTo7k9OjT4PcW8PgZnJ4jTY= github.com/hashicorp/go-slug v0.10.0/go.mod h1:Ib+IWBYfEfJGI1ZyXMGNbu2BU+aa3Dzu41RKLH301v4= -github.com/hashicorp/go-tfe v1.12.0 h1:2l7emKW8rNTTbnxYHNVj6b46iJzOEp2G/3xIHfGSDnc= -github.com/hashicorp/go-tfe v1.12.0/go.mod h1:thYtIxtgBpDDNdf/2yYPdBJ94Fz5yT5XCNZvGtTGHAU= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= From 04a2219233f680b25950fcbfd863ebd251e8cfd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Hern=C3=A1ndez?= Date: Tue, 15 Nov 2022 20:41:05 +0100 Subject: [PATCH 6/7] fix go.mod --- go.mod | 2 -- go.sum | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index d0fb28770..686c7e55a 100644 --- a/go.mod +++ b/go.mod @@ -66,5 +66,3 @@ require ( github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect github.com/vmihailenco/tagparser v0.1.1 // indirect ) - -replace github.com/hashicorp/go-tfe => ../go-tfe diff --git a/go.sum b/go.sum index 7d2a38e1c..380b30b4d 100644 --- a/go.sum +++ b/go.sum @@ -163,6 +163,8 @@ github.com/hashicorp/go-retryablehttp v0.7.1 h1:sUiuQAnLlbvmExtFQs72iFW/HXeUn8Z1 github.com/hashicorp/go-retryablehttp v0.7.1/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-slug v0.10.0 h1:mh4DDkBJTh9BuEjY/cv8PTo7k9OjT4PcW8PgZnJ4jTY= github.com/hashicorp/go-slug v0.10.0/go.mod h1:Ib+IWBYfEfJGI1ZyXMGNbu2BU+aa3Dzu41RKLH301v4= +github.com/hashicorp/go-tfe v1.13.0 h1:Z8pJrmN9BV5EncnFRmQmLjhP7pHMNXkC2VkCQXWxKjM= +github.com/hashicorp/go-tfe v1.13.0/go.mod h1:thYtIxtgBpDDNdf/2yYPdBJ94Fz5yT5XCNZvGtTGHAU= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= From 5e8d2939afef68f0f161eb5e02ba81999a280bf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Hern=C3=A1ndez?= Date: Wed, 16 Nov 2022 18:25:22 +0100 Subject: [PATCH 7/7] address feedback from code-review --- tfe/resource_tfe_registry_module.go | 7 +++---- tfe/resource_tfe_registry_module_test.go | 2 -- website/docs/r/registry_module.html.markdown | 20 +++++++++++++++++++- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/tfe/resource_tfe_registry_module.go b/tfe/resource_tfe_registry_module.go index 0f97bd5c9..5e663ad52 100644 --- a/tfe/resource_tfe_registry_module.go +++ b/tfe/resource_tfe_registry_module.go @@ -81,7 +81,6 @@ func resourceTFERegistryModule() *schema.Resource { Type: schema.TypeBool, Optional: true, Computed: true, - ForceNew: false, }, "registry_name": { Type: schema.TypeString, @@ -224,13 +223,12 @@ func resourceTFERegistryModuleUpdate(d *schema.ResourceData, meta interface{}) e }) if err != nil { - return fmt.Errorf("Error while waiting for module %s/%s to be ingested: %w", registryModule.Organization.Name, registryModule.Name, err) + return fmt.Errorf("Error while waiting for module %s/%s to be updated: %w", registryModule.Organization.Name, registryModule.Name, err) } d.SetId(registryModule.ID) - d.Set("no_code", registryModule.NoCode) - return nil + return resourceTFERegistryModuleRead(d, meta) } func resourceTFERegistryModuleRead(d *schema.ResourceData, meta interface{}) error { @@ -264,6 +262,7 @@ func resourceTFERegistryModuleRead(d *schema.ResourceData, meta interface{}) err d.Set("organization", registryModule.Organization.Name) d.Set("namespace", registryModule.Namespace) d.Set("registry_name", registryModule.RegistryName) + d.Set("no_code", registryModule.NoCode) // Set VCS repo options. var vcsRepo []interface{} diff --git a/tfe/resource_tfe_registry_module_test.go b/tfe/resource_tfe_registry_module_test.go index 7a2f1f44b..2eb042209 100644 --- a/tfe/resource_tfe_registry_module_test.go +++ b/tfe/resource_tfe_registry_module_test.go @@ -230,8 +230,6 @@ func TestAccTFERegistryModule_publicRegistryModule(t *testing.T) { "tfe_registry_module.foobar", "namespace", expectedRegistryModuleAttributes.Namespace), resource.TestCheckResourceAttr( "tfe_registry_module.foobar", "registry_name", string(expectedRegistryModuleAttributes.RegistryName)), - resource.TestCheckResourceAttr( - "tfe_registry_module.foobar", "no_code", "false"), ), }, }, diff --git a/website/docs/r/registry_module.html.markdown b/website/docs/r/registry_module.html.markdown index 28fb981f9..58e65b92a 100644 --- a/website/docs/r/registry_module.html.markdown +++ b/website/docs/r/registry_module.html.markdown @@ -70,6 +70,24 @@ resource "tfe_registry_module" "test-public-registry-module" { } ``` +Create no-code provisioning registry module: + +```hcl +resource "tfe_organization" "test-organization" { + name = "my-org-name" + email = "admin@company.com" +} + +resource "tfe_registry_module" "test-no-code-provisioning-registry-module" { + organization = tfe_organization.test-organization.name + namespace = "terraform-aws-modules" + module_provider = "aws" + name = "vpc" + registry_name = "public" + no_code = true +} +``` + ## Argument Reference The following arguments are supported: @@ -81,7 +99,7 @@ The following arguments are supported: * `organization` - (Optional) The name of the organization associated with the registry module. It must be set if `module_provider` is used. * `namespace` - (Optional) The namespace of a public registry module. It can be used if `module_provider` is set and `registry_name` is public. * `registry_name` - (Optional) Whether the registry module is private or public. It can be used if `module_provider` is set. -* `no_code` - (Optional) Whether the registry module is enabled for [no-code provisioning](https://learn.hashicorp.com/tutorials/terraform/no-code-provisioning). +* `no_code` - (Optional) Whether the registry module is enabled for [no-code provisioning](https://learn.hashicorp.com/tutorials/terraform/no-code-provisioning). Defaults to `false`. The `vcs_repo` block supports: