diff --git a/.changelog/22915.txt b/.changelog/22915.txt new file mode 100644 index 000000000000..7bbde63e56d3 --- /dev/null +++ b/.changelog/22915.txt @@ -0,0 +1,3 @@ +```release-note:breaking-change +resource/aws_fsx_ontap_storage_virtual_machine: Remove deprecated `active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguidshed_name`, migrating value to `active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguished_name` +``` \ No newline at end of file diff --git a/.github/workflows/terraform_provider.yml b/.github/workflows/terraform_provider.yml index f8daa0ee2a0d..42ab2400ca27 100644 --- a/.github/workflows/terraform_provider.yml +++ b/.github/workflows/terraform_provider.yml @@ -237,6 +237,9 @@ jobs: if [[ "${pkg}" == */test-fixtures ]]; then continue fi + if [[ "${pkg}" == internal/generate/* ]]; then + continue + fi while read file; do if [ "${file}" = "" ]; then continue diff --git a/docs/contributing/contribution-checklists.md b/docs/contributing/contribution-checklists.md index e2f3a17fb043..d2cb6524746e 100644 --- a/docs/contributing/contribution-checklists.md +++ b/docs/contributing/contribution-checklists.md @@ -583,7 +583,7 @@ More details about this code generation can be found in the [namevaluesfilters d ### Resource Filter Code Implementation -- In the resource's equivalent data source Go file (e.g., `internal/service/ec2/internet_gateway_data_source.go`), add the following Go import: `"github.com/hashicorp/terraform-provider-aws/internal/namevaluesfilters"` +- In the resource's equivalent data source Go file (e.g., `internal/service/ec2/internet_gateway_data_source.go`), add the following Go import: `"github.com/hashicorp/terraform-provider-aws/internal/generate/namevaluesfilters"` - In the resource schema, add `"filter": namevaluesfilters.Schema(),` - Implement the logic to build the list of filters: diff --git a/internal/service/fsx/ontap_storage_virtual_machine.go b/internal/service/fsx/ontap_storage_virtual_machine.go index f603b2f80851..04e915fbadba 100644 --- a/internal/service/fsx/ontap_storage_virtual_machine.go +++ b/internal/service/fsx/ontap_storage_virtual_machine.go @@ -35,6 +35,15 @@ func ResourceOntapStorageVirtualMachine() *schema.Resource { Delete: schema.DefaultTimeout(30 * time.Minute), }, + SchemaVersion: 1, + StateUpgraders: []schema.StateUpgrader{ + { + Type: ResourceOntapStorageVirtualMachineV0().CoreConfigSchema().ImpliedType(), + Upgrade: ResourceOntapStorageVirtualMachineStateUpgradeV0, + Version: 0, + }, + }, + Schema: map[string]*schema.Schema{ "arn": { Type: schema.TypeString, @@ -82,20 +91,11 @@ func ResourceOntapStorageVirtualMachine() *schema.Resource { ForceNew: true, ValidateFunc: validation.StringLenBetween(1, 256), }, - "organizational_unit_distinguidshed_name": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - ValidateFunc: validation.StringLenBetween(1, 2000), - Deprecated: "use 'organizational_unit_distinguished_name' instead", - ConflictsWith: []string{"active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguished_name"}, - }, "organizational_unit_distinguished_name": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - ValidateFunc: validation.StringLenBetween(1, 2000), - ConflictsWith: []string{"active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguidshed_name"}, + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(1, 2000), }, "password": { Type: schema.TypeString, @@ -430,9 +430,7 @@ func expandFsxOntapSvmSelfManagedActiveDirectoryConfiguration(cfg []interface{}) out.FileSystemAdministratorsGroup = aws.String(v) } - if v, ok := conf["organizational_unit_distinguidshed_name"].(string); ok && len(v) > 0 { - out.OrganizationalUnitDistinguishedName = aws.String(v) - } else if v, ok := conf["organizational_unit_distinguished_name"].(string); ok && len(v) > 0 { + if v, ok := conf["organizational_unit_distinguished_name"].(string); ok && len(v) > 0 { out.OrganizationalUnitDistinguishedName = aws.String(v) } @@ -523,9 +521,7 @@ func flattenFsxOntapSelfManagedActiveDirectoryConfiguration(d *schema.ResourceDa } if rs.OrganizationalUnitDistinguishedName != nil { - if _, ok := d.GetOk("active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguidshed_name"); ok { - m["organizational_unit_distinguidshed_name"] = aws.StringValue(rs.OrganizationalUnitDistinguishedName) - } else { + if _, ok := d.GetOk("active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguished_name"); ok { m["organizational_unit_distinguished_name"] = aws.StringValue(rs.OrganizationalUnitDistinguishedName) } } diff --git a/internal/service/fsx/ontap_storage_virtual_machine_migrate.go b/internal/service/fsx/ontap_storage_virtual_machine_migrate.go new file mode 100644 index 000000000000..6a1131ffc878 --- /dev/null +++ b/internal/service/fsx/ontap_storage_virtual_machine_migrate.go @@ -0,0 +1,217 @@ +package fsx + +import ( + "context" + "log" + "strings" + + "github.com/aws/aws-sdk-go/service/fsx" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" +) + +func ResourceOntapStorageVirtualMachineV0() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 0, + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "active_directory_configuration": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "netbios_name": { + Type: schema.TypeString, + Optional: true, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + return strings.EqualFold(old, new) + }, + ValidateFunc: validation.StringLenBetween(1, 15), + }, + "self_managed_active_directory_configuration": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dns_ips": { + Type: schema.TypeSet, + Required: true, + MinItems: 1, + MaxItems: 3, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.IsIPAddress, + }, + }, + "domain_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(1, 255), + }, + "file_system_administrators_group": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(1, 256), + }, + "organizational_unit_distinguidshed_name": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(1, 2000), + Deprecated: "use 'organizational_unit_distinguished_name' instead", + ConflictsWith: []string{"active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguished_name"}, + }, + "organizational_unit_distinguished_name": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(1, 2000), + ConflictsWith: []string{"active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguidshed_name"}, + }, + "password": { + Type: schema.TypeString, + Sensitive: true, + Required: true, + ValidateFunc: validation.StringLenBetween(1, 256), + }, + "username": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(1, 256), + }, + }, + }, + }, + }, + }, + }, + "endpoints": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "iscsi": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dns_name": { + Type: schema.TypeString, + Computed: true, + }, + "ip_addresses": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + }, + "management": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dns_name": { + Type: schema.TypeString, + Computed: true, + }, + "ip_addresses": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + }, + "nfs": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dns_name": { + Type: schema.TypeString, + Computed: true, + }, + "ip_addresses": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + }, + "smb": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dns_name": { + Type: schema.TypeString, + Computed: true, + }, + "ip_addresses": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + }, + }, + }, + }, + "file_system_id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(11, 21), + }, + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(1, 47), + }, + "root_volume_security_style": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice(fsx.StorageVirtualMachineRootVolumeSecurityStyle_Values(), false), + }, + "subtype": { + Type: schema.TypeString, + Computed: true, + }, + "svm_admin_password": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + ValidateFunc: validation.StringLenBetween(8, 50), + }, + "tags": tftags.TagsSchema(), + "tags_all": tftags.TagsSchemaComputed(), + "uuid": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func ResourceOntapStorageVirtualMachineStateUpgradeV0(_ context.Context, rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) { + log.Printf("[DEBUG] Attributes before migration: %#v", rawState) + + rawState["active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguished_name"] = rawState["active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguidshed_name"] + delete(rawState, "active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguidshed_name") + + log.Printf("[DEBUG] Attributes after migration: %#v", rawState) + return rawState, nil +} diff --git a/internal/service/fsx/ontap_storage_virtual_machine_migrate_test.go b/internal/service/fsx/ontap_storage_virtual_machine_migrate_test.go new file mode 100644 index 000000000000..5b67690165b5 --- /dev/null +++ b/internal/service/fsx/ontap_storage_virtual_machine_migrate_test.go @@ -0,0 +1,35 @@ +package fsx_test + +import ( + "context" + "reflect" + "testing" + + tffsx "github.com/hashicorp/terraform-provider-aws/internal/service/fsx" +) + +func testOntapStorageVirtualMachineStateDataV0() map[string]interface{} { + return map[string]interface{}{ + "active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguidshed_name": "MeArrugoDerrito", + } +} + +func testOntapStorageVirtualMachineStateDataV1() map[string]interface{} { + v0 := testOntapStorageVirtualMachineStateDataV0() + return map[string]interface{}{ + "active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguished_name": v0["active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguidshed_name"], + } +} + +func TestOntapStorageVirtualMachineStateUpgradeV0(t *testing.T) { + expected := testOntapStorageVirtualMachineStateDataV1() + actual, err := tffsx.ResourceOntapStorageVirtualMachineStateUpgradeV0(context.Background(), testOntapStorageVirtualMachineStateDataV0(), nil) + + if err != nil { + t.Fatalf("error migrating state: %s", err) + } + + if !reflect.DeepEqual(expected, actual) { + t.Fatalf("\n\nexpected:\n\n%#v\n\ngot:\n\n%#v\n\n", expected, actual) + } +} diff --git a/internal/service/fsx/ontap_storage_virtual_machine_test.go b/internal/service/fsx/ontap_storage_virtual_machine_test.go index 29098fb83d91..5d4d6c531556 100644 --- a/internal/service/fsx/ontap_storage_virtual_machine_test.go +++ b/internal/service/fsx/ontap_storage_virtual_machine_test.go @@ -277,46 +277,6 @@ func TestAccFSxOntapStorageVirtualMachine_activeDirectory(t *testing.T) { }) } -func TestAccFSxOntapStorageVirtualMachine_activeDirectoryDeprecatedOrganizationalUnitDistinguishedName(t *testing.T) { - var storageVirtualMachine1 fsx.StorageVirtualMachine - resourceName := "aws_fsx_ontap_storage_virtual_machine.test" - rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - netBiosName := "tftest-" + sdkacctest.RandString(7) - domainNetbiosName := "tftestcorp" - domainName := "tftestcorp.local" - domainPassword1 := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); acctest.PreCheckPartitionHasService(fsx.EndpointsID, t) }, - ErrorCheck: acctest.ErrorCheck(t, fsx.EndpointsID), - Providers: acctest.Providers, - CheckDestroy: testAccCheckFsxOntapStorageVirtualMachineDestroy, - Steps: []resource.TestStep{ - { - Config: testAccFsxOntapStorageVirutalMachineSelfManagedActiveDirectoryConfigDeprecatedOrganizationalUnitDistinguishedName(rName, netBiosName, domainNetbiosName, domainName, domainPassword1), - Check: resource.ComposeTestCheckFunc( - testAccCheckFsxOntapStorageVirtualMachineExists(resourceName, &storageVirtualMachine1), - resource.TestCheckResourceAttr(resourceName, "active_directory_configuration.#", "1"), - resource.TestCheckResourceAttr(resourceName, "active_directory_configuration.0.netbios_name", strings.ToUpper(netBiosName)), - resource.TestCheckResourceAttr(resourceName, "active_directory_configuration.0.self_managed_active_directory_configuration.0.domain_name", domainName), - resource.TestCheckResourceAttr(resourceName, "endpoints.0.smb.#", "1"), - resource.TestCheckResourceAttrSet(resourceName, "endpoints.0.smb.0.dns_name"), - resource.TestCheckResourceAttr(resourceName, "active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguidshed_name", fmt.Sprintf("OU=computers,OU=%s", domainNetbiosName)), - resource.TestCheckResourceAttr(resourceName, "active_directory_configuration.0.self_managed_active_directory_configuration.0.password", domainPassword1), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{ - "active_directory_configuration", - }, - }, - }, - }) -} - func testAccCheckFsxOntapStorageVirtualMachineExists(resourceName string, svm *fsx.StorageVirtualMachine) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[resourceName] @@ -520,24 +480,3 @@ resource "aws_fsx_ontap_storage_virtual_machine" "test" { } `, rName, netBiosName, domainName, domainPassword, domainNetbiosName)) } - -func testAccFsxOntapStorageVirutalMachineSelfManagedActiveDirectoryConfigDeprecatedOrganizationalUnitDistinguishedName(rName string, netBiosName string, domainNetbiosName string, domainName string, domainPassword string) string { - return acctest.ConfigCompose(testAccOntapStorageVirtualMachineADConfig(rName, domainName, domainPassword), fmt.Sprintf(` -resource "aws_fsx_ontap_storage_virtual_machine" "test" { - file_system_id = aws_fsx_ontap_file_system.test.id - name = %[1]q - depends_on = [aws_directory_service_directory.test] - - active_directory_configuration { - netbios_name = %[2]q - self_managed_active_directory_configuration { - dns_ips = aws_directory_service_directory.test.dns_ip_addresses - domain_name = %[3]q - password = %[4]q - username = "Admin" - organizational_unit_distinguidshed_name = "OU=computers,OU=%[5]s" - } - } -} -`, rName, netBiosName, domainName, domainPassword, domainNetbiosName)) -} diff --git a/website/docs/guides/version-4-upgrade.html.md b/website/docs/guides/version-4-upgrade.html.md index c887afe0ae0a..12af470b461b 100644 --- a/website/docs/guides/version-4-upgrade.html.md +++ b/website/docs/guides/version-4-upgrade.html.md @@ -34,6 +34,7 @@ Upgrade topics: - [Resource: aws_elasticache_cluster](#resource-aws_elasticache_cluster) - [Resource: aws_elasticache_global_replication_group](#resource-aws_elasticache_global_replication_group) - [Resource: aws_elasticache_replication_group](#resource-aws_elasticache_replication_group) +- [Resource: aws_fsx_ontap_storage_virtual_machine](#resource-aws_fsx_ontap_storage_virtual_machine) - [Resource: aws_network_interface](#resource-aws_network_interface) - [Resource: aws_s3_bucket](#resource-aws_s3_bucket) - [Resource: aws_s3_bucket_object](#resource-aws_s3_bucket_object) @@ -433,6 +434,10 @@ output "elasticache_global_replication_group_version_result" { !> **WARNING:** This topic is placeholder documentation. +## Resource: aws_fsx_ontap_storage_virtual_machine + +We removed the misspelled argument `active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguidshed_name` that was previously deprecated. Use `active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguished_name` now instead. Terraform will automatically migrate the state to `active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguished_name` during planning. + ## Resource: aws_network_interface !> **WARNING:** This topic is placeholder documentation.