Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce no-code modules in registry modules #673

Merged
merged 9 commits into from Nov 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
@@ -1,6 +1,7 @@
## Unreleased

FEATURES:
* r/registry_module: Adds `no_code` field. ([#673](https://github.com/hashicorp/terraform-provider-tfe/pull/673))
* r/tfe_organization: Add `allow_force_delete_workspaces` attribute to set whether admins are permitted to delete workspaces with resource under management. ([#661](https://github.com/hashicorp/terraform-provider-tfe/pull/661))

## v0.38.0 (October 24, 2022)
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Expand Up @@ -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.12.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.15.0 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Expand Up @@ -163,8 +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.12.0 h1:2l7emKW8rNTTbnxYHNVj6b46iJzOEp2G/3xIHfGSDnc=
github.com/hashicorp/go-tfe v1.12.0/go.mod h1:thYtIxtgBpDDNdf/2yYPdBJ94Fz5yT5XCNZvGtTGHAU=
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=
Expand Down
42 changes: 42 additions & 0 deletions tfe/resource_tfe_registry_module.go
Expand Up @@ -17,6 +17,7 @@ func resourceTFERegistryModule() *schema.Resource {
return &schema.Resource{
Create: resourceTFERegistryModuleCreate,
Read: resourceTFERegistryModuleRead,
Update: resourceTFERegistryModuleUpdate,
Delete: resourceTFERegistryModuleDelete,
Importer: &schema.ResourceImporter{
StateContext: resourceTFERegistryModuleImporter,
Expand Down Expand Up @@ -76,6 +77,11 @@ func resourceTFERegistryModule() *schema.Resource {
ForceNew: true,
RequiredWith: []string{"registry_name"},
},
"no_code": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
},
"registry_name": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -118,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 {
Expand Down Expand Up @@ -190,6 +197,40 @@ 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 updated: %w", registryModule.Organization.Name, registryModule.Name, err)
}

d.SetId(registryModule.ID)

return resourceTFERegistryModuleRead(d, meta)
}

func resourceTFERegistryModuleRead(d *schema.ResourceData, meta interface{}) error {
tfeClient := meta.(*tfe.Client)

Expand Down Expand Up @@ -221,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{}
Expand Down
71 changes: 71 additions & 0 deletions tfe/resource_tfe_registry_module_test.go
Expand Up @@ -236,6 +236,59 @@ func TestAccTFERegistryModule_publicRegistryModule(t *testing.T) {
})
}

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)),
),
},
},
})
}

func TestAccTFERegistryModuleImport_vcsPrivateRMDeprecatedFormat(t *testing.T) {
rInt := rand.New(rand.NewSource(time.Now().UnixNano())).Int()

Expand Down Expand Up @@ -674,6 +727,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" {
Expand Down
20 changes: 20 additions & 0 deletions website/docs/r/registry_module.html.markdown
Expand Up @@ -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:
Expand All @@ -81,6 +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). Defaults to `false`.

The `vcs_repo` block supports:

Expand All @@ -101,6 +120,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

Expand Down