From 70ef786356cdd15592d02120a4398517b514aebb Mon Sep 17 00:00:00 2001 From: nikhil Date: Sun, 14 Apr 2024 14:19:25 +0100 Subject: [PATCH 01/13] f-aws_db_instance: support upgrade storage config --- internal/service/rds/instance.go | 8 +++ internal/service/rds/instance_test.go | 94 +++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) diff --git a/internal/service/rds/instance.go b/internal/service/rds/instance.go index 1036c0452553..6d400e003a6e 100644 --- a/internal/service/rds/instance.go +++ b/internal/service/rds/instance.go @@ -652,6 +652,10 @@ func ResourceInstance() *schema.Resource { "s3_import", }, }, + "upgrade_storage_config": { + Type: schema.TypeBool, + Optional: true, + }, "username": { Type: schema.TypeString, Optional: true, @@ -851,6 +855,10 @@ func resourceInstanceCreate(ctx context.Context, d *schema.ResourceData, meta in input.StorageType = aws.String(v.(string)) } + if v, ok := d.GetOk("upgrade_storage_config"); ok { + input.UpgradeStorageConfig = aws.Bool(v.(bool)) + } + if v, ok := d.GetOk("vpc_security_group_ids"); ok && v.(*schema.Set).Len() > 0 { input.VpcSecurityGroupIds = flex.ExpandStringSet(v.(*schema.Set)) } diff --git a/internal/service/rds/instance_test.go b/internal/service/rds/instance_test.go index 7945647db6d9..b94c4e3f6346 100644 --- a/internal/service/rds/instance_test.go +++ b/internal/service/rds/instance_test.go @@ -1088,6 +1088,53 @@ func TestAccRDSInstance_ReplicateSourceDB_basic(t *testing.T) { }) } +func TestAccRDSInstance_ReplicateSourceDB_upgrade(t *testing.T) { + ctx := acctest.Context(t) + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + + var dbInstance, sourceDbInstance rds.DBInstance + + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + sourceResourceName := "aws_db_instance.source" + resourceName := "aws_db_instance.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.RDSServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckInstanceDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccInstanceConfig_ReplicateSourceDB_upgrade(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckInstanceExists(ctx, sourceResourceName, &sourceDbInstance), + testAccCheckInstanceExists(ctx, resourceName, &dbInstance), + resource.TestCheckResourceAttr(resourceName, "identifier", rName), + resource.TestCheckResourceAttr(resourceName, "identifier_prefix", ""), + resource.TestCheckResourceAttrPair(resourceName, "replicate_source_db", sourceResourceName, "identifier"), + resource.TestCheckResourceAttrPair(resourceName, "db_name", sourceResourceName, "db_name"), + resource.TestCheckResourceAttrPair(sourceResourceName, "instance_class", "data.aws_rds_orderable_db_instance.test", "instance_class"), + resource.TestCheckResourceAttrPair(resourceName, "instance_class", "data.aws_rds_orderable_db_instance.test_upgrade", "instance_class"), + + resource.TestCheckResourceAttr(sourceResourceName, "replicas.#", "0"), // Before refreshing source, it will not be aware of replicas + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "apply_immediately", + "password", + "upgrade_storage_config", + }, + }, + }, + }) +} + func TestAccRDSInstance_ReplicateSourceDB_namePrefix(t *testing.T) { ctx := acctest.Context(t) if testing.Short() { @@ -6482,6 +6529,23 @@ data "aws_rds_orderable_db_instance" "test" { `, engine, license, storage, mainInstanceClasses) } +func testAccInstanceConfig_orderableClass_upgrade(engine, license, storage string) string { + return fmt.Sprintf(` +data "aws_rds_engine_version" "default_upgrade" { + engine = %[1]q +} + +data "aws_rds_orderable_db_instance" "test_upgrade" { + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + license_model = %[2]q + storage_type = %[3]q + + preferred_instance_classes = ["db.t4g.small"] +} +`, engine, license, storage) +} + func testAccInstanceConfig_orderableClassDB2() string { return testAccInstanceConfig_orderableClass(tfrds.InstanceEngineDB2Standard, "bring-your-own-license", "gp3") } @@ -6490,6 +6554,10 @@ func testAccInstanceConfig_orderableClassMySQL() string { return testAccInstanceConfig_orderableClass(tfrds.InstanceEngineMySQL, "general-public-license", "standard") } +func testAccInstanceConfig_orderableClassMySQL_upgrade() string { + return testAccInstanceConfig_orderableClass_upgrade(tfrds.InstanceEngineMySQL, "general-public-license", "standard") +} + func testAccInstanceConfig_orderableClassMySQLGP3() string { return testAccInstanceConfig_orderableClass(tfrds.InstanceEngineMySQL, "general-public-license", "gp3") } @@ -8593,6 +8661,32 @@ resource "aws_db_instance" "test" { `, rName)) } +func testAccInstanceConfig_ReplicateSourceDB_upgrade(rName string) string { + return acctest.ConfigCompose( + testAccInstanceConfig_orderableClassMySQL(), + testAccInstanceConfig_orderableClassMySQL_upgrade(), + fmt.Sprintf(` +resource "aws_db_instance" "source" { + allocated_storage = 5 + backup_retention_period = 1 + engine = data.aws_rds_orderable_db_instance.test.engine + identifier = "%[1]s-source" + instance_class = data.aws_rds_orderable_db_instance.test.instance_class + password = "avoid-plaintext-passwords" + username = "tfacctest" + skip_final_snapshot = true +} + +resource "aws_db_instance" "test" { + identifier = %[1]q + instance_class = data.aws_rds_orderable_db_instance.test_upgrade.instance_class + replicate_source_db = aws_db_instance.source.identifier + skip_final_snapshot = true + upgrade_storage_config = true +} +`, rName)) +} + func testAccInstanceConfig_ReplicateSourceDB_namePrefix(identifierPrefix, sourceName string) string { return acctest.ConfigCompose( testAccInstanceConfig_orderableClassMySQL(), From 408fa696199acfbde4d9bcd42528dd9bba9f92a2 Mon Sep 17 00:00:00 2001 From: nikhil Date: Sun, 14 Apr 2024 14:27:33 +0100 Subject: [PATCH 02/13] f-support for network_card_index --- internal/service/rds/instance_test.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/internal/service/rds/instance_test.go b/internal/service/rds/instance_test.go index b94c4e3f6346..fac231810517 100644 --- a/internal/service/rds/instance_test.go +++ b/internal/service/rds/instance_test.go @@ -1113,10 +1113,10 @@ func TestAccRDSInstance_ReplicateSourceDB_upgrade(t *testing.T) { testAccCheckInstanceExists(ctx, resourceName, &dbInstance), resource.TestCheckResourceAttr(resourceName, "identifier", rName), resource.TestCheckResourceAttr(resourceName, "identifier_prefix", ""), + resource.TestCheckResourceAttr(resourceName, "upgrade_storage_config", "true"), + testAccCheckInstanceReplicaAttributes(&sourceDbInstance, &dbInstance), resource.TestCheckResourceAttrPair(resourceName, "replicate_source_db", sourceResourceName, "identifier"), resource.TestCheckResourceAttrPair(resourceName, "db_name", sourceResourceName, "db_name"), - resource.TestCheckResourceAttrPair(sourceResourceName, "instance_class", "data.aws_rds_orderable_db_instance.test", "instance_class"), - resource.TestCheckResourceAttrPair(resourceName, "instance_class", "data.aws_rds_orderable_db_instance.test_upgrade", "instance_class"), resource.TestCheckResourceAttr(sourceResourceName, "replicas.#", "0"), // Before refreshing source, it will not be aware of replicas ), @@ -6541,7 +6541,7 @@ data "aws_rds_orderable_db_instance" "test_upgrade" { license_model = %[2]q storage_type = %[3]q - preferred_instance_classes = ["db.t4g.small"] + preferred_instance_classes = ["db.t3.micro"] } `, engine, license, storage) } @@ -8663,15 +8663,14 @@ resource "aws_db_instance" "test" { func testAccInstanceConfig_ReplicateSourceDB_upgrade(rName string) string { return acctest.ConfigCompose( - testAccInstanceConfig_orderableClassMySQL(), testAccInstanceConfig_orderableClassMySQL_upgrade(), fmt.Sprintf(` resource "aws_db_instance" "source" { allocated_storage = 5 backup_retention_period = 1 - engine = data.aws_rds_orderable_db_instance.test.engine + engine = data.aws_rds_orderable_db_instance.test_upgrade.engine identifier = "%[1]s-source" - instance_class = data.aws_rds_orderable_db_instance.test.instance_class + instance_class = data.aws_rds_orderable_db_instance.test_upgrade.instance_class password = "avoid-plaintext-passwords" username = "tfacctest" skip_final_snapshot = true @@ -8683,6 +8682,9 @@ resource "aws_db_instance" "test" { replicate_source_db = aws_db_instance.source.identifier skip_final_snapshot = true upgrade_storage_config = true + timeouts { + update = "120m" + } } `, rName)) } From 98709ab18a62e5b7d42e9c60645727d84179d921 Mon Sep 17 00:00:00 2001 From: nikhil Date: Sun, 14 Apr 2024 14:29:07 +0100 Subject: [PATCH 03/13] f-support for network_card_index --- .changelog/36904.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/36904.txt diff --git a/.changelog/36904.txt b/.changelog/36904.txt new file mode 100644 index 000000000000..44d9bebeb654 --- /dev/null +++ b/.changelog/36904.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_sagemaker_prebuilt_ecr_image: Add `aws_db_instance` argument +``` \ No newline at end of file From f57a7fb33bee581bec1a4bcb965a82d0dbb248b1 Mon Sep 17 00:00:00 2001 From: nikhil Date: Sun, 14 Apr 2024 14:29:49 +0100 Subject: [PATCH 04/13] f-support for network_card_index --- .changelog/36904.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changelog/36904.txt b/.changelog/36904.txt index 44d9bebeb654..ea2bd79505e1 100644 --- a/.changelog/36904.txt +++ b/.changelog/36904.txt @@ -1,3 +1,3 @@ ```release-note:enhancement -resource/aws_sagemaker_prebuilt_ecr_image: Add `aws_db_instance` argument +resource/aws_db_instance: Add `aws_db_instance` argument ``` \ No newline at end of file From 5e396ff9e478761ea96f85a05812172f10e895a8 Mon Sep 17 00:00:00 2001 From: nikhil Date: Sun, 14 Apr 2024 14:30:25 +0100 Subject: [PATCH 05/13] f-support for network_card_index --- .changelog/36904.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changelog/36904.txt b/.changelog/36904.txt index ea2bd79505e1..f0dd62425abe 100644 --- a/.changelog/36904.txt +++ b/.changelog/36904.txt @@ -1,3 +1,3 @@ ```release-note:enhancement -resource/aws_db_instance: Add `aws_db_instance` argument +resource/aws_db_instance: Add `upgrade_storage_config` argument ``` \ No newline at end of file From a0ccb00a40c0527b856946b3b67adf05fb8b6ea2 Mon Sep 17 00:00:00 2001 From: nikhil Date: Sun, 14 Apr 2024 15:30:11 +0100 Subject: [PATCH 06/13] f-support for network_card_index --- internal/service/rds/instance_test.go | 29 ++++----------------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/internal/service/rds/instance_test.go b/internal/service/rds/instance_test.go index fac231810517..9404d029ebb5 100644 --- a/internal/service/rds/instance_test.go +++ b/internal/service/rds/instance_test.go @@ -6529,23 +6529,6 @@ data "aws_rds_orderable_db_instance" "test" { `, engine, license, storage, mainInstanceClasses) } -func testAccInstanceConfig_orderableClass_upgrade(engine, license, storage string) string { - return fmt.Sprintf(` -data "aws_rds_engine_version" "default_upgrade" { - engine = %[1]q -} - -data "aws_rds_orderable_db_instance" "test_upgrade" { - engine = data.aws_rds_engine_version.default.engine - engine_version = data.aws_rds_engine_version.default.version - license_model = %[2]q - storage_type = %[3]q - - preferred_instance_classes = ["db.t3.micro"] -} -`, engine, license, storage) -} - func testAccInstanceConfig_orderableClassDB2() string { return testAccInstanceConfig_orderableClass(tfrds.InstanceEngineDB2Standard, "bring-your-own-license", "gp3") } @@ -6554,10 +6537,6 @@ func testAccInstanceConfig_orderableClassMySQL() string { return testAccInstanceConfig_orderableClass(tfrds.InstanceEngineMySQL, "general-public-license", "standard") } -func testAccInstanceConfig_orderableClassMySQL_upgrade() string { - return testAccInstanceConfig_orderableClass_upgrade(tfrds.InstanceEngineMySQL, "general-public-license", "standard") -} - func testAccInstanceConfig_orderableClassMySQLGP3() string { return testAccInstanceConfig_orderableClass(tfrds.InstanceEngineMySQL, "general-public-license", "gp3") } @@ -8663,14 +8642,14 @@ resource "aws_db_instance" "test" { func testAccInstanceConfig_ReplicateSourceDB_upgrade(rName string) string { return acctest.ConfigCompose( - testAccInstanceConfig_orderableClassMySQL_upgrade(), + testAccInstanceConfig_orderableClassMySQL(), fmt.Sprintf(` resource "aws_db_instance" "source" { allocated_storage = 5 backup_retention_period = 1 - engine = data.aws_rds_orderable_db_instance.test_upgrade.engine + engine = data.aws_rds_orderable_db_instance.test.engine identifier = "%[1]s-source" - instance_class = data.aws_rds_orderable_db_instance.test_upgrade.instance_class + instance_class = data.aws_rds_orderable_db_instance.test.instance_class password = "avoid-plaintext-passwords" username = "tfacctest" skip_final_snapshot = true @@ -8678,7 +8657,7 @@ resource "aws_db_instance" "source" { resource "aws_db_instance" "test" { identifier = %[1]q - instance_class = data.aws_rds_orderable_db_instance.test_upgrade.instance_class + instance_class = aws_db_instance.source.instance_class replicate_source_db = aws_db_instance.source.identifier skip_final_snapshot = true upgrade_storage_config = true From 818639d17183668de1794f42daae7fcf58425d1d Mon Sep 17 00:00:00 2001 From: nikhil Date: Sun, 14 Apr 2024 15:36:51 +0100 Subject: [PATCH 07/13] f-support for network_card_index --- website/docs/r/db_instance.html.markdown | 1 + 1 file changed, 1 insertion(+) diff --git a/website/docs/r/db_instance.html.markdown b/website/docs/r/db_instance.html.markdown index 2530f640c4a6..fb8f7f1aba2d 100644 --- a/website/docs/r/db_instance.html.markdown +++ b/website/docs/r/db_instance.html.markdown @@ -392,6 +392,7 @@ creating a cross-region replica of an encrypted database you will also need to specify a `kms_key_id`. See [DB Instance Replication][instance-replication] and [Working with PostgreSQL and MySQL Read Replicas](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_ReadRepl.html) for more information on using Replication. +* `upgrade_storage_config` - (Optional) Whether to upgrade the storage file system configuration on the read replica. Can only be set with `replicate_source_db`. * `restore_to_point_in_time` - (Optional, Forces new resource) A configuration block for restoring a DB instance to an arbitrary point in time. Requires the `identifier` argument to be set with the name of the new DB instance to be created. See [Restore To Point In Time](#restore-to-point-in-time) below for details. * `s3_import` - (Optional) Restore from a Percona Xtrabackup in S3. See [Importing Data into an Amazon RDS MySQL DB Instance](http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/MySQL.Procedural.Importing.html) * `skip_final_snapshot` - (Optional) Determines whether a final DB snapshot is From d3c70813db3f61ac1d5355b0582bad0ecc2c2d70 Mon Sep 17 00:00:00 2001 From: nikhil Date: Sun, 14 Apr 2024 15:47:37 +0100 Subject: [PATCH 08/13] f-support for network_card_index --- internal/service/rds/instance_test.go | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/internal/service/rds/instance_test.go b/internal/service/rds/instance_test.go index 9404d029ebb5..8f2349c90d38 100644 --- a/internal/service/rds/instance_test.go +++ b/internal/service/rds/instance_test.go @@ -1111,26 +1111,10 @@ func TestAccRDSInstance_ReplicateSourceDB_upgrade(t *testing.T) { Check: resource.ComposeAggregateTestCheckFunc( testAccCheckInstanceExists(ctx, sourceResourceName, &sourceDbInstance), testAccCheckInstanceExists(ctx, resourceName, &dbInstance), - resource.TestCheckResourceAttr(resourceName, "identifier", rName), - resource.TestCheckResourceAttr(resourceName, "identifier_prefix", ""), - resource.TestCheckResourceAttr(resourceName, "upgrade_storage_config", "true"), testAccCheckInstanceReplicaAttributes(&sourceDbInstance, &dbInstance), - resource.TestCheckResourceAttrPair(resourceName, "replicate_source_db", sourceResourceName, "identifier"), - resource.TestCheckResourceAttrPair(resourceName, "db_name", sourceResourceName, "db_name"), - - resource.TestCheckResourceAttr(sourceResourceName, "replicas.#", "0"), // Before refreshing source, it will not be aware of replicas + resource.TestCheckResourceAttr(resourceName, "upgrade_storage_config", "true"), ), }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{ - "apply_immediately", - "password", - "upgrade_storage_config", - }, - }, }, }) } From 055912632be4713ad69846445eb9a466451d6fa7 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 1 Aug 2024 09:30:22 -0400 Subject: [PATCH 09/13] Tweak acceptance test name. --- internal/service/rds/instance_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/service/rds/instance_test.go b/internal/service/rds/instance_test.go index b2a3e4e7f4f6..d958319798eb 100644 --- a/internal/service/rds/instance_test.go +++ b/internal/service/rds/instance_test.go @@ -1077,7 +1077,7 @@ func TestAccRDSInstance_ReplicateSourceDB_basic(t *testing.T) { }) } -func TestAccRDSInstance_ReplicateSourceDB_upgrade(t *testing.T) { +func TestAccRDSInstance_ReplicateSourceDB_upgradeStorageConfig(t *testing.T) { ctx := acctest.Context(t) if testing.Short() { t.Skip("skipping long-running test in short mode") @@ -1096,7 +1096,7 @@ func TestAccRDSInstance_ReplicateSourceDB_upgrade(t *testing.T) { CheckDestroy: testAccCheckDBInstanceDestroy(ctx), Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_ReplicateSourceDB_upgrade(rName), + Config: testAccInstanceConfig_ReplicateSourceDB_upgradeStorageConfig(rName), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckDBInstanceExists(ctx, sourceResourceName, &sourceDbInstance), testAccCheckDBInstanceExists(ctx, resourceName, &dbInstance), @@ -8779,7 +8779,7 @@ resource "aws_db_instance" "test" { `, rName)) } -func testAccInstanceConfig_ReplicateSourceDB_upgrade(rName string) string { +func testAccInstanceConfig_ReplicateSourceDB_upgradeStorageConfig(rName string) string { return acctest.ConfigCompose( testAccInstanceConfig_orderableClassMySQL(), fmt.Sprintf(` From 9ef41d9a773bff2dfe639f99b498b7a715b39bd0 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 1 Aug 2024 10:25:29 -0400 Subject: [PATCH 10/13] r/aws_db_instance_role_association: Migrate to AWS SDK for Go v2. --- .../service/rds/cluster_role_association.go | 2 +- .../rds/cluster_role_association_test.go | 8 +- internal/service/rds/exports_test.go | 2 + .../service/rds/instance_role_association.go | 188 +++++++++--------- .../rds/instance_role_association_test.go | 66 ++---- internal/service/rds/service_package_gen.go | 3 +- 6 files changed, 115 insertions(+), 154 deletions(-) diff --git a/internal/service/rds/cluster_role_association.go b/internal/service/rds/cluster_role_association.go index 3ad6f855a664..a99c025e9b3c 100644 --- a/internal/service/rds/cluster_role_association.go +++ b/internal/service/rds/cluster_role_association.go @@ -105,7 +105,7 @@ func resourceClusterRoleAssociationRead(ctx context.Context, d *schema.ResourceD output, err := findDBClusterRoleByTwoPartKey(ctx, conn, dbClusterID, roleARN) if !d.IsNewResource() && tfresource.NotFound(err) { - log.Printf("[WARN] RDS DB Cluster (%s) IAM Role (%s) Association not found, removing from state", dbClusterID, roleARN) + log.Printf("[WARN] RDS Cluster (%s) IAM Role (%s) Association not found, removing from state", dbClusterID, roleARN) d.SetId("") return diags } diff --git a/internal/service/rds/cluster_role_association_test.go b/internal/service/rds/cluster_role_association_test.go index e1e10471d3c1..17b812790963 100644 --- a/internal/service/rds/cluster_role_association_test.go +++ b/internal/service/rds/cluster_role_association_test.go @@ -126,11 +126,11 @@ func TestAccRDSClusterRoleAssociation_Disappears_role(t *testing.T) { }) } -func testAccCheckClusterRoleAssociationExists(ctx context.Context, resourceName string, v *types.DBClusterRole) resource.TestCheckFunc { +func testAccCheckClusterRoleAssociationExists(ctx context.Context, n string, v *types.DBClusterRole) resource.TestCheckFunc { return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[resourceName] + rs, ok := s.RootModule().Resources[n] if !ok { - return fmt.Errorf("Not found: %s", resourceName) + return fmt.Errorf("Not found: %s", n) } conn := acctest.Provider.Meta().(*conns.AWSClient).RDSClient(ctx) @@ -166,7 +166,7 @@ func testAccCheckClusterRoleAssociationDestroy(ctx context.Context) resource.Tes return err } - return fmt.Errorf("RDS DB Cluster IAM Role Association %s still exists", rs.Primary.ID) + return fmt.Errorf("RDS Cluster IAM Role Association %s still exists", rs.Primary.ID) } return nil diff --git a/internal/service/rds/exports_test.go b/internal/service/rds/exports_test.go index 26a7beb4057f..35684956d824 100644 --- a/internal/service/rds/exports_test.go +++ b/internal/service/rds/exports_test.go @@ -14,6 +14,7 @@ var ( ResourceCustomDBEngineVersion = resourceCustomDBEngineVersion ResourceEventSubscription = resourceEventSubscription ResourceInstanceAutomatedBackupsReplication = resourceInstanceAutomatedBackupsReplication + ResourceInstanceRoleAssociation = resourceInstanceRoleAssociation ResourceParameterGroup = resourceParameterGroup ResourceProxy = resourceProxy ResourceProxyDefaultTargetGroup = resourceProxyDefaultTargetGroup @@ -30,6 +31,7 @@ var ( FindDBClusterSnapshotByID = findDBClusterSnapshotByID FindDBInstanceAutomatedBackupByARN = findDBInstanceAutomatedBackupByARN FindDBInstanceByID = findDBInstanceByIDSDKv1 + FindDBInstanceRoleByTwoPartKey = findDBInstanceRoleByTwoPartKey FindDBParameterGroupByName = findDBParameterGroupByName FindDBProxyByName = findDBProxyByName FindDBProxyEndpointByTwoPartKey = findDBProxyEndpointByTwoPartKey diff --git a/internal/service/rds/instance_role_association.go b/internal/service/rds/instance_role_association.go index 533d8dfb1abe..55803f1aa254 100644 --- a/internal/service/rds/instance_role_association.go +++ b/internal/service/rds/instance_role_association.go @@ -10,14 +10,16 @@ import ( "strings" "time" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/rds" - "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/rds" + "github.com/aws/aws-sdk-go-v2/service/rds/types" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/errs" "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" + tfslices "github.com/hashicorp/terraform-provider-aws/internal/slices" "github.com/hashicorp/terraform-provider-aws/internal/tfresource" "github.com/hashicorp/terraform-provider-aws/internal/verify" "github.com/hashicorp/terraform-provider-aws/names" @@ -29,13 +31,8 @@ const ( dbInstanceRoleStatusPending = "PENDING" ) -const ( - dbInstanceRoleAssociationCreatedTimeout = 10 * time.Minute - dbInstanceRoleAssociationDeletedTimeout = 10 * time.Minute -) - -// @SDKResource("aws_db_instance_role_association") -func ResourceInstanceRoleAssociation() *schema.Resource { +// @SDKResource("aws_db_instance_role_association", name="DB Instance IAM Role Association") +func resourceInstanceRoleAssociation() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceInstanceRoleAssociationCreate, ReadWithoutTimeout: resourceInstanceRoleAssociationRead, @@ -68,39 +65,32 @@ func ResourceInstanceRoleAssociation() *schema.Resource { func resourceInstanceRoleAssociationCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).RDSConn(ctx) + conn := meta.(*conns.AWSClient).RDSClient(ctx) dbInstanceIdentifier := d.Get("db_instance_identifier").(string) - roleArn := d.Get(names.AttrRoleARN).(string) - + roleARN := d.Get(names.AttrRoleARN).(string) + id := instanceRoleAssociationCreateResourceID(dbInstanceIdentifier, roleARN) input := &rds.AddRoleToDBInstanceInput{ DBInstanceIdentifier: aws.String(dbInstanceIdentifier), FeatureName: aws.String(d.Get("feature_name").(string)), - RoleArn: aws.String(roleArn), + RoleArn: aws.String(roleARN), } - err := retry.RetryContext(ctx, propagationTimeout, func() *retry.RetryError { - var err error - _, err = conn.AddRoleToDBInstanceWithContext(ctx, input) - if err != nil { - if tfawserr.ErrMessageContains(err, "InvalidParameterValue", "IAM role ARN value is invalid or does not include the required permissions") { - return retry.RetryableError(err) - } - return retry.NonRetryableError(err) - } - return nil - }) - if tfresource.TimedOut(err) { - _, err = conn.AddRoleToDBInstanceWithContext(ctx, input) - } + _, err := tfresource.RetryWhenAWSErrMessageContains(ctx, propagationTimeout, func() (interface{}, error) { + return conn.AddRoleToDBInstance(ctx, input) + }, errCodeInvalidParameterValue, "IAM role ARN value is invalid or does not include the required permissions") + if err != nil { - return sdkdiag.AppendErrorf(diags, "associating RDS DB Instance (%s) IAM Role (%s): %s", dbInstanceIdentifier, roleArn, err) + return sdkdiag.AppendErrorf(diags, "creating RDS DB Instance IAM Role Association (%s): %s", id, err) } - d.SetId(fmt.Sprintf("%s,%s", dbInstanceIdentifier, roleArn)) + d.SetId(id) - if err := waitForDBInstanceRoleAssociation(ctx, conn, dbInstanceIdentifier, roleArn); err != nil { - return sdkdiag.AppendErrorf(diags, "waiting for RDS DB Instance (%s) IAM Role (%s) association: %s", dbInstanceIdentifier, roleArn, err) + const ( + timeout = 10 * time.Minute + ) + if _, err := waitDBInstanceRoleAssociationCreated(ctx, conn, dbInstanceIdentifier, roleARN, timeout); err != nil { + return sdkdiag.AppendErrorf(diags, "waiting for RDS DB Instance IAM Role Association (%s) create: %s", d.Id(), err) } return append(diags, resourceInstanceRoleAssociationRead(ctx, d, meta)...) @@ -108,23 +98,23 @@ func resourceInstanceRoleAssociationCreate(ctx context.Context, d *schema.Resour func resourceInstanceRoleAssociationRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).RDSConn(ctx) + conn := meta.(*conns.AWSClient).RDSClient(ctx) - dbInstanceIdentifier, roleArn, err := InstanceRoleAssociationDecodeID(d.Id()) + dbInstanceIdentifier, roleARN, err := instanceRoleAssociationParseResourceID(d.Id()) if err != nil { - return sdkdiag.AppendErrorf(diags, "reading resource ID: %s", err) + return sdkdiag.AppendFromErr(diags, err) } - dbInstanceRole, err := DescribeDBInstanceRole(ctx, conn, dbInstanceIdentifier, roleArn) + dbInstanceRole, err := findDBInstanceRoleByTwoPartKey(ctx, conn, dbInstanceIdentifier, roleARN) if !d.IsNewResource() && tfresource.NotFound(err) { - log.Printf("[WARN] RDS DB Instance (%s) not found, removing from state", dbInstanceIdentifier) + log.Printf("[WARN] RDS DB Instance (%s) IAM Role (%s) Association not found, removing from state", dbInstanceIdentifier, roleARN) d.SetId("") return diags } if err != nil { - return sdkdiag.AppendErrorf(diags, "reading RDS DB Instance (%s) IAM Role (%s) association: %s", dbInstanceIdentifier, roleArn, err) + return sdkdiag.AppendErrorf(diags, "reading RDS DB Instance IAM Role Association (%s): %s", d.Id(), err) } d.Set("db_instance_identifier", dbInstanceIdentifier) @@ -136,109 +126,115 @@ func resourceInstanceRoleAssociationRead(ctx context.Context, d *schema.Resource func resourceInstanceRoleAssociationDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).RDSConn(ctx) + conn := meta.(*conns.AWSClient).RDSClient(ctx) - dbInstanceIdentifier, roleArn, err := InstanceRoleAssociationDecodeID(d.Id()) + dbInstanceIdentifier, roleARN, err := instanceRoleAssociationParseResourceID(d.Id()) if err != nil { - return sdkdiag.AppendErrorf(diags, "reading resource ID: %s", err) + return sdkdiag.AppendFromErr(diags, err) } - input := &rds.RemoveRoleFromDBInstanceInput{ + log.Printf("[DEBUG] Deleting RDS DB Instance IAM Role Association: %s", d.Id()) + _, err = conn.RemoveRoleFromDBInstance(ctx, &rds.RemoveRoleFromDBInstanceInput{ DBInstanceIdentifier: aws.String(dbInstanceIdentifier), FeatureName: aws.String(d.Get("feature_name").(string)), - RoleArn: aws.String(roleArn), - } - - log.Printf("[DEBUG] RDS DB Instance (%s) IAM Role disassociating: %s", dbInstanceIdentifier, roleArn) - _, err = conn.RemoveRoleFromDBInstanceWithContext(ctx, input) - - if tfawserr.ErrCodeEquals(err, rds.ErrCodeDBInstanceNotFoundFault) { - return diags - } + RoleArn: aws.String(roleARN), + }) - if tfawserr.ErrCodeEquals(err, rds.ErrCodeDBInstanceRoleNotFoundFault) { + if errs.IsA[*types.DBInstanceNotFoundFault](err) || errs.IsA[*types.DBInstanceRoleNotFoundFault](err) { return diags } if err != nil { - return sdkdiag.AppendErrorf(diags, "disassociating RDS DB Instance (%s) IAM Role (%s): %s", dbInstanceIdentifier, roleArn, err) + return sdkdiag.AppendErrorf(diags, "deleting RDS DB Instance IAM Role Association (%s): %s", d.Id(), err) } - if err := WaitForDBInstanceRoleDisassociation(ctx, conn, dbInstanceIdentifier, roleArn); err != nil { - return sdkdiag.AppendErrorf(diags, "waiting for RDS DB Instance (%s) IAM Role (%s) disassociation: %s", dbInstanceIdentifier, roleArn, err) + const ( + timeout = 10 * time.Minute + ) + if _, err := waitDBInstanceRoleAssociationDeleted(ctx, conn, dbInstanceIdentifier, roleARN, timeout); err != nil { + return sdkdiag.AppendErrorf(diags, "waiting for RDS DB Instance IAM Role Association (%s) delete: %s", d.Id(), err) } return diags } -func InstanceRoleAssociationDecodeID(id string) (string, string, error) { - parts := strings.SplitN(id, ",", 2) +const instanceRoleAssociationResourceIDSeparator = "," + +func instanceRoleAssociationCreateResourceID(dbInstanceID, roleARN string) string { + parts := []string{dbInstanceID, roleARN} + id := strings.Join(parts, instanceRoleAssociationResourceIDSeparator) + + return id +} + +func instanceRoleAssociationParseResourceID(id string) (string, string, error) { + parts := strings.SplitN(id, instanceRoleAssociationResourceIDSeparator, 2) if len(parts) != 2 || parts[0] == "" || parts[1] == "" { - return "", "", fmt.Errorf("unexpected format of ID (%s), expected DB-INSTANCE-ID,ROLE-ARN", id) + return "", "", fmt.Errorf("unexpected format for ID (%[1]s), expected DB-INSTANCE-ID%[2]sROLE-ARN", id, instanceRoleAssociationResourceIDSeparator) } return parts[0], parts[1], nil } -func DescribeDBInstanceRole(ctx context.Context, conn *rds.RDS, dbInstanceIdentifier, roleArn string) (*rds.DBInstanceRole, error) { - dbInstance, err := findDBInstanceByIDSDKv1(ctx, conn, dbInstanceIdentifier) +func findDBInstanceRoleByTwoPartKey(ctx context.Context, conn *rds.Client, dbInstanceIdentifier, roleARN string) (*types.DBInstanceRole, error) { + dbInstance, err := findDBInstanceByIDSDKv2(ctx, conn, dbInstanceIdentifier) + if err != nil { return nil, err } - for _, associatedRole := range dbInstance.AssociatedRoles { - if aws.StringValue(associatedRole.RoleArn) == roleArn { - return associatedRole, nil + return tfresource.AssertSingleValueResult(tfslices.Filter(dbInstance.AssociatedRoles, func(v types.DBInstanceRole) bool { + return aws.ToString(v.RoleArn) == roleARN + })) +} + +func statusDBInstanceRoleAssociation(ctx context.Context, conn *rds.Client, dbInstanceIdentifier, roleARN string) retry.StateRefreshFunc { + return func() (interface{}, string, error) { + output, err := findDBInstanceRoleByTwoPartKey(ctx, conn, dbInstanceIdentifier, roleARN) + + if tfresource.NotFound(err) { + return nil, "", nil + } + + if err != nil { + return nil, "", err } - } - return nil, &tfresource.EmptyResultError{} + return output, aws.ToString(output.Status), nil + } } -func waitForDBInstanceRoleAssociation(ctx context.Context, conn *rds.RDS, dbInstanceIdentifier, roleArn string) error { +func waitDBInstanceRoleAssociationCreated(ctx context.Context, conn *rds.Client, dbInstanceIdentifier, roleARN string, timeout time.Duration) (*types.DBInstanceRole, error) { stateConf := &retry.StateChangeConf{ Pending: []string{dbInstanceRoleStatusPending}, Target: []string{dbInstanceRoleStatusActive}, - Refresh: statusDBInstanceRoleAssociation(ctx, conn, dbInstanceIdentifier, roleArn), - Timeout: dbInstanceRoleAssociationCreatedTimeout, + Refresh: statusDBInstanceRoleAssociation(ctx, conn, dbInstanceIdentifier, roleARN), + Timeout: timeout, } - log.Printf("[DEBUG] Waiting for RDS DB Instance (%s) IAM Role association: %s", dbInstanceIdentifier, roleArn) - _, err := stateConf.WaitForStateContext(ctx) + outputRaw, err := stateConf.WaitForStateContext(ctx) + + if output, ok := outputRaw.(*types.DBInstanceRole); ok { + return output, err + } - return err + return nil, err } -func WaitForDBInstanceRoleDisassociation(ctx context.Context, conn *rds.RDS, dbInstanceIdentifier, roleArn string) error { +func waitDBInstanceRoleAssociationDeleted(ctx context.Context, conn *rds.Client, dbInstanceIdentifier, roleARN string, timeout time.Duration) (*types.DBInstanceRole, error) { stateConf := &retry.StateChangeConf{ - Pending: []string{ - dbInstanceRoleStatusActive, - dbInstanceRoleStatusPending, - }, + Pending: []string{dbInstanceRoleStatusActive, dbInstanceRoleStatusPending}, Target: []string{}, - Refresh: statusDBInstanceRoleAssociation(ctx, conn, dbInstanceIdentifier, roleArn), - Timeout: dbInstanceRoleAssociationDeletedTimeout, + Refresh: statusDBInstanceRoleAssociation(ctx, conn, dbInstanceIdentifier, roleARN), + Timeout: timeout, } - log.Printf("[DEBUG] Waiting for RDS DB Instance (%s) IAM Role disassociation: %s", dbInstanceIdentifier, roleArn) - _, err := stateConf.WaitForStateContext(ctx) - - return err -} - -func statusDBInstanceRoleAssociation(ctx context.Context, conn *rds.RDS, dbInstanceIdentifier, roleArn string) retry.StateRefreshFunc { - return func() (interface{}, string, error) { - dbInstanceRole, err := DescribeDBInstanceRole(ctx, conn, dbInstanceIdentifier, roleArn) - - if tfresource.NotFound(err) { - return nil, "", nil - } - - if err != nil { - return nil, "", err - } + outputRaw, err := stateConf.WaitForStateContext(ctx) - return dbInstanceRole, aws.StringValue(dbInstanceRole.Status), nil + if output, ok := outputRaw.(*types.DBInstanceRole); ok { + return output, err } + + return nil, err } diff --git a/internal/service/rds/instance_role_association_test.go b/internal/service/rds/instance_role_association_test.go index 3b1b6174e229..c64138e1beee 100644 --- a/internal/service/rds/instance_role_association_test.go +++ b/internal/service/rds/instance_role_association_test.go @@ -8,8 +8,7 @@ import ( "fmt" "testing" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/rds" + "github.com/aws/aws-sdk-go-v2/service/rds/types" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -26,7 +25,7 @@ func TestAccRDSInstanceRoleAssociation_basic(t *testing.T) { t.Skip("skipping long-running test in short mode") } - var dbInstanceRole1 rds.DBInstanceRole + var dbInstanceRole1 types.DBInstanceRole rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) dbInstanceResourceName := "aws_db_instance.test" iamRoleResourceName := "aws_iam_role.test" @@ -62,10 +61,8 @@ func TestAccRDSInstanceRoleAssociation_disappears(t *testing.T) { t.Skip("skipping long-running test in short mode") } - var dbInstance1 rds.DBInstance - var dbInstanceRole1 rds.DBInstanceRole + var dbInstanceRole1 types.DBInstanceRole rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - dbInstanceResourceName := "aws_db_instance.test" resourceName := "aws_db_instance_role_association.test" resource.ParallelTest(t, resource.TestCase{ @@ -77,9 +74,8 @@ func TestAccRDSInstanceRoleAssociation_disappears(t *testing.T) { { Config: testAccInstanceRoleAssociationConfig_basic(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckDBInstanceExists(ctx, dbInstanceResourceName, &dbInstance1), testAccCheckInstanceRoleAssociationExists(ctx, resourceName, &dbInstanceRole1), - testAccCheckInstanceRoleAssociationDisappears(ctx, &dbInstance1, &dbInstanceRole1), + acctest.CheckResourceDisappears(ctx, acctest.Provider, tfrds.ResourceInstanceRoleAssociation(), resourceName), ), ExpectNonEmptyPlan: true, }, @@ -87,34 +83,22 @@ func TestAccRDSInstanceRoleAssociation_disappears(t *testing.T) { }) } -func testAccCheckInstanceRoleAssociationExists(ctx context.Context, resourceName string, dbInstanceRole *rds.DBInstanceRole) resource.TestCheckFunc { +func testAccCheckInstanceRoleAssociationExists(ctx context.Context, n string, v *types.DBInstanceRole) resource.TestCheckFunc { return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[resourceName] - + rs, ok := s.RootModule().Resources[n] if !ok { - return fmt.Errorf("Resource not found: %s", resourceName) + return fmt.Errorf("Not found: %s", n) } - dbInstanceIdentifier, roleArn, err := tfrds.InstanceRoleAssociationDecodeID(rs.Primary.ID) - if err != nil { - return fmt.Errorf("error reading resource ID: %s", err) - } + conn := acctest.Provider.Meta().(*conns.AWSClient).RDSClient(ctx) - conn := acctest.Provider.Meta().(*conns.AWSClient).RDSConn(ctx) + output, err := tfrds.FindDBInstanceRoleByTwoPartKey(ctx, conn, rs.Primary.Attributes["db_instance_identifier"], rs.Primary.Attributes[names.AttrRoleARN]) - role, err := tfrds.DescribeDBInstanceRole(ctx, conn, dbInstanceIdentifier, roleArn) - if tfresource.NotFound(err) { - return fmt.Errorf("RDS DB Instance IAM Role Association not found") - } if err != nil { return err } - if aws.StringValue(role.Status) != "ACTIVE" { - return fmt.Errorf("RDS DB Instance (%s) IAM Role (%s) association exists in non-ACTIVE (%s) state", dbInstanceIdentifier, roleArn, aws.StringValue(role.Status)) - } - - *dbInstanceRole = *role + *v = *output return nil } @@ -122,52 +106,30 @@ func testAccCheckInstanceRoleAssociationExists(ctx context.Context, resourceName func testAccCheckInstanceRoleAssociationDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { - conn := acctest.Provider.Meta().(*conns.AWSClient).RDSConn(ctx) + conn := acctest.Provider.Meta().(*conns.AWSClient).RDSClient(ctx) for _, rs := range s.RootModule().Resources { if rs.Type != "aws_db_instance_role_association" { continue } - dbInstanceIdentifier, roleArn, err := tfrds.InstanceRoleAssociationDecodeID(rs.Primary.ID) - if err != nil { - return fmt.Errorf("error reading resource ID: %s", err) - } + _, err := tfrds.FindDBInstanceRoleByTwoPartKey(ctx, conn, rs.Primary.Attributes["db_instance_identifier"], rs.Primary.Attributes[names.AttrRoleARN]) - dbInstanceRole, err := tfrds.DescribeDBInstanceRole(ctx, conn, dbInstanceIdentifier, roleArn) if tfresource.NotFound(err) { continue } + if err != nil { return err } - return fmt.Errorf("RDS DB Instance (%s) IAM Role (%s) association still exists in non-deleted (%s) state", dbInstanceIdentifier, roleArn, aws.StringValue(dbInstanceRole.Status)) + return fmt.Errorf("RDS DB Instance IAM Role Association %s still exists", rs.Primary.ID) } return nil } } -func testAccCheckInstanceRoleAssociationDisappears(ctx context.Context, dbInstance *rds.DBInstance, dbInstanceRole *rds.DBInstanceRole) resource.TestCheckFunc { - return func(s *terraform.State) error { - conn := acctest.Provider.Meta().(*conns.AWSClient).RDSConn(ctx) - - input := &rds.RemoveRoleFromDBInstanceInput{ - DBInstanceIdentifier: dbInstance.DBInstanceIdentifier, - FeatureName: dbInstanceRole.FeatureName, - RoleArn: dbInstanceRole.RoleArn, - } - - _, err := conn.RemoveRoleFromDBInstanceWithContext(ctx, input) - if err != nil { - return err - } - - return tfrds.WaitForDBInstanceRoleDisassociation(ctx, conn, aws.StringValue(dbInstance.DBInstanceIdentifier), aws.StringValue(dbInstanceRole.RoleArn)) - } -} - func testAccInstanceRoleAssociationConfig_basic(rName string) string { return fmt.Sprintf(` resource "aws_db_instance_role_association" "test" { diff --git a/internal/service/rds/service_package_gen.go b/internal/service/rds/service_package_gen.go index 95a34d351099..338d8d4e149d 100644 --- a/internal/service/rds/service_package_gen.go +++ b/internal/service/rds/service_package_gen.go @@ -133,8 +133,9 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePacka Name: "Instance Automated Backups Replication", }, { - Factory: ResourceInstanceRoleAssociation, + Factory: resourceInstanceRoleAssociation, TypeName: "aws_db_instance_role_association", + Name: "DB Instance IAM Role Association", }, { Factory: ResourceOptionGroup, From 3d6bdd3022e76725b780a8a38697e18ba969fcdc Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 1 Aug 2024 11:47:53 -0400 Subject: [PATCH 11/13] r/aws_db_option_group: Migrate to AWS SDK for Go v2. --- internal/service/rds/exports_test.go | 2 + internal/service/rds/option_group.go | 286 ++++++++------------ internal/service/rds/option_group_test.go | 50 ++-- internal/service/rds/service_package_gen.go | 2 +- internal/service/rds/sweep.go | 2 +- 5 files changed, 145 insertions(+), 197 deletions(-) diff --git a/internal/service/rds/exports_test.go b/internal/service/rds/exports_test.go index 35684956d824..be465b9cb7e1 100644 --- a/internal/service/rds/exports_test.go +++ b/internal/service/rds/exports_test.go @@ -15,6 +15,7 @@ var ( ResourceEventSubscription = resourceEventSubscription ResourceInstanceAutomatedBackupsReplication = resourceInstanceAutomatedBackupsReplication ResourceInstanceRoleAssociation = resourceInstanceRoleAssociation + ResourceOptionGroup = resourceOptionGroup ResourceParameterGroup = resourceParameterGroup ResourceProxy = resourceProxy ResourceProxyDefaultTargetGroup = resourceProxyDefaultTargetGroup @@ -41,6 +42,7 @@ var ( FindDefaultCertificate = findDefaultCertificate FindDefaultDBProxyTargetGroupByDBProxyName = findDefaultDBProxyTargetGroupByDBProxyName FindEventSubscriptionByID = findEventSubscriptionByID + FindOptionGroupByName = findOptionGroupByName ListTags = listTags NewBlueGreenOrchestrator = newBlueGreenOrchestrator ParameterGroupModifyChunk = parameterGroupModifyChunk diff --git a/internal/service/rds/option_group.go b/internal/service/rds/option_group.go index fb390899940a..14fea7aed7e7 100644 --- a/internal/service/rds/option_group.go +++ b/internal/service/rds/option_group.go @@ -6,17 +6,19 @@ package rds import ( "context" "log" + "slices" "strings" "time" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/rds" - "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/rds" + "github.com/aws/aws-sdk-go-v2/service/rds/types" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/create" + "github.com/hashicorp/terraform-provider-aws/internal/errs" "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" "github.com/hashicorp/terraform-provider-aws/internal/flex" tfslices "github.com/hashicorp/terraform-provider-aws/internal/slices" @@ -29,7 +31,7 @@ import ( // @SDKResource("aws_db_option_group", name="DB Option Group") // @Tags(identifierAttribute="arn") // @Testing(tagsTest=false) -func ResourceOptionGroup() *schema.Resource { +func resourceOptionGroup() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceOptionGroupCreate, ReadWithoutTimeout: resourceOptionGroupRead, @@ -137,7 +139,7 @@ func ResourceOptionGroup() *schema.Resource { func resourceOptionGroupCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).RDSConn(ctx) + conn := meta.(*conns.AWSClient).RDSClient(ctx) name := create.Name(d.Get(names.AttrName).(string), d.Get(names.AttrNamePrefix).(string)) input := &rds.CreateOptionGroupInput{ @@ -145,10 +147,10 @@ func resourceOptionGroupCreate(ctx context.Context, d *schema.ResourceData, meta MajorEngineVersion: aws.String(d.Get("major_engine_version").(string)), OptionGroupDescription: aws.String(d.Get("option_group_description").(string)), OptionGroupName: aws.String(name), - Tags: getTagsIn(ctx), + Tags: getTagsInV2(ctx), } - _, err := conn.CreateOptionGroupWithContext(ctx, input) + _, err := conn.CreateOptionGroup(ctx, input) if err != nil { return sdkdiag.AppendErrorf(diags, "creating RDS DB Option Group (%s): %s", name, err) @@ -161,9 +163,9 @@ func resourceOptionGroupCreate(ctx context.Context, d *schema.ResourceData, meta func resourceOptionGroupRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).RDSConn(ctx) + conn := meta.(*conns.AWSClient).RDSClient(ctx) - option, err := FindOptionGroupByName(ctx, conn, d.Id()) + option, err := findOptionGroupByName(ctx, conn, d.Id()) if !d.IsNewResource() && tfresource.NotFound(err) { log.Printf("[WARN] RDS DB Option Group (%s) not found, removing from state", d.Id()) @@ -179,8 +181,8 @@ func resourceOptionGroupRead(ctx context.Context, d *schema.ResourceData, meta i d.Set("engine_name", option.EngineName) d.Set("major_engine_version", option.MajorEngineVersion) d.Set(names.AttrName, option.OptionGroupName) - d.Set(names.AttrNamePrefix, create.NamePrefixFromName(aws.StringValue(option.OptionGroupName))) - if err := d.Set("option", flattenOptions(option.Options, expandOptionConfiguration(d.Get("option").(*schema.Set).List()))); err != nil { + d.Set(names.AttrNamePrefix, create.NamePrefixFromName(aws.ToString(option.OptionGroupName))) + if err := d.Set("option", flattenOptions(option.Options, expandOptionConfigurations(d.Get("option").(*schema.Set).List()))); err != nil { return sdkdiag.AppendErrorf(diags, "setting option: %s", err) } d.Set("option_group_description", option.OptionGroupDescription) @@ -190,32 +192,24 @@ func resourceOptionGroupRead(ctx context.Context, d *schema.ResourceData, meta i func resourceOptionGroupUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).RDSConn(ctx) + conn := meta.(*conns.AWSClient).RDSClient(ctx) if d.HasChange("option") { o, n := d.GetChange("option") - if o == nil { - o = new(schema.Set) - } - if n == nil { - n = new(schema.Set) - } - - os := o.(*schema.Set) - ns := n.(*schema.Set) - optionsToInclude := expandOptionConfiguration(ns.Difference(os).List()) + os, ns := o.(*schema.Set), n.(*schema.Set) + optionsToInclude := expandOptionConfigurations(ns.Difference(os).List()) optionsToIncludeNames := flattenOptionNames(ns.Difference(os).List()) - optionsToRemove := []*string{} + optionsToRemove := []string{} optionsToRemoveNames := flattenOptionNames(os.Difference(ns).List()) for _, optionToRemoveName := range optionsToRemoveNames { - if optionInList(*optionToRemoveName, optionsToIncludeNames) { + if slices.Contains(optionsToIncludeNames, optionToRemoveName) { continue } optionsToRemove = append(optionsToRemove, optionToRemoveName) } - // Ensure there is actually something to update + // Ensure there is actually something to update. // InvalidParameterValue: At least one option must be added, modified, or removed. if len(optionsToInclude) > 0 || len(optionsToRemove) > 0 { input := &rds.ModifyOptionGroupInput{ @@ -232,7 +226,7 @@ func resourceOptionGroupUpdate(ctx context.Context, d *schema.ResourceData, meta } _, err := tfresource.RetryWhenAWSErrMessageContains(ctx, propagationTimeout, func() (interface{}, error) { - return conn.ModifyOptionGroupWithContext(ctx, input) + return conn.ModifyOptionGroup(ctx, input) }, errCodeInvalidParameterValue, "IAM role ARN value is invalid or does not include the required permissions") if err != nil { @@ -246,16 +240,16 @@ func resourceOptionGroupUpdate(ctx context.Context, d *schema.ResourceData, meta func resourceOptionGroupDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).RDSConn(ctx) + conn := meta.(*conns.AWSClient).RDSClient(ctx) log.Printf("[DEBUG] Deleting RDS DB Option Group: %s", d.Id()) - _, err := tfresource.RetryWhenAWSErrCodeEquals(ctx, d.Timeout(schema.TimeoutDelete), func() (interface{}, error) { - return conn.DeleteOptionGroupWithContext(ctx, &rds.DeleteOptionGroupInput{ + _, err := tfresource.RetryWhenIsA[*types.InvalidOptionGroupStateFault](ctx, d.Timeout(schema.TimeoutDelete), func() (interface{}, error) { + return conn.DeleteOptionGroup(ctx, &rds.DeleteOptionGroupInput{ OptionGroupName: aws.String(d.Id()), }) - }, rds.ErrCodeInvalidOptionGroupStateFault) + }) - if tfawserr.ErrCodeEquals(err, rds.ErrCodeOptionGroupNotFoundFault) { + if errs.IsA[*types.OptionGroupNotFoundFault](err) { return diags } @@ -266,18 +260,18 @@ func resourceOptionGroupDelete(ctx context.Context, d *schema.ResourceData, meta return diags } -func FindOptionGroupByName(ctx context.Context, conn *rds.RDS, name string) (*rds.OptionGroup, error) { +func findOptionGroupByName(ctx context.Context, conn *rds.Client, name string) (*types.OptionGroup, error) { input := &rds.DescribeOptionGroupsInput{ OptionGroupName: aws.String(name), } - output, err := findOptionGroup(ctx, conn, input, tfslices.PredicateTrue[*rds.OptionGroup]()) + output, err := findOptionGroup(ctx, conn, input, tfslices.PredicateTrue[*types.OptionGroup]()) if err != nil { return nil, err } // Eventual consistency check. - if aws.StringValue(output.OptionGroupName) != name { + if aws.ToString(output.OptionGroupName) != name { return nil, &retry.NotFoundError{ LastRequest: input, } @@ -286,224 +280,176 @@ func FindOptionGroupByName(ctx context.Context, conn *rds.RDS, name string) (*rd return output, nil } -func findOptionGroup(ctx context.Context, conn *rds.RDS, input *rds.DescribeOptionGroupsInput, filter tfslices.Predicate[*rds.OptionGroup]) (*rds.OptionGroup, error) { +func findOptionGroup(ctx context.Context, conn *rds.Client, input *rds.DescribeOptionGroupsInput, filter tfslices.Predicate[*types.OptionGroup]) (*types.OptionGroup, error) { output, err := findOptionGroups(ctx, conn, input, filter) if err != nil { return nil, err } - return tfresource.AssertSinglePtrResult(output) + return tfresource.AssertSingleValueResult(output) } -func findOptionGroups(ctx context.Context, conn *rds.RDS, input *rds.DescribeOptionGroupsInput, filter tfslices.Predicate[*rds.OptionGroup]) ([]*rds.OptionGroup, error) { - var output []*rds.OptionGroup +func findOptionGroups(ctx context.Context, conn *rds.Client, input *rds.DescribeOptionGroupsInput, filter tfslices.Predicate[*types.OptionGroup]) ([]types.OptionGroup, error) { + var output []types.OptionGroup - err := conn.DescribeOptionGroupsPagesWithContext(ctx, input, func(page *rds.DescribeOptionGroupsOutput, lastPage bool) bool { - if page == nil { - return !lastPage - } + pages := rds.NewDescribeOptionGroupsPaginator(conn, input) + for pages.HasMorePages() { + page, err := pages.NextPage(ctx) - for _, v := range page.OptionGroupsList { - if v != nil && filter(v) { - output = append(output, v) + if errs.IsA[*types.OptionGroupNotFoundFault](err) { + return nil, &retry.NotFoundError{ + LastError: err, + LastRequest: input, } } - return !lastPage - }) - - if tfawserr.ErrCodeEquals(err, rds.ErrCodeOptionGroupNotFoundFault) { - return nil, &retry.NotFoundError{ - LastError: err, - LastRequest: input, + if err != nil { + return nil, err } - } - if err != nil { - return nil, err + for _, v := range page.OptionGroupsList { + if filter(&v) { + output = append(output, v) + } + } } return output, nil } -func optionInList(optionName string, list []*string) bool { - for _, opt := range list { - if aws.StringValue(opt) == optionName { - return true - } - } - return false -} - -func flattenOptionNames(configured []interface{}) []*string { - var optionNames []*string - for _, pRaw := range configured { - data := pRaw.(map[string]interface{}) - optionNames = append(optionNames, aws.String(data["option_name"].(string))) - } - - return optionNames +func flattenOptionNames(tfList []interface{}) []string { + return tfslices.ApplyToAll(tfList, func(v interface{}) string { + return v.(map[string]interface{})["option_name"].(string) + }) } -func expandOptionConfiguration(configured []interface{}) []*rds.OptionConfiguration { - var option []*rds.OptionConfiguration +func expandOptionConfigurations(tfList []interface{}) []types.OptionConfiguration { + var apiObjects []types.OptionConfiguration - for _, pRaw := range configured { - data := pRaw.(map[string]interface{}) + for _, tfMapRaw := range tfList { + tfMap := tfMapRaw.(map[string]interface{}) - o := &rds.OptionConfiguration{ - OptionName: aws.String(data["option_name"].(string)), + apiObject := types.OptionConfiguration{ + OptionName: aws.String(tfMap["option_name"].(string)), } - if raw, ok := data[names.AttrPort]; ok { - port := raw.(int) - if port != 0 { - o.Port = aws.Int64(int64(port)) - } + if v, ok := tfMap["db_security_group_memberships"].(*schema.Set); ok && v.Len() > 0 { + apiObject.DBSecurityGroupMemberships = flex.ExpandStringValueSet(v) } - if raw, ok := data["db_security_group_memberships"]; ok { - memberships := flex.ExpandStringSet(raw.(*schema.Set)) - if len(memberships) > 0 { - o.DBSecurityGroupMemberships = memberships - } + if v, ok := tfMap["option_settings"].(*schema.Set); ok && v.Len() > 0 { + apiObject.OptionSettings = expandOptionSettings(v.List()) } - if raw, ok := data["vpc_security_group_memberships"]; ok { - memberships := flex.ExpandStringSet(raw.(*schema.Set)) - if len(memberships) > 0 { - o.VpcSecurityGroupMemberships = memberships - } + if v, ok := tfMap[names.AttrPort].(int); ok && v != 0 { + apiObject.Port = aws.Int32(int32(v)) } - if raw, ok := data["option_settings"]; ok { - o.OptionSettings = expandOptionSetting(raw.(*schema.Set).List()) + if v, ok := tfMap[names.AttrVersion].(string); ok && v != "" { + apiObject.OptionVersion = aws.String(v) } - if raw, ok := data[names.AttrVersion]; ok && raw.(string) != "" { - o.OptionVersion = aws.String(raw.(string)) + if v, ok := tfMap["vpc_security_group_memberships"].(*schema.Set); ok && v.Len() > 0 { + apiObject.VpcSecurityGroupMemberships = flex.ExpandStringValueSet(v) } - option = append(option, o) + apiObjects = append(apiObjects, apiObject) } - return option + return apiObjects } -// Flattens an array of Options into a []map[string]interface{} -func flattenOptions(apiOptions []*rds.Option, optionConfigurations []*rds.OptionConfiguration) []map[string]interface{} { - result := make([]map[string]interface{}, 0) +func flattenOptions(apiObjects []types.Option, configuredObjects []types.OptionConfiguration) []interface{} { + tfList := make([]interface{}, 0) - for _, apiOption := range apiOptions { - if apiOption == nil || apiOption.OptionName == nil { + for _, apiObject := range apiObjects { + if apiObject.OptionName == nil { continue } - var configuredOption *rds.OptionConfiguration - - for _, optionConfiguration := range optionConfigurations { - if aws.StringValue(apiOption.OptionName) == aws.StringValue(optionConfiguration.OptionName) { - configuredOption = optionConfiguration - break - } - } - - dbSecurityGroupMemberships := make([]interface{}, 0) - for _, db := range apiOption.DBSecurityGroupMemberships { - if db != nil { - dbSecurityGroupMemberships = append(dbSecurityGroupMemberships, aws.StringValue(db.DBSecurityGroupName)) - } + optionName := aws.ToString(apiObject.OptionName) + var configuredOption *types.OptionConfiguration + if v := tfslices.Filter(configuredObjects, func(v types.OptionConfiguration) bool { + return aws.ToString(v.OptionName) == optionName + }); len(v) > 0 { + configuredOption = &v[0] } optionSettings := make([]interface{}, 0) - for _, apiOptionSetting := range apiOption.OptionSettings { + for _, apiOptionSetting := range apiObject.OptionSettings { // The RDS API responds with all settings. Omit settings that match default value, // but only if unconfigured. This is to prevent operators from continually needing // to continually update their Terraform configurations to match new option settings // when added by the API. - var configuredOptionSetting *rds.OptionSetting + optionSettingName := aws.ToString(apiOptionSetting.Name) + var configuredOptionSetting *types.OptionSetting if configuredOption != nil { - for _, configuredOptionOptionSetting := range configuredOption.OptionSettings { - if aws.StringValue(apiOptionSetting.Name) == aws.StringValue(configuredOptionOptionSetting.Name) { - configuredOptionSetting = configuredOptionOptionSetting - break - } + if v := tfslices.Filter(configuredOption.OptionSettings, func(v types.OptionSetting) bool { + return aws.ToString(v.Name) == optionSettingName + }); len(v) > 0 { + configuredOptionSetting = &v[0] } } - if configuredOptionSetting == nil && aws.StringValue(apiOptionSetting.Value) == aws.StringValue(apiOptionSetting.DefaultValue) { + optionSettingValue := aws.ToString(apiOptionSetting.Value) + if configuredOptionSetting == nil && optionSettingValue == aws.ToString(apiOptionSetting.DefaultValue) { continue } optionSetting := map[string]interface{}{ - names.AttrName: aws.StringValue(apiOptionSetting.Name), - names.AttrValue: aws.StringValue(apiOptionSetting.Value), + names.AttrName: optionSettingName, + names.AttrValue: optionSettingValue, } // Some values, like passwords, are sent back from the API as ****. - // Set the response to match the configuration to prevent an unexpected difference - if configuredOptionSetting != nil && aws.StringValue(apiOptionSetting.Value) == "****" { - optionSetting[names.AttrValue] = aws.StringValue(configuredOptionSetting.Value) + // Set the response to match the configuration to prevent an unexpected difference. + if configuredOptionSetting != nil && optionSettingValue == "****" { + optionSetting[names.AttrValue] = aws.ToString(configuredOptionSetting.Value) } optionSettings = append(optionSettings, optionSetting) } - optionSettingsResource := &schema.Resource{ - Schema: map[string]*schema.Schema{ - names.AttrName: { - Type: schema.TypeString, - Required: true, - }, - names.AttrValue: { - Type: schema.TypeString, - Required: true, - }, - }, - } - - vpcSecurityGroupMemberships := make([]interface{}, 0) - for _, vpc := range apiOption.VpcSecurityGroupMemberships { - if vpc != nil { - vpcSecurityGroupMemberships = append(vpcSecurityGroupMemberships, aws.StringValue(vpc.VpcSecurityGroupId)) - } - } - r := map[string]interface{}{ - "db_security_group_memberships": schema.NewSet(schema.HashString, dbSecurityGroupMemberships), - "option_name": aws.StringValue(apiOption.OptionName), - "option_settings": schema.NewSet(schema.HashResource(optionSettingsResource), optionSettings), - "vpc_security_group_memberships": schema.NewSet(schema.HashString, vpcSecurityGroupMemberships), + tfMap := map[string]interface{}{ + "db_security_group_memberships": tfslices.ApplyToAll(apiObject.DBSecurityGroupMemberships, func(v types.DBSecurityGroupMembership) string { + return aws.ToString(v.DBSecurityGroupName) + }), + "option_name": optionName, + "option_settings": optionSettings, + "vpc_security_group_memberships": tfslices.ApplyToAll(apiObject.VpcSecurityGroupMemberships, func(v types.VpcSecurityGroupMembership) string { + return aws.ToString(v.VpcSecurityGroupId) + }), } - if apiOption.OptionVersion != nil && configuredOption != nil && configuredOption.OptionVersion != nil { - r[names.AttrVersion] = aws.StringValue(apiOption.OptionVersion) + if apiObject.OptionVersion != nil && configuredOption != nil && configuredOption.OptionVersion != nil { + tfMap[names.AttrVersion] = aws.ToString(apiObject.OptionVersion) } - if apiOption.Port != nil && configuredOption != nil && configuredOption.Port != nil { - r[names.AttrPort] = aws.Int64Value(apiOption.Port) + if apiObject.Port != nil && configuredOption != nil && configuredOption.Port != nil { + tfMap[names.AttrPort] = aws.ToInt32(apiObject.Port) } - result = append(result, r) + tfList = append(tfList, tfMap) } - return result + return tfList } -func expandOptionSetting(list []interface{}) []*rds.OptionSetting { - options := make([]*rds.OptionSetting, 0, len(list)) +func expandOptionSettings(tfList []interface{}) []types.OptionSetting { + apiObjects := make([]types.OptionSetting, 0, len(tfList)) - for _, oRaw := range list { - data := oRaw.(map[string]interface{}) + for _, tfMapRaw := range tfList { + tfMap := tfMapRaw.(map[string]interface{}) - o := &rds.OptionSetting{ - Name: aws.String(data[names.AttrName].(string)), - Value: aws.String(data[names.AttrValue].(string)), + apiObject := types.OptionSetting{ + Name: aws.String(tfMap[names.AttrName].(string)), + Value: aws.String(tfMap[names.AttrValue].(string)), } - options = append(options, o) + apiObjects = append(apiObjects, apiObject) } - return options + return apiObjects } diff --git a/internal/service/rds/option_group_test.go b/internal/service/rds/option_group_test.go index f6f16daa5841..4f5f9ba42d3f 100644 --- a/internal/service/rds/option_group_test.go +++ b/internal/service/rds/option_group_test.go @@ -10,8 +10,8 @@ import ( "testing" "github.com/YakDriver/regexache" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/rds" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/rds/types" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/id" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" @@ -25,7 +25,7 @@ import ( func TestAccRDSOptionGroup_basic(t *testing.T) { ctx := acctest.Context(t) - var v rds.OptionGroup + var v types.OptionGroup rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_db_option_group.test" @@ -60,7 +60,7 @@ func TestAccRDSOptionGroup_basic(t *testing.T) { func TestAccRDSOptionGroup_disappears(t *testing.T) { ctx := acctest.Context(t) - var v rds.OptionGroup + var v types.OptionGroup rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_db_option_group.test" @@ -84,7 +84,7 @@ func TestAccRDSOptionGroup_disappears(t *testing.T) { func TestAccRDSOptionGroup_nameGenerated(t *testing.T) { ctx := acctest.Context(t) - var v rds.OptionGroup + var v types.OptionGroup resourceName := "aws_db_option_group.test" resource.ParallelTest(t, resource.TestCase{ @@ -112,7 +112,7 @@ func TestAccRDSOptionGroup_nameGenerated(t *testing.T) { func TestAccRDSOptionGroup_namePrefix(t *testing.T) { ctx := acctest.Context(t) - var v rds.OptionGroup + var v types.OptionGroup resourceName := "aws_db_option_group.test" resource.ParallelTest(t, resource.TestCase{ @@ -140,7 +140,7 @@ func TestAccRDSOptionGroup_namePrefix(t *testing.T) { func TestAccRDSOptionGroup_tags(t *testing.T) { ctx := acctest.Context(t) - var optionGroup1, optionGroup2, optionGroup3 rds.OptionGroup + var optionGroup1, optionGroup2, optionGroup3 types.OptionGroup resourceName := "aws_db_option_group.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -186,7 +186,7 @@ func TestAccRDSOptionGroup_tags(t *testing.T) { func TestAccRDSOptionGroup_timeoutBlock(t *testing.T) { ctx := acctest.Context(t) - var v rds.OptionGroup + var v types.OptionGroup rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_db_option_group.test" @@ -214,7 +214,7 @@ func TestAccRDSOptionGroup_timeoutBlock(t *testing.T) { func TestAccRDSOptionGroup_optionGroupDescription(t *testing.T) { ctx := acctest.Context(t) - var optionGroup1 rds.OptionGroup + var optionGroup1 types.OptionGroup rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_db_option_group.test" @@ -269,7 +269,7 @@ func TestAccRDSOptionGroup_basicDestroyWithInstance(t *testing.T) { func TestAccRDSOptionGroup_Option_optionSettings(t *testing.T) { ctx := acctest.Context(t) - var v rds.OptionGroup + var v types.OptionGroup rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_db_option_group.test" @@ -320,7 +320,7 @@ func TestAccRDSOptionGroup_Option_optionSettings(t *testing.T) { func TestAccRDSOptionGroup_OptionOptionSettings_iamRole(t *testing.T) { ctx := acctest.Context(t) - var v rds.OptionGroup + var v types.OptionGroup rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_db_option_group.test" @@ -350,7 +350,7 @@ func TestAccRDSOptionGroup_OptionOptionSettings_iamRole(t *testing.T) { func TestAccRDSOptionGroup_sqlServerOptionsUpdate(t *testing.T) { ctx := acctest.Context(t) - var v rds.OptionGroup + var v types.OptionGroup rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_db_option_group.test" @@ -386,7 +386,7 @@ func TestAccRDSOptionGroup_sqlServerOptionsUpdate(t *testing.T) { func TestAccRDSOptionGroup_oracleOptionsUpdate(t *testing.T) { ctx := acctest.Context(t) - var v rds.OptionGroup + var v types.OptionGroup rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_db_option_group.test" @@ -428,7 +428,7 @@ func TestAccRDSOptionGroup_oracleOptionsUpdate(t *testing.T) { // Reference: https://github.com/hashicorp/terraform-provider-aws/issues/1876 func TestAccRDSOptionGroup_OptionOptionSettings_multipleNonDefault(t *testing.T) { ctx := acctest.Context(t) - var optionGroup1, optionGroup2 rds.OptionGroup + var optionGroup1, optionGroup2 types.OptionGroup rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_db_option_group.test" @@ -463,7 +463,7 @@ func TestAccRDSOptionGroup_OptionOptionSettings_multipleNonDefault(t *testing.T) func TestAccRDSOptionGroup_multipleOptions(t *testing.T) { ctx := acctest.Context(t) - var v rds.OptionGroup + var v types.OptionGroup rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_db_option_group.test" @@ -493,7 +493,7 @@ func TestAccRDSOptionGroup_multipleOptions(t *testing.T) { // Reference: https://github.com/hashicorp/terraform-provider-aws/issues/7114 func TestAccRDSOptionGroup_Tags_withOptions(t *testing.T) { ctx := acctest.Context(t) - var optionGroup1, optionGroup2, optionGroup3 rds.OptionGroup + var optionGroup1, optionGroup2, optionGroup3 types.OptionGroup resourceName := "aws_db_option_group.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -543,7 +543,7 @@ func TestAccRDSOptionGroup_Tags_withOptions(t *testing.T) { // https://github.com/hashicorp/terraform-provider-aws/issues/21367 func TestAccRDSOptionGroup_badDiffs(t *testing.T) { ctx := acctest.Context(t) - var optionGroup1 rds.OptionGroup + var optionGroup1 types.OptionGroup resourceName := "aws_db_option_group.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -593,7 +593,7 @@ func TestAccRDSOptionGroup_badDiffs(t *testing.T) { }) } -func testAccCheckOptionGroupOptionSettingsIAMRole(optionGroup *rds.OptionGroup) resource.TestCheckFunc { +func testAccCheckOptionGroupOptionSettingsIAMRole(optionGroup *types.OptionGroup) resource.TestCheckFunc { return func(s *terraform.State) error { if optionGroup == nil { return errors.New("Option Group does not exist") @@ -605,12 +605,12 @@ func testAccCheckOptionGroupOptionSettingsIAMRole(optionGroup *rds.OptionGroup) return errors.New("Option Group does not have any option settings") } - settingName := aws.StringValue(optionGroup.Options[0].OptionSettings[0].Name) + settingName := aws.ToString(optionGroup.Options[0].OptionSettings[0].Name) if settingName != "IAM_ROLE_ARN" { return fmt.Errorf("Expected option setting IAM_ROLE_ARN and received %s", settingName) } - settingValue := aws.StringValue(optionGroup.Options[0].OptionSettings[0].Value) + settingValue := aws.ToString(optionGroup.Options[0].OptionSettings[0].Value) iamArnRegExp := regexache.MustCompile(fmt.Sprintf(`^arn:%s:iam::\d{12}:role/.+`, acctest.Partition())) if !iamArnRegExp.MatchString(settingValue) { return fmt.Errorf("Expected option setting to be a valid IAM role but received %s", settingValue) @@ -619,7 +619,7 @@ func testAccCheckOptionGroupOptionSettingsIAMRole(optionGroup *rds.OptionGroup) } } -func testAccCheckOptionGroupOptionVersionAttribute(optionGroup *rds.OptionGroup, optionVersion string) resource.TestCheckFunc { +func testAccCheckOptionGroupOptionVersionAttribute(optionGroup *types.OptionGroup, optionVersion string) resource.TestCheckFunc { return func(s *terraform.State) error { if optionGroup == nil { return errors.New("Option Group does not exist") @@ -627,7 +627,7 @@ func testAccCheckOptionGroupOptionVersionAttribute(optionGroup *rds.OptionGroup, if len(optionGroup.Options) == 0 { return errors.New("Option Group does not have any options") } - foundOptionVersion := aws.StringValue(optionGroup.Options[0].OptionVersion) + foundOptionVersion := aws.ToString(optionGroup.Options[0].OptionVersion) if foundOptionVersion != optionVersion { return fmt.Errorf("Expected option version %q and received %q", optionVersion, foundOptionVersion) } @@ -635,14 +635,14 @@ func testAccCheckOptionGroupOptionVersionAttribute(optionGroup *rds.OptionGroup, } } -func testAccCheckOptionGroupExists(ctx context.Context, n string, v *rds.OptionGroup) resource.TestCheckFunc { +func testAccCheckOptionGroupExists(ctx context.Context, n string, v *types.OptionGroup) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { return fmt.Errorf("Not found: %s", n) } - conn := acctest.Provider.Meta().(*conns.AWSClient).RDSConn(ctx) + conn := acctest.Provider.Meta().(*conns.AWSClient).RDSClient(ctx) output, err := tfrds.FindOptionGroupByName(ctx, conn, rs.Primary.ID) @@ -658,7 +658,7 @@ func testAccCheckOptionGroupExists(ctx context.Context, n string, v *rds.OptionG func testAccCheckOptionGroupDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { - conn := acctest.Provider.Meta().(*conns.AWSClient).RDSConn(ctx) + conn := acctest.Provider.Meta().(*conns.AWSClient).RDSClient(ctx) for _, rs := range s.RootModule().Resources { if rs.Type != "aws_db_option_group" { diff --git a/internal/service/rds/service_package_gen.go b/internal/service/rds/service_package_gen.go index 338d8d4e149d..286e6581c98d 100644 --- a/internal/service/rds/service_package_gen.go +++ b/internal/service/rds/service_package_gen.go @@ -138,7 +138,7 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePacka Name: "DB Instance IAM Role Association", }, { - Factory: ResourceOptionGroup, + Factory: resourceOptionGroup, TypeName: "aws_db_option_group", Name: "DB Option Group", Tags: &types.ServicePackageResourceTags{ diff --git a/internal/service/rds/sweep.go b/internal/service/rds/sweep.go index de7dd072c3c5..c0ed8499c534 100644 --- a/internal/service/rds/sweep.go +++ b/internal/service/rds/sweep.go @@ -434,7 +434,7 @@ func sweepOptionGroups(region string) error { continue } - r := ResourceOptionGroup() + r := resourceOptionGroup() d := r.Data(nil) d.SetId(name) From 4549a27820c4218e541c3f471f4dc2f8a83e61d5 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 1 Aug 2024 12:00:05 -0400 Subject: [PATCH 12/13] r/aws_db_option_group: Fix acceptance tests. --- internal/service/rds/option_group_test.go | 32 ++++++++++++++--------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/internal/service/rds/option_group_test.go b/internal/service/rds/option_group_test.go index 4f5f9ba42d3f..df3de8d6c4e7 100644 --- a/internal/service/rds/option_group_test.go +++ b/internal/service/rds/option_group_test.go @@ -310,9 +310,10 @@ func TestAccRDSOptionGroup_Option_optionSettings(t *testing.T) { ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"option.0.port"}, }, }, }) @@ -340,9 +341,10 @@ func TestAccRDSOptionGroup_OptionOptionSettings_iamRole(t *testing.T) { ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"option.0.port"}, }, }, }) @@ -446,9 +448,10 @@ func TestAccRDSOptionGroup_OptionOptionSettings_multipleNonDefault(t *testing.T) ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"option.0.port"}, }, { Config: testAccOptionGroupConfig_settingsMultiple(rName, "example1,example2"), @@ -485,6 +488,10 @@ func TestAccRDSOptionGroup_multipleOptions(t *testing.T) { ResourceName: resourceName, ImportState: true, ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "option.0.port", + "option.1.port", + }, }, }, }) @@ -513,9 +520,10 @@ func TestAccRDSOptionGroup_Tags_withOptions(t *testing.T) { ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"option.0.port"}, }, { Config: testAccOptionGroupConfig_tagsOption2(rName, acctest.CtKey1, acctest.CtValue1Updated, acctest.CtKey2, acctest.CtValue2), From 4117037e42dd1333ff6afe4577cd820e474d4365 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 1 Aug 2024 12:01:44 -0400 Subject: [PATCH 13/13] Run 'make fix-constants PKG=rds'. --- internal/service/rds/instance_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/rds/instance_test.go b/internal/service/rds/instance_test.go index d958319798eb..ab8d3e4bd729 100644 --- a/internal/service/rds/instance_test.go +++ b/internal/service/rds/instance_test.go @@ -1101,7 +1101,7 @@ func TestAccRDSInstance_ReplicateSourceDB_upgradeStorageConfig(t *testing.T) { testAccCheckDBInstanceExists(ctx, sourceResourceName, &sourceDbInstance), testAccCheckDBInstanceExists(ctx, resourceName, &dbInstance), testAccCheckInstanceReplicaAttributes(&sourceDbInstance, &dbInstance), - resource.TestCheckResourceAttr(resourceName, "upgrade_storage_config", "true"), + resource.TestCheckResourceAttr(resourceName, "upgrade_storage_config", acctest.CtTrue), ), }, },