From 06d2c0148b1d0ba80837430d8fac29339dd51903 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Wed, 4 Nov 2020 14:56:51 -0500 Subject: [PATCH] service/rds: Additional error handling for Global Clusters, test fixes for engine versions (#15938) Reference: https://github.com/terraform-providers/terraform-provider-aws/issues/8186 At a certain point new RDS Clusters wishing to specify `engine_mode = "global"`, which is now legacy, began automatically creating `provisioned` mode clusters instead. Specifying a compatible `engine_version` allows the legacy `global` mode usage still. Separately, the `engine_version` being used for testing updates to that attribute are now updated to recent versions supported in both AWS Commercial and GovCloud (US). Finally, while testing the test updates, ran into a similar error recently reported in #8186 as well, so added logic to ignore the error in the deletion function because it did not need to be returned. Previously in AWS Commercial: ``` --- FAIL: TestAccAWSRDSCluster_EngineMode_Global (129.27s) TestAccAWSRDSCluster_EngineMode_Global: resource_aws_rds_cluster_test.go:977: Step 1/2 error: Check failed: Check 2/2 error: aws_rds_cluster.test: Attribute 'engine_mode' expected "global", got "provisioned" --- FAIL: TestAccAWSRDSCluster_EngineVersionWithPrimaryInstance (1132.14s) TestAccAWSRDSCluster_EngineVersionWithPrimaryInstance: resource_aws_rds_cluster_test.go:1116: Step 3/3 error: Check failed: Check 3/3 error: aws_rds_cluster.test: Attribute 'engine_version' expected "9.6.6", got "9.6.8" --- FAIL: TestAccAWSRDSCluster_GlobalClusterIdentifier_EngineMode_Global (133.32s) TestAccAWSRDSCluster_GlobalClusterIdentifier_EngineMode_Global: resource_aws_rds_cluster_test.go:1160: Step 1/2 error: After applying this test step, the plan was not empty. ... ~ engine_mode = "provisioned" -> "global" ~ engine_version = "5.6.mysql_aurora.1.22.2" -> (known after apply) --- FAIL: TestAccAWSRDSCluster_GlobalClusterIdentifier_EngineMode_Global_Add (142.29s) TestAccAWSRDSCluster_GlobalClusterIdentifier_EngineMode_Global_Add: resource_aws_rds_cluster_test.go:1194: Step 1/3 error: After applying this test step, the plan was not empty. ... ~ engine_mode = "provisioned" -> "global" ~ engine_version = "5.6.mysql_aurora.1.22.2" -> (known after apply) --- FAIL: TestAccAWSRDSCluster_GlobalClusterIdentifier_EngineMode_Global_Remove (124.34s) TestAccAWSRDSCluster_GlobalClusterIdentifier_EngineMode_Global_Remove: resource_aws_rds_cluster_test.go:1233: Step 1/3 error: After applying this test step, the plan was not empty. ... ~ engine_mode = "provisioned" -> "global" ~ engine_version = "5.6.mysql_aurora.1.22.2" -> (known after apply) --- FAIL: TestAccAWSRDSCluster_GlobalClusterIdentifier_EngineMode_Global_Update (164.15s) TestAccAWSRDSCluster_GlobalClusterIdentifier_EngineMode_Global_Update: resource_aws_rds_cluster_test.go:1276: Step 1/3 error: After applying this test step, the plan was not empty. ... ~ engine_mode = "provisioned" -> "global" ~ engine_version = "5.6.mysql_aurora.1.22.2" -> (known after apply) ``` Previously in AWS GovCloud (US): ``` --- FAIL: TestAccAWSRDSCluster_EngineVersionWithPrimaryInstance (4.74s) TestAccAWSRDSCluster_EngineVersionWithPrimaryInstance: resource_aws_rds_cluster_test.go:1116: Step 1/3 error: Error running apply: 2020/10/29 15:18:58 [DEBUG] Using modified User-Agent: Terraform/0.12.29 HashiCorp-terraform-exec/0.10.0 Error: error creating RDS cluster: InvalidParameterCombination: Cannot find version 9.6.3 for aurora-postgresql status code: 400, request id: 49b61f8c-3a33-4390-8fa8-cda26650b82b ``` Output from acceptance testing in AWS Commerical: ``` --- FAIL: TestAccAWSRDSCluster_s3Restore (26.99s) # https://github.com/terraform-providers/terraform-provider-aws/issues/13391 --- PASS: TestAccAWSRDSCluster_AllowMajorVersionUpgrade (1163.37s) --- PASS: TestAccAWSRDSCluster_AvailabilityZones (121.24s) --- PASS: TestAccAWSRDSCluster_BacktrackWindow (161.38s) --- PASS: TestAccAWSRDSCluster_backupsUpdate (217.31s) --- PASS: TestAccAWSRDSCluster_basic (184.11s) --- PASS: TestAccAWSRDSCluster_ClusterIdentifierPrefix (140.55s) --- PASS: TestAccAWSRDSCluster_copyTagsToSnapshot (251.25s) --- PASS: TestAccAWSRDSCluster_DbSubnetGroupName (188.87s) --- PASS: TestAccAWSRDSCluster_DeletionProtection (161.77s) --- PASS: TestAccAWSRDSCluster_EnabledCloudwatchLogsExports_MySQL (227.56s) --- PASS: TestAccAWSRDSCluster_EnabledCloudwatchLogsExports_Postgresql (146.68s) --- PASS: TestAccAWSRDSCluster_EnableHttpEndpoint (369.29s) --- PASS: TestAccAWSRDSCluster_encrypted (191.28s) --- PASS: TestAccAWSRDSCluster_EngineMode (467.55s) --- PASS: TestAccAWSRDSCluster_EngineMode_Global (153.36s) --- PASS: TestAccAWSRDSCluster_EngineMode_Multimaster (143.75s) --- PASS: TestAccAWSRDSCluster_EngineMode_ParallelQuery (172.28s) --- PASS: TestAccAWSRDSCluster_EngineVersion (445.21s) --- PASS: TestAccAWSRDSCluster_EngineVersionWithPrimaryInstance (1087.08s) --- PASS: TestAccAWSRDSCluster_generatedName (120.93s) --- PASS: TestAccAWSRDSCluster_GlobalClusterIdentifier_EngineMode_Global (170.73s) --- PASS: TestAccAWSRDSCluster_GlobalClusterIdentifier_EngineMode_Global_Add (170.70s) --- PASS: TestAccAWSRDSCluster_GlobalClusterIdentifier_EngineMode_Global_Remove (160.68s) --- PASS: TestAccAWSRDSCluster_GlobalClusterIdentifier_EngineMode_Global_Update (173.82s) --- PASS: TestAccAWSRDSCluster_GlobalClusterIdentifier_EngineMode_Provisioned (178.17s) --- PASS: TestAccAWSRDSCluster_GlobalClusterIdentifier_PrimarySecondaryClusters (1805.19s) --- PASS: TestAccAWSRDSCluster_GlobalClusterIdentifier_ReplicationSourceIdentifier (1864.34s) --- PASS: TestAccAWSRDSCluster_iamAuth (129.14s) --- PASS: TestAccAWSRDSCluster_kmsKey (188.31s) --- PASS: TestAccAWSRDSCluster_missingUserNameCausesError (9.80s) --- PASS: TestAccAWSRDSCluster_Port (339.07s) --- PASS: TestAccAWSRDSCluster_ReplicationSourceIdentifier_KmsKeyId (1537.43s) --- PASS: TestAccAWSRDSCluster_ScalingConfiguration (368.52s) --- PASS: TestAccAWSRDSCluster_ScalingConfiguration_DefaultMinCapacity (340.43s) --- PASS: TestAccAWSRDSCluster_SnapshotIdentifier (370.94s) --- PASS: TestAccAWSRDSCluster_SnapshotIdentifier_DeletionProtection (418.15s) --- PASS: TestAccAWSRDSCluster_SnapshotIdentifier_EncryptedRestore (363.14s) --- PASS: TestAccAWSRDSCluster_SnapshotIdentifier_EngineMode_ParallelQuery (419.92s) --- PASS: TestAccAWSRDSCluster_SnapshotIdentifier_EngineMode_Provisioned (358.63s) --- PASS: TestAccAWSRDSCluster_SnapshotIdentifier_EngineVersion_Different (403.08s) --- PASS: TestAccAWSRDSCluster_SnapshotIdentifier_EngineVersion_Equal (421.50s) --- PASS: TestAccAWSRDSCluster_SnapshotIdentifier_MasterPassword (372.04s) --- PASS: TestAccAWSRDSCluster_SnapshotIdentifier_MasterUsername (361.12s) --- PASS: TestAccAWSRDSCluster_SnapshotIdentifier_PreferredBackupWindow (379.74s) --- PASS: TestAccAWSRDSCluster_SnapshotIdentifier_PreferredMaintenanceWindow (360.90s) --- PASS: TestAccAWSRDSCluster_SnapshotIdentifier_Tags (464.57s) --- PASS: TestAccAWSRDSCluster_SnapshotIdentifier_VpcSecurityGroupIds (420.15s) --- PASS: TestAccAWSRDSCluster_SnapshotIdentifier_VpcSecurityGroupIds_Tags (440.36s) --- PASS: TestAccAWSRDSCluster_Tags (163.24s) --- PASS: TestAccAWSRDSCluster_takeFinalSnapshot (180.83s) --- PASS: TestAccAWSRDSCluster_updateIamRoles (223.14s) --- SKIP: TestAccAWSRDSCluster_SnapshotIdentifier_EngineMode_Serverless (0.00s) --- PASS: TestAccAWSRdsGlobalCluster_basic (17.74s) --- PASS: TestAccAWSRdsGlobalCluster_DatabaseName (30.67s) --- PASS: TestAccAWSRdsGlobalCluster_DeletionProtection (28.82s) --- PASS: TestAccAWSRdsGlobalCluster_disappears (14.06s) --- PASS: TestAccAWSRdsGlobalCluster_Engine_Aurora (16.50s) --- PASS: TestAccAWSRdsGlobalCluster_EngineVersion_Aurora (22.12s) --- PASS: TestAccAWSRdsGlobalCluster_EngineVersion_AuroraMySQL (21.94s) --- PASS: TestAccAWSRdsGlobalCluster_EngineVersion_AuroraPostgresql (22.01s) --- PASS: TestAccAWSRdsGlobalCluster_SourceDbClusterIdentifier (180.95s) --- PASS: TestAccAWSRdsGlobalCluster_SourceDbClusterIdentifier_StorageEncrypted (209.32s) --- PASS: TestAccAWSRdsGlobalCluster_StorageEncrypted (34.92s) ``` Output from acceptance testing in AWS GovCloud (US): ``` --- SKIP: TestAccAWSRDSCluster_EngineMode_Global (1.71s) --- PASS: TestAccAWSRDSCluster_EngineVersionWithPrimaryInstance (1073.20s) --- SKIP: TestAccAWSRDSCluster_GlobalClusterIdentifier_EngineMode_Global (1.66s) --- SKIP: TestAccAWSRDSCluster_GlobalClusterIdentifier_EngineMode_Global_Add (1.67s) --- SKIP: TestAccAWSRDSCluster_GlobalClusterIdentifier_EngineMode_Global_Remove (1.65s) --- SKIP: TestAccAWSRDSCluster_GlobalClusterIdentifier_EngineMode_Global_Update (1.65s) ``` --- aws/resource_aws_rds_cluster.go | 7 ++-- aws/resource_aws_rds_cluster_test.go | 46 ++++++++++++++++++-------- aws/resource_aws_rds_global_cluster.go | 9 ++++- 3 files changed, 45 insertions(+), 17 deletions(-) diff --git a/aws/resource_aws_rds_cluster.go b/aws/resource_aws_rds_cluster.go index 79845c07f2a..610f226197f 100644 --- a/aws/resource_aws_rds_cluster.go +++ b/aws/resource_aws_rds_cluster.go @@ -10,6 +10,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/rds" + "github.com/hashicorp/aws-sdk-go-base/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -1122,7 +1123,9 @@ func resourceAwsRDSClusterUpdate(d *schema.ResourceData, meta interface{}) error } log.Printf("[DEBUG] Removing RDS Cluster from RDS Global Cluster: %s", input) - if _, err := conn.RemoveFromGlobalCluster(input); err != nil { + _, err := conn.RemoveFromGlobalCluster(input) + + if err != nil && !tfawserr.ErrCodeEquals(err, rds.ErrCodeGlobalClusterNotFoundFault) && !tfawserr.ErrMessageContains(err, "InvalidParameterValue", "is not found in global cluster") { return fmt.Errorf("error removing RDS Cluster (%s) from RDS Global Cluster: %s", d.Id(), err) } } @@ -1182,7 +1185,7 @@ func resourceAwsRDSClusterDelete(d *schema.ResourceData, meta interface{}) error log.Printf("[DEBUG] Removing RDS Cluster from RDS Global Cluster: %s", input) _, err := conn.RemoveFromGlobalCluster(input) - if err != nil && !isAWSErr(err, rds.ErrCodeGlobalClusterNotFoundFault, "") { + if err != nil && !tfawserr.ErrCodeEquals(err, rds.ErrCodeGlobalClusterNotFoundFault) && !tfawserr.ErrMessageContains(err, "InvalidParameterValue", "is not found in global cluster") { return fmt.Errorf("error removing RDS Cluster (%s) from RDS Global Cluster: %s", d.Id(), err) } } diff --git a/aws/resource_aws_rds_cluster_test.go b/aws/resource_aws_rds_cluster_test.go index 8d7c4038b5b..41d0736bda2 100644 --- a/aws/resource_aws_rds_cluster_test.go +++ b/aws/resource_aws_rds_cluster_test.go @@ -980,7 +980,7 @@ func TestAccAWSRDSCluster_EngineMode_Global(t *testing.T) { CheckDestroy: testAccCheckAWSClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSRDSClusterConfig_EngineMode(rName, "global"), + Config: testAccAWSRDSClusterConfig_EngineMode_Global(rName), Check: resource.ComposeTestCheckFunc( testAccCheckAWSClusterExists(resourceName, &dbCluster1), resource.TestCheckResourceAttr(resourceName, "engine_mode", "global"), @@ -1119,11 +1119,11 @@ func TestAccAWSRDSCluster_EngineVersionWithPrimaryInstance(t *testing.T) { CheckDestroy: testAccCheckAWSClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSClusterConfig_EngineVersionWithPrimaryInstance(rInt, "aurora-postgresql", "9.6.3"), + Config: testAccAWSClusterConfig_EngineVersionWithPrimaryInstance(rInt, "aurora-postgresql", "9.6.17"), Check: resource.ComposeTestCheckFunc( testAccCheckAWSClusterExists(resourceName, &dbCluster), resource.TestCheckResourceAttr(resourceName, "engine", "aurora-postgresql"), - resource.TestCheckResourceAttr(resourceName, "engine_version", "9.6.3"), + resource.TestCheckResourceAttr(resourceName, "engine_version", "9.6.17"), ), }, { @@ -1139,11 +1139,11 @@ func TestAccAWSRDSCluster_EngineVersionWithPrimaryInstance(t *testing.T) { }, }, { - Config: testAccAWSClusterConfig_EngineVersionWithPrimaryInstance(rInt, "aurora-postgresql", "9.6.6"), + Config: testAccAWSClusterConfig_EngineVersionWithPrimaryInstance(rInt, "aurora-postgresql", "9.6.18"), Check: resource.ComposeTestCheckFunc( testAccCheckAWSClusterExists(resourceName, &dbCluster), resource.TestCheckResourceAttr(resourceName, "engine", "aurora-postgresql"), - resource.TestCheckResourceAttr(resourceName, "engine_version", "9.6.6"), + resource.TestCheckResourceAttr(resourceName, "engine_version", "9.6.18"), ), }, }, @@ -1197,7 +1197,7 @@ func TestAccAWSRDSCluster_GlobalClusterIdentifier_EngineMode_Global_Add(t *testi CheckDestroy: testAccCheckAWSClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSRDSClusterConfig_EngineMode(rName, "global"), + Config: testAccAWSRDSClusterConfig_EngineMode_Global(rName), Check: resource.ComposeTestCheckFunc( testAccCheckAWSClusterExists(resourceName, &dbCluster1), resource.TestCheckResourceAttr(resourceName, "global_cluster_identifier", ""), @@ -1255,7 +1255,7 @@ func TestAccAWSRDSCluster_GlobalClusterIdentifier_EngineMode_Global_Remove(t *te }, }, { - Config: testAccAWSRDSClusterConfig_EngineMode(rName, "global"), + Config: testAccAWSRDSClusterConfig_EngineMode_Global(rName), Check: resource.ComposeTestCheckFunc( testAccCheckAWSClusterExists(resourceName, &dbCluster1), resource.TestCheckResourceAttr(resourceName, "global_cluster_identifier", ""), @@ -3199,6 +3199,19 @@ resource "aws_rds_cluster" "test" { `, rName, engineMode) } +func testAccAWSRDSClusterConfig_EngineMode_Global(rName string) string { + return fmt.Sprintf(` +resource "aws_rds_cluster" "test" { + cluster_identifier = %[1]q + engine_mode = "global" + engine_version = "5.6.10a" # version compatible with engine_mode = "global" + master_password = "barbarbarbar" + master_username = "foo" + skip_final_snapshot = true +} +`, rName) +} + func testAccAWSRDSClusterConfig_EngineMode_Multimaster(rName string) string { return fmt.Sprintf(` data "aws_availability_zones" "available" { @@ -3258,18 +3271,21 @@ resource "aws_rds_cluster" "test" { func testAccAWSRDSClusterConfig_GlobalClusterIdentifier_EngineMode_Global(rName string) string { return fmt.Sprintf(` resource "aws_rds_global_cluster" "test" { - global_cluster_identifier = %q + engine_version = "5.6.10a" # version compatible with engine_mode = "global" + force_destroy = true # Partial configuration removal ordering fix for after Terraform 0.12 + global_cluster_identifier = %[1]q } resource "aws_rds_cluster" "test" { - cluster_identifier = %q + cluster_identifier = %[1]q global_cluster_identifier = aws_rds_global_cluster.test.id engine_mode = "global" + engine_version = aws_rds_global_cluster.test.engine_version master_password = "barbarbarbar" master_username = "foo" skip_final_snapshot = true } -`, rName, rName) +`, rName) } func testAccAWSRDSClusterConfig_GlobalClusterIdentifier_EngineMode_Global_Update(rName, globalClusterIdentifierResourceName string) string { @@ -3277,18 +3293,20 @@ func testAccAWSRDSClusterConfig_GlobalClusterIdentifier_EngineMode_Global_Update resource "aws_rds_global_cluster" "test" { count = 2 - global_cluster_identifier = "%s-${count.index}" + engine_version = "5.6.10a" # version compatible with engine_mode = "global" + global_cluster_identifier = "%[1]s-${count.index}" } resource "aws_rds_cluster" "test" { - cluster_identifier = %q - global_cluster_identifier = %s.id + cluster_identifier = %[1]q + global_cluster_identifier = %[2]s.id engine_mode = "global" + engine_version = %[2]s.engine_version master_password = "barbarbarbar" master_username = "foo" skip_final_snapshot = true } -`, rName, rName, globalClusterIdentifierResourceName) +`, rName, globalClusterIdentifierResourceName) } func testAccAWSRDSClusterConfig_GlobalClusterIdentifier_EngineMode_Provisioned(rName string) string { diff --git a/aws/resource_aws_rds_global_cluster.go b/aws/resource_aws_rds_global_cluster.go index fdbd9e45e0f..2a49ba95945 100644 --- a/aws/resource_aws_rds_global_cluster.go +++ b/aws/resource_aws_rds_global_cluster.go @@ -7,6 +7,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/rds" + "github.com/hashicorp/aws-sdk-go-base/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -250,7 +251,13 @@ func resourceAwsRDSGlobalClusterDelete(d *schema.ResourceData, meta interface{}) GlobalClusterIdentifier: aws.String(d.Id()), } - if _, err := conn.RemoveFromGlobalCluster(input); err != nil { + _, err := conn.RemoveFromGlobalCluster(input) + + if tfawserr.ErrMessageContains(err, "InvalidParameterValue", "is not found in global cluster") { + continue + } + + if err != nil { return fmt.Errorf("error removing RDS DB Cluster (%s) from Global Cluster (%s): %w", dbClusterArn, d.Id(), err) }