From d90aa040999edbce593d40359521304239122811 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Thu, 23 Aug 2018 18:18:16 -0400 Subject: [PATCH] resource/aws_db_instance: Prevent double apply with replicate_source_db, prevent pending-reboot on creation with parameter_group_name * Add ModifyDBInstance call to CreateDBInstanceReadReplica if necessary * Add RebootDBInstance call after ModifyDBInstance if necessary * Refactor to not call update function during create function * Additional acceptance testing with snapshot_identifier with allocated_storage, availability_zone, auto_minor_version_upgrade, and port Previously: ``` --- FAIL: TestAccAWSDBInstance_SnapshotIdentifier_AllocatedStorage (1160.55s) testing.go:527: Step 0 error: Check failed: Check 4/4 error: aws_db_instance.test: Attribute 'allocated_storage' expected "10", got "5" --- FAIL: TestAccAWSDBInstance_ReplicateSourceDb_AllocatedStorage (1433.85s) testing.go:527: Step 0 error: Check failed: Check 4/4 error: aws_db_instance.test: Attribute 'allocated_storage' expected "10", got "5" --- FAIL: TestAccAWSDBInstance_ReplicateSourceDb_AutoMinorVersionUpgrade (1707.73s) testing.go:527: Step 0 error: Check failed: Check 4/4 error: aws_db_instance.test: Attribute 'auto_minor_version_upgrade' expected "false", got "true" --- FAIL: TestAccAWSDBInstance_ReplicateSourceDb_BackupRetentionPeriod (1336.28s) testing.go:527: Step 0 error: Check failed: Check 4/4 error: aws_db_instance.test: Attribute 'backup_retention_period' expected "1", got "0" --- FAIL: TestAccAWSDBInstance_ReplicateSourceDb_BackupWindow (1451.16s) testing.go:527: Step 0 error: Check failed: Check 4/4 error: aws_db_instance.test: Attribute 'backup_window' expected "00:00-08:00", got "08:31-09:01" --- FAIL: TestAccAWSDBInstance_ReplicateSourceDb_IamDatabaseAuthenticationEnabled (1525.07s) testing.go:527: Step 0 error: Check failed: Check 4/4 error: aws_db_instance.test: Attribute 'iam_database_authentication_enabled' expected "true", got "false" --- FAIL: TestAccAWSDBInstance_ReplicateSourceDb_MaintenanceWindow (1695.94s) testing.go:527: Step 0 error: Check failed: Check 4/4 error: aws_db_instance.test: Attribute 'maintenance_window' expected "sun:01:00-sun:01:30", got "sat:07:22-sat:07:52" --- FAIL: TestAccAWSDBInstance_ReplicateSourceDb_MultiAZ (1802.71s) testing.go:527: Step 0 error: Check failed: Check 4/4 error: aws_db_instance.test: Attribute 'multi_az' expected "true", got "false" --- FAIL: TestAccAWSDBInstance_ReplicateSourceDb_ParameterGroupName (1624.64s) testing.go:527: Step 0 error: Check failed: Check 4/4 error: aws_db_instance.test: Attribute 'parameter_group_name' expected "tf-acc-test-2677194822897355379", got "default.mysql5.7" --- FAIL: TestAccAWSDBInstance_ReplicateSourceDb_VpcSecurityGroupIds (1479.95s) testing.go:527: Step 0 error: After applying this step, the plan was not empty: DIFF: UPDATE: aws_db_instance.test vpc_security_group_ids.1493394302: "" => "sg-0202c4194da544ffb" vpc_security_group_ids.81746784: "sg-1ca59078" => "" ``` Before RebootDBInstance addition: ``` --- FAIL: TestAccAWSDBInstance_SnapshotIdentifier_ParameterGroupName (1256.87s) testing.go:527: Step 0 error: Check failed: Check 5/5 error: expected DB Instance (tf-acc-test-8132994030462245505) Parameter Group (tf-acc-test-8132994030462245505) apply status to be: "in-sync", got: "pending-reboot" --- FAIL: TestAccAWSDBInstance_ReplicateSourceDb_ParameterGroupName (1761.14s) testing.go:527: Step 0 error: Check failed: Check 5/5 error: expected DB Instance (tf-acc-test-632112102194298217) Parameter Group (tf-acc-test-632112102194298217) apply status to be: "in-sync", got: "pending-reboot" ``` --- aws/resource_aws_db_instance.go | 258 ++-- aws/resource_aws_db_instance_test.go | 1663 +++++++++++++++++++------- 2 files changed, 1417 insertions(+), 504 deletions(-) diff --git a/aws/resource_aws_db_instance.go b/aws/resource_aws_db_instance.go index d6ab5efc923..8e44d8703c3 100644 --- a/aws/resource_aws_db_instance.go +++ b/aws/resource_aws_db_instance.go @@ -414,6 +414,23 @@ func resourceAwsDbInstance() *schema.Resource { func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).rdsconn + + // Some API calls (e.g. CreateDBInstanceReadReplica and + // RestoreDBInstanceFromDBSnapshot do not support all parameters to + // correctly apply all settings in one pass. For missing parameters or + // unsupported configurations, we may need to call ModifyDBInstance + // afterwards to prevent Terraform operators from API errors or needing + // to double apply. + var requiresModifyDbInstance bool + modifyDbInstanceInput := &rds.ModifyDBInstanceInput{ + ApplyImmediately: aws.Bool(true), + } + + // Some ModifyDBInstance parameters (e.g. DBParameterGroupName) require + // a database instance reboot to take affect. During resource creation, + // we expect everything to be in sync before returning completion. + var requiresRebootDbInstance bool + tags := tagsFromMapRDS(d.Get("tags").(map[string]interface{})) var identifier string @@ -437,27 +454,32 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error if v, ok := d.GetOk("replicate_source_db"); ok { opts := rds.CreateDBInstanceReadReplicaInput{ - SourceDBInstanceIdentifier: aws.String(v.(string)), + AutoMinorVersionUpgrade: aws.Bool(d.Get("auto_minor_version_upgrade").(bool)), CopyTagsToSnapshot: aws.Bool(d.Get("copy_tags_to_snapshot").(bool)), DBInstanceClass: aws.String(d.Get("instance_class").(string)), DBInstanceIdentifier: aws.String(identifier), PubliclyAccessible: aws.Bool(d.Get("publicly_accessible").(bool)), - Tags: tags, - } - if attr, ok := d.GetOk("iops"); ok { - opts.Iops = aws.Int64(int64(attr.(int))) + SourceDBInstanceIdentifier: aws.String(v.(string)), + Tags: tags, } - if attr, ok := d.GetOk("port"); ok { - opts.Port = aws.Int64(int64(attr.(int))) + if attr, ok := d.GetOk("allocated_storage"); ok { + modifyDbInstanceInput.AllocatedStorage = aws.Int64(int64(attr.(int))) + requiresModifyDbInstance = true } if attr, ok := d.GetOk("availability_zone"); ok { opts.AvailabilityZone = aws.String(attr.(string)) } - if attr, ok := d.GetOk("storage_type"); ok { - opts.StorageType = aws.String(attr.(string)) + if attr, ok := d.GetOk("backup_retention_period"); ok { + modifyDbInstanceInput.BackupRetentionPeriod = aws.Int64(int64(attr.(int))) + requiresModifyDbInstance = true + } + + if attr, ok := d.GetOk("backup_window"); ok { + modifyDbInstanceInput.PreferredBackupWindow = aws.String(attr.(string)) + requiresModifyDbInstance = true } if attr, ok := d.GetOk("db_subnet_group_name"); ok { @@ -468,6 +490,14 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error opts.EnableCloudwatchLogsExports = expandStringList(attr.([]interface{})) } + if attr, ok := d.GetOk("iam_database_authentication_enabled"); ok { + opts.EnableIAMDatabaseAuthentication = aws.Bool(attr.(bool)) + } + + if attr, ok := d.GetOk("iops"); ok { + opts.Iops = aws.Int64(int64(attr.(int))) + } + if attr, ok := d.GetOk("kms_key_id"); ok { opts.KmsKeyId = aws.String(attr.(string)) if arnParts := strings.Split(v.(string), ":"); len(arnParts) >= 4 { @@ -475,18 +505,56 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error } } - if attr, ok := d.GetOk("monitoring_role_arn"); ok { - opts.MonitoringRoleArn = aws.String(attr.(string)) + if attr, ok := d.GetOk("maintenance_window"); ok { + modifyDbInstanceInput.PreferredMaintenanceWindow = aws.String(attr.(string)) + requiresModifyDbInstance = true } if attr, ok := d.GetOk("monitoring_interval"); ok { opts.MonitoringInterval = aws.Int64(int64(attr.(int))) } + if attr, ok := d.GetOk("monitoring_role_arn"); ok { + opts.MonitoringRoleArn = aws.String(attr.(string)) + } + + if attr, ok := d.GetOk("multi_az"); ok { + opts.MultiAZ = aws.Bool(attr.(bool)) + } + if attr, ok := d.GetOk("option_group_name"); ok { opts.OptionGroupName = aws.String(attr.(string)) } + if attr, ok := d.GetOk("parameter_group_name"); ok { + modifyDbInstanceInput.DBParameterGroupName = aws.String(attr.(string)) + requiresModifyDbInstance = true + requiresRebootDbInstance = true + } + + if attr, ok := d.GetOk("password"); ok { + modifyDbInstanceInput.MasterUserPassword = aws.String(attr.(string)) + requiresModifyDbInstance = true + } + + if attr, ok := d.GetOk("port"); ok { + opts.Port = aws.Int64(int64(attr.(int))) + } + + if attr := d.Get("security_group_names").(*schema.Set); attr.Len() > 0 { + modifyDbInstanceInput.DBSecurityGroups = expandStringSet(attr) + requiresModifyDbInstance = true + } + + if attr, ok := d.GetOk("storage_type"); ok { + opts.StorageType = aws.String(attr.(string)) + } + + if attr := d.Get("vpc_security_group_ids").(*schema.Set); attr.Len() > 0 { + modifyDbInstanceInput.VpcSecurityGroupIds = expandStringSet(attr) + requiresModifyDbInstance = true + } + log.Printf("[DEBUG] DB Instance Replica create configuration: %#v", opts) _, err := conn.CreateDBInstanceReadReplica(&opts) if err != nil { @@ -665,12 +733,6 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error return resourceAwsDbInstanceRead(d, meta) } else if _, ok := d.GetOk("snapshot_identifier"); ok { - // RestoreDBInstanceFromDBSnapshot does not support all parameters - // correctly apply in one pass. For missing parameters or unsupported - // configurations, we need to call ModifyDBInstance afterwards to - // prevent Terraform operators from API errors or double apply. - var requiresModifyDbInstance bool - opts := rds.RestoreDBInstanceFromDBSnapshotInput{ AutoMinorVersionUpgrade: aws.Bool(d.Get("auto_minor_version_upgrade").(bool)), CopyTagsToSnapshot: aws.Bool(d.Get("copy_tags_to_snapshot").(bool)), @@ -692,15 +754,22 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error } } + if attr, ok := d.GetOk("allocated_storage"); ok { + modifyDbInstanceInput.AllocatedStorage = aws.Int64(int64(attr.(int))) + requiresModifyDbInstance = true + } + if attr, ok := d.GetOk("availability_zone"); ok { opts.AvailabilityZone = aws.String(attr.(string)) } - if _, ok := d.GetOk("backup_retention_period"); ok { + if attr, ok := d.GetOk("backup_retention_period"); ok { + modifyDbInstanceInput.BackupRetentionPeriod = aws.Int64(int64(attr.(int))) requiresModifyDbInstance = true } - if _, ok := d.GetOk("backup_window"); ok { + if attr, ok := d.GetOk("backup_window"); ok { + modifyDbInstanceInput.PreferredBackupWindow = aws.String(attr.(string)) requiresModifyDbInstance = true } @@ -716,8 +785,8 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error opts.Engine = aws.String(attr.(string)) } - if _, ok := d.GetOk("iam_database_authentication_enabled"); ok { - requiresModifyDbInstance = true + if attr, ok := d.GetOk("iam_database_authentication_enabled"); ok { + opts.EnableIAMDatabaseAuthentication = aws.Bool(attr.(bool)) } if attr, ok := d.GetOk("iops"); ok { @@ -728,15 +797,18 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error opts.LicenseModel = aws.String(attr.(string)) } - if _, ok := d.GetOk("maintenance_window"); ok { + if attr, ok := d.GetOk("maintenance_window"); ok { + modifyDbInstanceInput.PreferredMaintenanceWindow = aws.String(attr.(string)) requiresModifyDbInstance = true } - if _, ok := d.GetOk("monitoring_interval"); ok { + if attr, ok := d.GetOk("monitoring_interval"); ok { + modifyDbInstanceInput.MonitoringInterval = aws.Int64(int64(attr.(int))) requiresModifyDbInstance = true } - if _, ok := d.GetOk("monitoring_role_arn"); ok { + if attr, ok := d.GetOk("monitoring_role_arn"); ok { + modifyDbInstanceInput.MonitoringRoleArn = aws.String(attr.(string)) requiresModifyDbInstance = true } @@ -748,6 +820,7 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error // InvalidParameterValue: Mirroring cannot be applied to instances with backup retention set to zero. // If we know the engine, prevent the error upfront. if v, ok := d.GetOk("engine"); ok && strings.HasPrefix(strings.ToLower(v.(string)), "sqlserver") { + modifyDbInstanceInput.MultiAZ = aws.Bool(attr.(bool)) requiresModifyDbInstance = true } else { opts.MultiAZ = aws.Bool(attr.(bool)) @@ -758,11 +831,14 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error opts.OptionGroupName = aws.String(attr.(string)) } - if _, ok := d.GetOk("parameter_group_name"); ok { + if attr, ok := d.GetOk("parameter_group_name"); ok { + modifyDbInstanceInput.DBParameterGroupName = aws.String(attr.(string)) requiresModifyDbInstance = true + requiresRebootDbInstance = true } - if _, ok := d.GetOk("password"); ok { + if attr, ok := d.GetOk("password"); ok { + modifyDbInstanceInput.MasterUserPassword = aws.String(attr.(string)) requiresModifyDbInstance = true } @@ -771,6 +847,7 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error } if attr := d.Get("security_group_names").(*schema.Set); attr.Len() > 0 { + modifyDbInstanceInput.DBSecurityGroups = expandStringSet(attr) requiresModifyDbInstance = true } @@ -783,6 +860,7 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error } if attr := d.Get("vpc_security_group_ids").(*schema.Set); attr.Len() > 0 { + modifyDbInstanceInput.VpcSecurityGroupIds = expandStringSet(attr) requiresModifyDbInstance = true } @@ -799,6 +877,7 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error // and remove the invalid configuration for it to be fixed afterwards. if isAWSErr(err, "InvalidParameterValue", "Mirroring cannot be applied to instances with backup retention set to zero") { opts.MultiAZ = aws.Bool(false) + modifyDbInstanceInput.MultiAZ = aws.Bool(true) requiresModifyDbInstance = true _, err = conn.RestoreDBInstanceFromDBSnapshot(&opts) } @@ -806,34 +885,6 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error if err != nil { return fmt.Errorf("Error creating DB Instance: %s", err) } - - if requiresModifyDbInstance { - d.SetId(d.Get("identifier").(string)) - - log.Printf("[INFO] DB Instance %q configuration requires ModifyDBInstance after RestoreDBInstanceFromDBSnapshot", d.Id()) - log.Printf("[INFO] Waiting for DB Instance %q to be available", d.Id()) - - stateConf := &resource.StateChangeConf{ - Pending: resourceAwsDbInstanceCreatePendingStates, - Target: []string{"available", "storage-optimization"}, - Refresh: resourceAwsDbInstanceStateRefreshFunc(d.Id(), conn), - Timeout: d.Timeout(schema.TimeoutCreate), - MinTimeout: 10 * time.Second, - Delay: 30 * time.Second, // Wait 30 secs before starting - } - - // Wait, catching any errors - _, err := stateConf.WaitForState() - if err != nil { - return err - } - - err = resourceAwsDbInstanceUpdate(d, meta) - if err != nil { - return err - } - - } } else { if _, ok := d.GetOk("allocated_storage"); !ok { return fmt.Errorf(`provider.aws: aws_db_instance: %s: "allocated_storage": required field is not set`, d.Get("name").(string)) @@ -975,11 +1026,6 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error d.SetId(d.Get("identifier").(string)) - log.Printf("[INFO] DB Instance ID: %s", d.Id()) - - log.Println( - "[INFO] Waiting for DB Instance to be available") - stateConf := &resource.StateChangeConf{ Pending: resourceAwsDbInstanceCreatePendingStates, Target: []string{"available", "storage-optimization"}, @@ -989,12 +1035,46 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error Delay: 30 * time.Second, // Wait 30 secs before starting } - // Wait, catching any errors + log.Printf("[INFO] Waiting for DB Instance (%s) to be available", d.Id()) _, err := stateConf.WaitForState() if err != nil { return err } + if requiresModifyDbInstance { + modifyDbInstanceInput.DBInstanceIdentifier = aws.String(d.Id()) + + log.Printf("[INFO] DB Instance (%s) configuration requires ModifyDBInstance: %s", d.Id(), modifyDbInstanceInput) + _, err := conn.ModifyDBInstance(modifyDbInstanceInput) + if err != nil { + return fmt.Errorf("error modifying DB Instance (%s): %s", d.Id(), err) + } + + log.Printf("[INFO] Waiting for DB Instance (%s) to be available", d.Id()) + err = waitUntilAwsDbInstanceIsAvailableAfterUpdate(d.Id(), conn, d.Timeout(schema.TimeoutUpdate)) + if err != nil { + return fmt.Errorf("error waiting for DB Instance (%s) to be available: %s", d.Id(), err) + } + } + + if requiresRebootDbInstance { + rebootDbInstanceInput := &rds.RebootDBInstanceInput{ + DBInstanceIdentifier: aws.String(d.Id()), + } + + log.Printf("[INFO] DB Instance (%s) configuration requires RebootDBInstance: %s", d.Id(), rebootDbInstanceInput) + _, err := conn.RebootDBInstance(rebootDbInstanceInput) + if err != nil { + return fmt.Errorf("error rebooting DB Instance (%s): %s", d.Id(), err) + } + + log.Printf("[INFO] Waiting for DB Instance (%s) to be available", d.Id()) + err = waitUntilAwsDbInstanceIsAvailableAfterUpdate(d.Id(), conn, d.Timeout(schema.TimeoutUpdate)) + if err != nil { + return fmt.Errorf("error waiting for DB Instance (%s) to be available: %s", d.Id(), err) + } + } + return resourceAwsDbInstanceRead(d, meta) } @@ -1157,6 +1237,19 @@ func resourceAwsDbInstanceDelete(d *schema.ResourceData, meta interface{}) error return waitUntilAwsDbInstanceIsDeleted(d.Id(), conn, d.Timeout(schema.TimeoutDelete)) } +func waitUntilAwsDbInstanceIsAvailableAfterUpdate(id string, conn *rds.RDS, timeout time.Duration) error { + stateConf := &resource.StateChangeConf{ + Pending: resourceAwsDbInstanceUpdatePendingStates, + Target: []string{"available", "storage-optimization"}, + Refresh: resourceAwsDbInstanceStateRefreshFunc(id, conn), + Timeout: timeout, + MinTimeout: 10 * time.Second, + Delay: 30 * time.Second, // Wait 30 secs before starting + } + _, err := stateConf.WaitForState() + return err +} + func waitUntilAwsDbInstanceIsDeleted(id string, conn *rds.RDS, timeout time.Duration) error { stateConf := &resource.StateChangeConf{ Pending: resourceAwsDbInstanceDeletePendingStates, @@ -1180,13 +1273,6 @@ func resourceAwsDbInstanceUpdate(d *schema.ResourceData, meta interface{}) error DBInstanceIdentifier: aws.String(d.Id()), } - // ModifyDBInstance might be called during resource creation - // to fix unsupported configurations, e.g. missing parameters - // from RestoreDBInstanceFromDBSnapshot. In this case, we should - // always apply immediately. - if d.IsNewResource() { - req.ApplyImmediately = aws.Bool(true) - } d.SetPartial("apply_immediately") if !aws.BoolValue(req.ApplyImmediately) { @@ -1286,22 +1372,14 @@ func resourceAwsDbInstanceUpdate(d *schema.ResourceData, meta interface{}) error if d.HasChange("vpc_security_group_ids") { if attr := d.Get("vpc_security_group_ids").(*schema.Set); attr.Len() > 0 { - var s []*string - for _, v := range attr.List() { - s = append(s, aws.String(v.(string))) - } - req.VpcSecurityGroupIds = s + req.VpcSecurityGroupIds = expandStringSet(attr) } requestUpdate = true } if d.HasChange("security_group_names") { if attr := d.Get("security_group_names").(*schema.Set); attr.Len() > 0 { - var s []*string - for _, v := range attr.List() { - s = append(s, aws.String(v.(string))) - } - req.DBSecurityGroups = s + req.DBSecurityGroups = expandStringSet(attr) } requestUpdate = true } @@ -1317,13 +1395,13 @@ func resourceAwsDbInstanceUpdate(d *schema.ResourceData, meta interface{}) error req.DBPortNumber = aws.Int64(int64(d.Get("port").(int))) requestUpdate = true } - if d.HasChange("db_subnet_group_name") && !d.IsNewResource() { + if d.HasChange("db_subnet_group_name") { d.SetPartial("db_subnet_group_name") req.DBSubnetGroupName = aws.String(d.Get("db_subnet_group_name").(string)) requestUpdate = true } - if d.HasChange("enabled_cloudwatch_logs_exports") && !d.IsNewResource() { + if d.HasChange("enabled_cloudwatch_logs_exports") { d.SetPartial("enabled_cloudwatch_logs_exports") req.CloudwatchLogsExportConfiguration = buildCloudwatchLogsExportConfiguration(d) requestUpdate = true @@ -1342,21 +1420,10 @@ func resourceAwsDbInstanceUpdate(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("Error modifying DB Instance %s: %s", d.Id(), err) } - log.Println("[INFO] Waiting for DB Instance to be available") - - stateConf := &resource.StateChangeConf{ - Pending: resourceAwsDbInstanceUpdatePendingStates, - Target: []string{"available", "storage-optimization"}, - Refresh: resourceAwsDbInstanceStateRefreshFunc(d.Id(), conn), - Timeout: d.Timeout(schema.TimeoutUpdate), - MinTimeout: 10 * time.Second, - Delay: 30 * time.Second, // Wait 30 secs before starting - } - - // Wait, catching any errors - _, dbStateErr := stateConf.WaitForState() - if dbStateErr != nil { - return dbStateErr + log.Printf("[DEBUG] Waiting for DB Instance (%s) to be available", d.Id()) + err = waitUntilAwsDbInstanceIsAvailableAfterUpdate(d.Id(), conn, d.Timeout(schema.TimeoutUpdate)) + if err != nil { + return fmt.Errorf("error waiting for DB Instance (%s) to be available: %s", d.Id(), err) } } @@ -1382,8 +1449,7 @@ func resourceAwsDbInstanceUpdate(d *schema.ResourceData, meta interface{}) error } } - // Tags are set on creation - if !d.IsNewResource() && d.HasChange("tags") { + if d.HasChange("tags") { if err := setTagsRDS(conn, d, d.Get("arn").(string)); err != nil { return err } else { diff --git a/aws/resource_aws_db_instance_test.go b/aws/resource_aws_db_instance_test.go index a23d198526e..7e2f8cbba8d 100644 --- a/aws/resource_aws_db_instance_test.go +++ b/aws/resource_aws_db_instance_test.go @@ -259,6 +259,45 @@ func TestAccAWSDBInstance_iamAuth(t *testing.T) { }) } +func TestAccAWSDBInstance_FinalSnapshotIdentifier(t *testing.T) { + var snap rds.DBInstance + rInt := acctest.RandInt() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + // testAccCheckAWSDBInstanceSnapshot verifies a database snapshot is + // created, and subequently deletes it + CheckDestroy: testAccCheckAWSDBInstanceSnapshot, + Steps: []resource.TestStep{ + { + Config: testAccAWSDBInstanceConfig_FinalSnapshotIdentifier(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSDBInstanceExists("aws_db_instance.snapshot", &snap), + ), + }, + }, + }) +} + +func TestAccAWSDBInstance_FinalSnapshotIdentifier_SkipFinalSnapshot(t *testing.T) { + var snap rds.DBInstance + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSDBInstanceNoSnapshot, + Steps: []resource.TestStep{ + { + Config: testAccAWSDBInstanceConfig_FinalSnapshotIdentifier_SkipFinalSnapshot(), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSDBInstanceExists("aws_db_instance.snapshot", &snap), + ), + }, + }, + }) +} + func TestAccAWSDBInstance_IsAlreadyBeingDeleted(t *testing.T) { var dbInstance rds.DBInstance @@ -296,8 +335,12 @@ func TestAccAWSDBInstance_IsAlreadyBeingDeleted(t *testing.T) { }) } -func TestAccAWSDBInstance_replica(t *testing.T) { - var s, r rds.DBInstance +func TestAccAWSDBInstance_ReplicateSourceDb(t *testing.T) { + var dbInstance, sourceDbInstance rds.DBInstance + + rName := acctest.RandomWithPrefix("tf-acc-test") + sourceResourceName := "aws_db_instance.source" + resourceName := "aws_db_instance.test" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -305,61 +348,73 @@ func TestAccAWSDBInstance_replica(t *testing.T) { CheckDestroy: testAccCheckAWSDBInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccReplicaInstanceConfig(acctest.RandInt()), + Config: testAccAWSDBInstanceConfig_ReplicateSourceDb(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &s), - testAccCheckAWSDBInstanceExists("aws_db_instance.replica", &r), - testAccCheckAWSDBInstanceReplicaAttributes(&s, &r), + testAccCheckAWSDBInstanceExists(sourceResourceName, &sourceDbInstance), + testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), + testAccCheckAWSDBInstanceReplicaAttributes(&sourceDbInstance, &dbInstance), ), }, }, }) } -func TestAccAWSDBInstance_noSnapshot(t *testing.T) { - var snap rds.DBInstance +func TestAccAWSDBInstance_ReplicateSourceDb_AllocatedStorage(t *testing.T) { + var dbInstance, sourceDbInstance rds.DBInstance + + rName := acctest.RandomWithPrefix("tf-acc-test") + sourceResourceName := "aws_db_instance.source" + resourceName := "aws_db_instance.test" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testAccCheckAWSDBInstanceNoSnapshot, + CheckDestroy: testAccCheckAWSDBInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSDBInstanceConfig_FinalSnapshotIdentifier_SkipFinalSnapshot(), + Config: testAccAWSDBInstanceConfig_ReplicateSourceDb_AllocatedStorage(rName, 10), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists("aws_db_instance.snapshot", &snap), + testAccCheckAWSDBInstanceExists(sourceResourceName, &sourceDbInstance), + testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), + testAccCheckAWSDBInstanceReplicaAttributes(&sourceDbInstance, &dbInstance), + resource.TestCheckResourceAttr(resourceName, "allocated_storage", "10"), ), }, }, }) } -func TestAccAWSDBInstance_snapshot(t *testing.T) { - var snap rds.DBInstance - rInt := acctest.RandInt() +func TestAccAWSDBInstance_ReplicateSourceDb_AutoMinorVersionUpgrade(t *testing.T) { + var dbInstance, sourceDbInstance rds.DBInstance + + rName := acctest.RandomWithPrefix("tf-acc-test") + sourceResourceName := "aws_db_instance.source" + resourceName := "aws_db_instance.test" resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - // testAccCheckAWSDBInstanceSnapshot verifies a database snapshot is - // created, and subequently deletes it - CheckDestroy: testAccCheckAWSDBInstanceSnapshot, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSDBInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccSnapshotInstanceConfigWithSnapshot(rInt), + Config: testAccAWSDBInstanceConfig_ReplicateSourceDb_AutoMinorVersionUpgrade(rName, false), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists("aws_db_instance.snapshot", &snap), + testAccCheckAWSDBInstanceExists(sourceResourceName, &sourceDbInstance), + testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), + testAccCheckAWSDBInstanceReplicaAttributes(&sourceDbInstance, &dbInstance), + resource.TestCheckResourceAttr(resourceName, "auto_minor_version_upgrade", "false"), ), }, }, }) } -func TestAccAWSDBInstance_s3(t *testing.T) { - var snap rds.DBInstance - bucket := acctest.RandomWithPrefix("tf-acc-test") - uniqueId := acctest.RandomWithPrefix("tf-acc-s3-import-test") - bucketPrefix := acctest.RandString(5) +func TestAccAWSDBInstance_ReplicateSourceDb_AvailabilityZone(t *testing.T) { + var dbInstance, sourceDbInstance rds.DBInstance + + rName := acctest.RandomWithPrefix("tf-acc-test") + sourceResourceName := "aws_db_instance.source" + resourceName := "aws_db_instance.test" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -367,22 +422,22 @@ func TestAccAWSDBInstance_s3(t *testing.T) { CheckDestroy: testAccCheckAWSDBInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccSnapshotInstanceConfigWithS3Import(bucket, bucketPrefix, uniqueId), + Config: testAccAWSDBInstanceConfig_ReplicateSourceDb_AvailabilityZone(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists("aws_db_instance.s3", &snap), + testAccCheckAWSDBInstanceExists(sourceResourceName, &sourceDbInstance), + testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), + testAccCheckAWSDBInstanceReplicaAttributes(&sourceDbInstance, &dbInstance), ), }, }, }) } -func TestAccAWSDBInstance_SnapshotIdentifier(t *testing.T) { +func TestAccAWSDBInstance_ReplicateSourceDb_BackupRetentionPeriod(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance - var dbSnapshot rds.DBSnapshot rName := acctest.RandomWithPrefix("tf-acc-test") - sourceDbResourceName := "aws_db_instance.source" - snapshotResourceName := "aws_db_snapshot.test" + sourceResourceName := "aws_db_instance.source" resourceName := "aws_db_instance.test" resource.Test(t, resource.TestCase{ @@ -391,24 +446,23 @@ func TestAccAWSDBInstance_SnapshotIdentifier(t *testing.T) { CheckDestroy: testAccCheckAWSDBInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSDBInstanceConfig_SnapshotIdentifier(rName), + Config: testAccAWSDBInstanceConfig_ReplicateSourceDb_BackupRetentionPeriod(rName, 1), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists(sourceDbResourceName, &sourceDbInstance), - testAccCheckDbSnapshotExists(snapshotResourceName, &dbSnapshot), + testAccCheckAWSDBInstanceExists(sourceResourceName, &sourceDbInstance), testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), + testAccCheckAWSDBInstanceReplicaAttributes(&sourceDbInstance, &dbInstance), + resource.TestCheckResourceAttr(resourceName, "backup_retention_period", "1"), ), }, }, }) } -func TestAccAWSDBInstance_SnapshotIdentifier_BackupRetentionPeriod(t *testing.T) { +func TestAccAWSDBInstance_ReplicateSourceDb_BackupWindow(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance - var dbSnapshot rds.DBSnapshot rName := acctest.RandomWithPrefix("tf-acc-test") - sourceDbResourceName := "aws_db_instance.source" - snapshotResourceName := "aws_db_snapshot.test" + sourceResourceName := "aws_db_instance.source" resourceName := "aws_db_instance.test" resource.Test(t, resource.TestCase{ @@ -417,25 +471,23 @@ func TestAccAWSDBInstance_SnapshotIdentifier_BackupRetentionPeriod(t *testing.T) CheckDestroy: testAccCheckAWSDBInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSDBInstanceConfig_SnapshotIdentifier_BackupRetentionPeriod(rName, 1), + Config: testAccAWSDBInstanceConfig_ReplicateSourceDb_BackupWindow(rName, "00:00-08:00"), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists(sourceDbResourceName, &sourceDbInstance), - testAccCheckDbSnapshotExists(snapshotResourceName, &dbSnapshot), + testAccCheckAWSDBInstanceExists(sourceResourceName, &sourceDbInstance), testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), - resource.TestCheckResourceAttr(resourceName, "backup_retention_period", "1"), + testAccCheckAWSDBInstanceReplicaAttributes(&sourceDbInstance, &dbInstance), + resource.TestCheckResourceAttr(resourceName, "backup_window", "00:00-08:00"), ), }, }, }) } -func TestAccAWSDBInstance_SnapshotIdentifier_BackupWindow(t *testing.T) { +func TestAccAWSDBInstance_ReplicateSourceDb_IamDatabaseAuthenticationEnabled(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance - var dbSnapshot rds.DBSnapshot rName := acctest.RandomWithPrefix("tf-acc-test") - sourceDbResourceName := "aws_db_instance.source" - snapshotResourceName := "aws_db_snapshot.test" + sourceResourceName := "aws_db_instance.source" resourceName := "aws_db_instance.test" resource.Test(t, resource.TestCase{ @@ -444,25 +496,23 @@ func TestAccAWSDBInstance_SnapshotIdentifier_BackupWindow(t *testing.T) { CheckDestroy: testAccCheckAWSDBInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSDBInstanceConfig_SnapshotIdentifier_BackupWindow(rName, "00:00-08:00"), + Config: testAccAWSDBInstanceConfig_ReplicateSourceDb_IamDatabaseAuthenticationEnabled(rName, true), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists(sourceDbResourceName, &sourceDbInstance), - testAccCheckDbSnapshotExists(snapshotResourceName, &dbSnapshot), + testAccCheckAWSDBInstanceExists(sourceResourceName, &sourceDbInstance), testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), - resource.TestCheckResourceAttr(resourceName, "backup_window", "00:00-08:00"), + testAccCheckAWSDBInstanceReplicaAttributes(&sourceDbInstance, &dbInstance), + resource.TestCheckResourceAttr(resourceName, "iam_database_authentication_enabled", "true"), ), }, }, }) } -func TestAccAWSDBInstance_SnapshotIdentifier_IamDatabaseAuthenticationEnabled(t *testing.T) { +func TestAccAWSDBInstance_ReplicateSourceDb_MaintenanceWindow(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance - var dbSnapshot rds.DBSnapshot rName := acctest.RandomWithPrefix("tf-acc-test") - sourceDbResourceName := "aws_db_instance.source" - snapshotResourceName := "aws_db_snapshot.test" + sourceResourceName := "aws_db_instance.source" resourceName := "aws_db_instance.test" resource.Test(t, resource.TestCase{ @@ -471,25 +521,23 @@ func TestAccAWSDBInstance_SnapshotIdentifier_IamDatabaseAuthenticationEnabled(t CheckDestroy: testAccCheckAWSDBInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSDBInstanceConfig_SnapshotIdentifier_IamDatabaseAuthenticationEnabled(rName, true), + Config: testAccAWSDBInstanceConfig_ReplicateSourceDb_MaintenanceWindow(rName, "sun:01:00-sun:01:30"), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists(sourceDbResourceName, &sourceDbInstance), - testAccCheckDbSnapshotExists(snapshotResourceName, &dbSnapshot), + testAccCheckAWSDBInstanceExists(sourceResourceName, &sourceDbInstance), testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), - resource.TestCheckResourceAttr(resourceName, "iam_database_authentication_enabled", "true"), + testAccCheckAWSDBInstanceReplicaAttributes(&sourceDbInstance, &dbInstance), + resource.TestCheckResourceAttr(resourceName, "maintenance_window", "sun:01:00-sun:01:30"), ), }, }, }) } -func TestAccAWSDBInstance_SnapshotIdentifier_MaintenanceWindow(t *testing.T) { +func TestAccAWSDBInstance_ReplicateSourceDb_Monitoring(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance - var dbSnapshot rds.DBSnapshot rName := acctest.RandomWithPrefix("tf-acc-test") - sourceDbResourceName := "aws_db_instance.source" - snapshotResourceName := "aws_db_snapshot.test" + sourceResourceName := "aws_db_instance.source" resourceName := "aws_db_instance.test" resource.Test(t, resource.TestCase{ @@ -498,25 +546,23 @@ func TestAccAWSDBInstance_SnapshotIdentifier_MaintenanceWindow(t *testing.T) { CheckDestroy: testAccCheckAWSDBInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSDBInstanceConfig_SnapshotIdentifier_MaintenanceWindow(rName, "sun:01:00-sun:01:30"), + Config: testAccAWSDBInstanceConfig_ReplicateSourceDb_Monitoring(rName, 5), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists(sourceDbResourceName, &sourceDbInstance), - testAccCheckDbSnapshotExists(snapshotResourceName, &dbSnapshot), + testAccCheckAWSDBInstanceExists(sourceResourceName, &sourceDbInstance), testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), - resource.TestCheckResourceAttr(resourceName, "maintenance_window", "sun:01:00-sun:01:30"), + testAccCheckAWSDBInstanceReplicaAttributes(&sourceDbInstance, &dbInstance), + resource.TestCheckResourceAttr(resourceName, "monitoring_interval", "5"), ), }, }, }) } -func TestAccAWSDBInstance_SnapshotIdentifier_Monitoring(t *testing.T) { +func TestAccAWSDBInstance_ReplicateSourceDb_MultiAZ(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance - var dbSnapshot rds.DBSnapshot rName := acctest.RandomWithPrefix("tf-acc-test") - sourceDbResourceName := "aws_db_instance.source" - snapshotResourceName := "aws_db_snapshot.test" + sourceResourceName := "aws_db_instance.source" resourceName := "aws_db_instance.test" resource.Test(t, resource.TestCase{ @@ -525,25 +571,23 @@ func TestAccAWSDBInstance_SnapshotIdentifier_Monitoring(t *testing.T) { CheckDestroy: testAccCheckAWSDBInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSDBInstanceConfig_SnapshotIdentifier_Monitoring(rName, 5), + Config: testAccAWSDBInstanceConfig_ReplicateSourceDb_MultiAZ(rName, true), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists(sourceDbResourceName, &sourceDbInstance), - testAccCheckDbSnapshotExists(snapshotResourceName, &dbSnapshot), + testAccCheckAWSDBInstanceExists(sourceResourceName, &sourceDbInstance), testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), - resource.TestCheckResourceAttr(resourceName, "monitoring_interval", "5"), + testAccCheckAWSDBInstanceReplicaAttributes(&sourceDbInstance, &dbInstance), + resource.TestCheckResourceAttr(resourceName, "multi_az", "true"), ), }, }, }) } -func TestAccAWSDBInstance_SnapshotIdentifier_MultiAZ(t *testing.T) { +func TestAccAWSDBInstance_ReplicateSourceDb_ParameterGroupName(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance - var dbSnapshot rds.DBSnapshot rName := acctest.RandomWithPrefix("tf-acc-test") - sourceDbResourceName := "aws_db_instance.source" - snapshotResourceName := "aws_db_snapshot.test" + sourceResourceName := "aws_db_instance.source" resourceName := "aws_db_instance.test" resource.Test(t, resource.TestCase{ @@ -552,25 +596,24 @@ func TestAccAWSDBInstance_SnapshotIdentifier_MultiAZ(t *testing.T) { CheckDestroy: testAccCheckAWSDBInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSDBInstanceConfig_SnapshotIdentifier_MultiAZ(rName, true), + Config: testAccAWSDBInstanceConfig_ReplicateSourceDb_ParameterGroupName(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists(sourceDbResourceName, &sourceDbInstance), - testAccCheckDbSnapshotExists(snapshotResourceName, &dbSnapshot), + testAccCheckAWSDBInstanceExists(sourceResourceName, &sourceDbInstance), testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), - resource.TestCheckResourceAttr(resourceName, "multi_az", "true"), + testAccCheckAWSDBInstanceReplicaAttributes(&sourceDbInstance, &dbInstance), + resource.TestCheckResourceAttr(resourceName, "parameter_group_name", rName), + testAccCheckAWSDBInstanceParameterApplyStatusInSync(&dbInstance), ), }, }, }) } -func TestAccAWSDBInstance_SnapshotIdentifier_MultiAZ_SQLServer(t *testing.T) { +func TestAccAWSDBInstance_ReplicateSourceDb_Port(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance - var dbSnapshot rds.DBSnapshot rName := acctest.RandomWithPrefix("tf-acc-test") - sourceDbResourceName := "aws_db_instance.source" - snapshotResourceName := "aws_db_snapshot.test" + sourceResourceName := "aws_db_instance.source" resourceName := "aws_db_instance.test" resource.Test(t, resource.TestCase{ @@ -579,25 +622,23 @@ func TestAccAWSDBInstance_SnapshotIdentifier_MultiAZ_SQLServer(t *testing.T) { CheckDestroy: testAccCheckAWSDBInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSDBInstanceConfig_SnapshotIdentifier_MultiAZ_SQLServer(rName, true), + Config: testAccAWSDBInstanceConfig_ReplicateSourceDb_Port(rName, 9999), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists(sourceDbResourceName, &sourceDbInstance), - testAccCheckDbSnapshotExists(snapshotResourceName, &dbSnapshot), + testAccCheckAWSDBInstanceExists(sourceResourceName, &sourceDbInstance), testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), - resource.TestCheckResourceAttr(resourceName, "multi_az", "true"), + testAccCheckAWSDBInstanceReplicaAttributes(&sourceDbInstance, &dbInstance), + resource.TestCheckResourceAttr(resourceName, "port", "9999"), ), }, }, }) } -func TestAccAWSDBInstance_SnapshotIdentifier_ParameterGroupName(t *testing.T) { +func TestAccAWSDBInstance_ReplicateSourceDb_VpcSecurityGroupIds(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance - var dbSnapshot rds.DBSnapshot rName := acctest.RandomWithPrefix("tf-acc-test") - sourceDbResourceName := "aws_db_instance.source" - snapshotResourceName := "aws_db_snapshot.test" + sourceResourceName := "aws_db_instance.source" resourceName := "aws_db_instance.test" resource.Test(t, resource.TestCase{ @@ -606,19 +647,40 @@ func TestAccAWSDBInstance_SnapshotIdentifier_ParameterGroupName(t *testing.T) { CheckDestroy: testAccCheckAWSDBInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSDBInstanceConfig_SnapshotIdentifier_ParameterGroupName(rName), + Config: testAccAWSDBInstanceConfig_ReplicateSourceDb_VpcSecurityGroupIds(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists(sourceDbResourceName, &sourceDbInstance), - testAccCheckDbSnapshotExists(snapshotResourceName, &dbSnapshot), + testAccCheckAWSDBInstanceExists(sourceResourceName, &sourceDbInstance), testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), - resource.TestCheckResourceAttr(resourceName, "parameter_group_name", rName), + testAccCheckAWSDBInstanceReplicaAttributes(&sourceDbInstance, &dbInstance), + resource.TestCheckResourceAttr(resourceName, "vpc_security_group_ids.#", "1"), ), }, }, }) } -func TestAccAWSDBInstance_SnapshotIdentifier_Tags(t *testing.T) { +func TestAccAWSDBInstance_S3Import(t *testing.T) { + var snap rds.DBInstance + bucket := acctest.RandomWithPrefix("tf-acc-test") + uniqueId := acctest.RandomWithPrefix("tf-acc-s3-import-test") + bucketPrefix := acctest.RandString(5) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSDBInstanceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSDBInstanceConfig_S3Import(bucket, bucketPrefix, uniqueId), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSDBInstanceExists("aws_db_instance.s3", &snap), + ), + }, + }, + }) +} + +func TestAccAWSDBInstance_SnapshotIdentifier(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -633,20 +695,18 @@ func TestAccAWSDBInstance_SnapshotIdentifier_Tags(t *testing.T) { CheckDestroy: testAccCheckAWSDBInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSDBInstanceConfig_SnapshotIdentifier_Tags(rName), + Config: testAccAWSDBInstanceConfig_SnapshotIdentifier(rName), Check: resource.ComposeTestCheckFunc( testAccCheckAWSDBInstanceExists(sourceDbResourceName, &sourceDbInstance), testAccCheckDbSnapshotExists(snapshotResourceName, &dbSnapshot), testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), - resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), - resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), ), }, }, }) } -func TestAccAWSDBInstance_SnapshotIdentifier_VpcSecurityGroupIds(t *testing.T) { +func TestAccAWSDBInstance_SnapshotIdentifier_AllocatedStorage(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -661,22 +721,19 @@ func TestAccAWSDBInstance_SnapshotIdentifier_VpcSecurityGroupIds(t *testing.T) { CheckDestroy: testAccCheckAWSDBInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSDBInstanceConfig_SnapshotIdentifier_VpcSecurityGroupIds(rName), + Config: testAccAWSDBInstanceConfig_SnapshotIdentifier_AllocatedStorage(rName, 10), Check: resource.ComposeTestCheckFunc( testAccCheckAWSDBInstanceExists(sourceDbResourceName, &sourceDbInstance), testAccCheckDbSnapshotExists(snapshotResourceName, &dbSnapshot), testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), + resource.TestCheckResourceAttr(resourceName, "allocated_storage", "10"), ), }, }, }) } -// Regression reference: https://github.com/terraform-providers/terraform-provider-aws/issues/5360 -// This acceptance test explicitly tests when snapshot_identifer is set, -// vpc_security_group_ids is set (which triggered the resource update function), -// and tags is set which was missing its ARN used for tagging -func TestAccAWSDBInstance_SnapshotIdentifier_VpcSecurityGroupIds_Tags(t *testing.T) { +func TestAccAWSDBInstance_SnapshotIdentifier_AutoMinorVersionUpgrade(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -691,22 +748,26 @@ func TestAccAWSDBInstance_SnapshotIdentifier_VpcSecurityGroupIds_Tags(t *testing CheckDestroy: testAccCheckAWSDBInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSDBInstanceConfig_SnapshotIdentifier_VpcSecurityGroupIds_Tags(rName), + Config: testAccAWSDBInstanceConfig_SnapshotIdentifier_AutoMinorVersionUpgrade(rName, false), Check: resource.ComposeTestCheckFunc( testAccCheckAWSDBInstanceExists(sourceDbResourceName, &sourceDbInstance), testAccCheckDbSnapshotExists(snapshotResourceName, &dbSnapshot), testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), - resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), - resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), + resource.TestCheckResourceAttr(resourceName, "auto_minor_version_upgrade", "false"), ), }, }, }) } -func TestAccAWSDBInstance_enhancedMonitoring(t *testing.T) { - var dbInstance rds.DBInstance - rName := acctest.RandString(5) +func TestAccAWSDBInstance_SnapshotIdentifier_AvailabilityZone(t *testing.T) { + var dbInstance, sourceDbInstance rds.DBInstance + var dbSnapshot rds.DBSnapshot + + rName := acctest.RandomWithPrefix("tf-acc-test") + sourceDbResourceName := "aws_db_instance.source" + snapshotResourceName := "aws_db_snapshot.test" + resourceName := "aws_db_instance.test" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -714,24 +775,25 @@ func TestAccAWSDBInstance_enhancedMonitoring(t *testing.T) { CheckDestroy: testAccCheckAWSDBInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccSnapshotInstanceConfig_enhancedMonitoring(rName), + Config: testAccAWSDBInstanceConfig_SnapshotIdentifier_AvailabilityZone(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists("aws_db_instance.enhanced_monitoring", &dbInstance), - resource.TestCheckResourceAttr( - "aws_db_instance.enhanced_monitoring", "monitoring_interval", "5"), + testAccCheckAWSDBInstanceExists(sourceDbResourceName, &sourceDbInstance), + testAccCheckDbSnapshotExists(snapshotResourceName, &dbSnapshot), + testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), ), }, }, }) } -// Regression test for https://github.com/hashicorp/terraform/issues/3760 . -// We apply a plan, then change just the iops. If the apply succeeds, we -// consider this a pass, as before in 3760 the request would fail -func TestAccAWSDBInstance_separate_iops_update(t *testing.T) { - var v rds.DBInstance +func TestAccAWSDBInstance_SnapshotIdentifier_BackupRetentionPeriod(t *testing.T) { + var dbInstance, sourceDbInstance rds.DBInstance + var dbSnapshot rds.DBSnapshot - rName := acctest.RandString(5) + rName := acctest.RandomWithPrefix("tf-acc-test") + sourceDbResourceName := "aws_db_instance.source" + snapshotResourceName := "aws_db_snapshot.test" + resourceName := "aws_db_instance.test" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -739,28 +801,26 @@ func TestAccAWSDBInstance_separate_iops_update(t *testing.T) { CheckDestroy: testAccCheckAWSDBInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccSnapshotInstanceConfig_iopsUpdate(rName, 1000), - Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v), - testAccCheckAWSDBInstanceAttributes(&v), - ), - }, - - { - Config: testAccSnapshotInstanceConfig_iopsUpdate(rName, 2000), + Config: testAccAWSDBInstanceConfig_SnapshotIdentifier_BackupRetentionPeriod(rName, 1), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v), - testAccCheckAWSDBInstanceAttributes(&v), + testAccCheckAWSDBInstanceExists(sourceDbResourceName, &sourceDbInstance), + testAccCheckDbSnapshotExists(snapshotResourceName, &dbSnapshot), + testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), + resource.TestCheckResourceAttr(resourceName, "backup_retention_period", "1"), ), }, }, }) } -func TestAccAWSDBInstance_portUpdate(t *testing.T) { - var v rds.DBInstance +func TestAccAWSDBInstance_SnapshotIdentifier_BackupWindow(t *testing.T) { + var dbInstance, sourceDbInstance rds.DBInstance + var dbSnapshot rds.DBSnapshot - rName := acctest.RandString(5) + rName := acctest.RandomWithPrefix("tf-acc-test") + sourceDbResourceName := "aws_db_instance.source" + snapshotResourceName := "aws_db_snapshot.test" + resourceName := "aws_db_instance.test" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -768,29 +828,26 @@ func TestAccAWSDBInstance_portUpdate(t *testing.T) { CheckDestroy: testAccCheckAWSDBInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccSnapshotInstanceConfig_mysqlPort(rName), + Config: testAccAWSDBInstanceConfig_SnapshotIdentifier_BackupWindow(rName, "00:00-08:00"), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_instance.bar", "port", "3306"), - ), - }, - - { - Config: testAccSnapshotInstanceConfig_updateMysqlPort(rName), - Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_instance.bar", "port", "3305"), + testAccCheckAWSDBInstanceExists(sourceDbResourceName, &sourceDbInstance), + testAccCheckDbSnapshotExists(snapshotResourceName, &dbSnapshot), + testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), + resource.TestCheckResourceAttr(resourceName, "backup_window", "00:00-08:00"), ), }, }, }) } -func TestAccAWSDBInstance_MSSQL_TZ(t *testing.T) { - var v rds.DBInstance - rInt := acctest.RandInt() +func TestAccAWSDBInstance_SnapshotIdentifier_IamDatabaseAuthenticationEnabled(t *testing.T) { + var dbInstance, sourceDbInstance rds.DBInstance + var dbSnapshot rds.DBSnapshot + + rName := acctest.RandomWithPrefix("tf-acc-test") + sourceDbResourceName := "aws_db_instance.source" + snapshotResourceName := "aws_db_snapshot.test" + resourceName := "aws_db_instance.test" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -798,34 +855,53 @@ func TestAccAWSDBInstance_MSSQL_TZ(t *testing.T) { CheckDestroy: testAccCheckAWSDBInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSDBMSSQL_timezone(rInt), + Config: testAccAWSDBInstanceConfig_SnapshotIdentifier_IamDatabaseAuthenticationEnabled(rName, true), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists("aws_db_instance.mssql", &v), - testAccCheckAWSDBInstanceAttributes_MSSQL(&v, ""), - resource.TestCheckResourceAttr( - "aws_db_instance.mssql", "allocated_storage", "20"), - resource.TestCheckResourceAttr( - "aws_db_instance.mssql", "engine", "sqlserver-ex"), + testAccCheckAWSDBInstanceExists(sourceDbResourceName, &sourceDbInstance), + testAccCheckDbSnapshotExists(snapshotResourceName, &dbSnapshot), + testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), + resource.TestCheckResourceAttr(resourceName, "iam_database_authentication_enabled", "true"), ), }, + }, + }) +} + +func TestAccAWSDBInstance_SnapshotIdentifier_MaintenanceWindow(t *testing.T) { + var dbInstance, sourceDbInstance rds.DBInstance + var dbSnapshot rds.DBSnapshot + + rName := acctest.RandomWithPrefix("tf-acc-test") + sourceDbResourceName := "aws_db_instance.source" + snapshotResourceName := "aws_db_snapshot.test" + resourceName := "aws_db_instance.test" + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSDBInstanceDestroy, + Steps: []resource.TestStep{ { - Config: testAccAWSDBMSSQL_timezone_AKST(rInt), + Config: testAccAWSDBInstanceConfig_SnapshotIdentifier_MaintenanceWindow(rName, "sun:01:00-sun:01:30"), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists("aws_db_instance.mssql", &v), - testAccCheckAWSDBInstanceAttributes_MSSQL(&v, "Alaskan Standard Time"), - resource.TestCheckResourceAttr( - "aws_db_instance.mssql", "allocated_storage", "20"), - resource.TestCheckResourceAttr( - "aws_db_instance.mssql", "engine", "sqlserver-ex"), + testAccCheckAWSDBInstanceExists(sourceDbResourceName, &sourceDbInstance), + testAccCheckDbSnapshotExists(snapshotResourceName, &dbSnapshot), + testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), + resource.TestCheckResourceAttr(resourceName, "maintenance_window", "sun:01:00-sun:01:30"), ), }, }, }) } -func TestAccAWSDBInstance_MinorVersion(t *testing.T) { - var v rds.DBInstance +func TestAccAWSDBInstance_SnapshotIdentifier_Monitoring(t *testing.T) { + var dbInstance, sourceDbInstance rds.DBInstance + var dbSnapshot rds.DBSnapshot + + rName := acctest.RandomWithPrefix("tf-acc-test") + sourceDbResourceName := "aws_db_instance.source" + snapshotResourceName := "aws_db_snapshot.test" + resourceName := "aws_db_instance.test" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -833,19 +909,26 @@ func TestAccAWSDBInstance_MinorVersion(t *testing.T) { CheckDestroy: testAccCheckAWSDBInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSDBInstanceConfigAutoMinorVersion, + Config: testAccAWSDBInstanceConfig_SnapshotIdentifier_Monitoring(rName, 5), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v), + testAccCheckAWSDBInstanceExists(sourceDbResourceName, &sourceDbInstance), + testAccCheckDbSnapshotExists(snapshotResourceName, &dbSnapshot), + testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), + resource.TestCheckResourceAttr(resourceName, "monitoring_interval", "5"), ), }, }, }) } -// See https://github.com/hashicorp/terraform/issues/11881 -func TestAccAWSDBInstance_diffSuppressInitialState(t *testing.T) { - var v rds.DBInstance - rInt := acctest.RandInt() +func TestAccAWSDBInstance_SnapshotIdentifier_MultiAZ(t *testing.T) { + var dbInstance, sourceDbInstance rds.DBInstance + var dbSnapshot rds.DBSnapshot + + rName := acctest.RandomWithPrefix("tf-acc-test") + sourceDbResourceName := "aws_db_instance.source" + snapshotResourceName := "aws_db_snapshot.test" + resourceName := "aws_db_instance.test" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -853,43 +936,53 @@ func TestAccAWSDBInstance_diffSuppressInitialState(t *testing.T) { CheckDestroy: testAccCheckAWSDBInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSDBInstanceConfigSuppressInitialState(rInt), + Config: testAccAWSDBInstanceConfig_SnapshotIdentifier_MultiAZ(rName, true), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v), + testAccCheckAWSDBInstanceExists(sourceDbResourceName, &sourceDbInstance), + testAccCheckDbSnapshotExists(snapshotResourceName, &dbSnapshot), + testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), + resource.TestCheckResourceAttr(resourceName, "multi_az", "true"), ), }, }, }) } -func TestAccAWSDBInstance_ec2Classic(t *testing.T) { - var v rds.DBInstance - - oldvar := os.Getenv("AWS_DEFAULT_REGION") - os.Setenv("AWS_DEFAULT_REGION", "us-east-1") - defer os.Setenv("AWS_DEFAULT_REGION", oldvar) +func TestAccAWSDBInstance_SnapshotIdentifier_MultiAZ_SQLServer(t *testing.T) { + var dbInstance, sourceDbInstance rds.DBInstance + var dbSnapshot rds.DBSnapshot - rInt := acctest.RandInt() + rName := acctest.RandomWithPrefix("tf-acc-test") + sourceDbResourceName := "aws_db_instance.source" + snapshotResourceName := "aws_db_snapshot.test" + resourceName := "aws_db_instance.test" resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t); testAccEC2ClassicPreCheck(t) }, + PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAWSDBInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSDBInstanceConfigEc2Classic(rInt), + Config: testAccAWSDBInstanceConfig_SnapshotIdentifier_MultiAZ_SQLServer(rName, true), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v), + testAccCheckAWSDBInstanceExists(sourceDbResourceName, &sourceDbInstance), + testAccCheckDbSnapshotExists(snapshotResourceName, &dbSnapshot), + testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), + resource.TestCheckResourceAttr(resourceName, "multi_az", "true"), ), }, }, }) } -func TestAccAWSDBInstance_cloudwatchLogsExportConfiguration(t *testing.T) { - var v rds.DBInstance +func TestAccAWSDBInstance_SnapshotIdentifier_ParameterGroupName(t *testing.T) { + var dbInstance, sourceDbInstance rds.DBInstance + var dbSnapshot rds.DBSnapshot - rInt := acctest.RandInt() + rName := acctest.RandomWithPrefix("tf-acc-test") + sourceDbResourceName := "aws_db_instance.source" + snapshotResourceName := "aws_db_snapshot.test" + resourceName := "aws_db_instance.test" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -897,25 +990,27 @@ func TestAccAWSDBInstance_cloudwatchLogsExportConfiguration(t *testing.T) { CheckDestroy: testAccCheckAWSDBInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSDBInstanceConfigCloudwatchLogsExportConfiguration(rInt), + Config: testAccAWSDBInstanceConfig_SnapshotIdentifier_ParameterGroupName(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v), + testAccCheckAWSDBInstanceExists(sourceDbResourceName, &sourceDbInstance), + testAccCheckDbSnapshotExists(snapshotResourceName, &dbSnapshot), + testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), + resource.TestCheckResourceAttr(resourceName, "parameter_group_name", rName), + testAccCheckAWSDBInstanceParameterApplyStatusInSync(&dbInstance), ), }, - { - ResourceName: "aws_db_instance.bar", - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"password"}, - }, }, }) } -func TestAccAWSDBInstance_cloudwatchLogsExportConfigurationUpdate(t *testing.T) { - var v rds.DBInstance +func TestAccAWSDBInstance_SnapshotIdentifier_Port(t *testing.T) { + var dbInstance, sourceDbInstance rds.DBInstance + var dbSnapshot rds.DBSnapshot - rInt := acctest.RandInt() + rName := acctest.RandomWithPrefix("tf-acc-test") + sourceDbResourceName := "aws_db_instance.source" + snapshotResourceName := "aws_db_snapshot.test" + resourceName := "aws_db_instance.test" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -923,55 +1018,83 @@ func TestAccAWSDBInstance_cloudwatchLogsExportConfigurationUpdate(t *testing.T) CheckDestroy: testAccCheckAWSDBInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSDBInstanceConfigCloudwatchLogsExportConfiguration(rInt), - Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_instance.bar", "enabled_cloudwatch_logs_exports.0", "audit"), - resource.TestCheckResourceAttr( - "aws_db_instance.bar", "enabled_cloudwatch_logs_exports.1", "error"), - ), - }, - { - Config: testAccAWSDBInstanceConfigCloudwatchLogsExportConfigurationAdd(rInt), + Config: testAccAWSDBInstanceConfig_SnapshotIdentifier_Port(rName, 9999), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_instance.bar", "enabled_cloudwatch_logs_exports.0", "audit"), - resource.TestCheckResourceAttr( - "aws_db_instance.bar", "enabled_cloudwatch_logs_exports.1", "error"), - resource.TestCheckResourceAttr( - "aws_db_instance.bar", "enabled_cloudwatch_logs_exports.2", "general"), + testAccCheckAWSDBInstanceExists(sourceDbResourceName, &sourceDbInstance), + testAccCheckDbSnapshotExists(snapshotResourceName, &dbSnapshot), + testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), + resource.TestCheckResourceAttr(resourceName, "port", "9999"), ), }, + }, + }) +} + +func TestAccAWSDBInstance_SnapshotIdentifier_Tags(t *testing.T) { + var dbInstance, sourceDbInstance rds.DBInstance + var dbSnapshot rds.DBSnapshot + + rName := acctest.RandomWithPrefix("tf-acc-test") + sourceDbResourceName := "aws_db_instance.source" + snapshotResourceName := "aws_db_snapshot.test" + resourceName := "aws_db_instance.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSDBInstanceDestroy, + Steps: []resource.TestStep{ { - Config: testAccAWSDBInstanceConfigCloudwatchLogsExportConfigurationModify(rInt), + Config: testAccAWSDBInstanceConfig_SnapshotIdentifier_Tags(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_instance.bar", "enabled_cloudwatch_logs_exports.0", "audit"), - resource.TestCheckResourceAttr( - "aws_db_instance.bar", "enabled_cloudwatch_logs_exports.1", "general"), - resource.TestCheckResourceAttr( - "aws_db_instance.bar", "enabled_cloudwatch_logs_exports.2", "slowquery"), + testAccCheckAWSDBInstanceExists(sourceDbResourceName, &sourceDbInstance), + testAccCheckDbSnapshotExists(snapshotResourceName, &dbSnapshot), + testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), ), }, + }, + }) +} + +func TestAccAWSDBInstance_SnapshotIdentifier_VpcSecurityGroupIds(t *testing.T) { + var dbInstance, sourceDbInstance rds.DBInstance + var dbSnapshot rds.DBSnapshot + + rName := acctest.RandomWithPrefix("tf-acc-test") + sourceDbResourceName := "aws_db_instance.source" + snapshotResourceName := "aws_db_snapshot.test" + resourceName := "aws_db_instance.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSDBInstanceDestroy, + Steps: []resource.TestStep{ { - Config: testAccAWSDBInstanceConfigCloudwatchLogsExportConfigurationDelete(rInt), + Config: testAccAWSDBInstanceConfig_SnapshotIdentifier_VpcSecurityGroupIds(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_instance.bar", "enabled_cloudwatch_logs_exports.#", "0"), + testAccCheckAWSDBInstanceExists(sourceDbResourceName, &sourceDbInstance), + testAccCheckDbSnapshotExists(snapshotResourceName, &dbSnapshot), + testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), ), }, }, }) } -func TestAccAWSDBInstance_EnabledCloudwatchLogsExports_Oracle(t *testing.T) { - var dbInstance rds.DBInstance +// Regression reference: https://github.com/terraform-providers/terraform-provider-aws/issues/5360 +// This acceptance test explicitly tests when snapshot_identifer is set, +// vpc_security_group_ids is set (which triggered the resource update function), +// and tags is set which was missing its ARN used for tagging +func TestAccAWSDBInstance_SnapshotIdentifier_VpcSecurityGroupIds_Tags(t *testing.T) { + var dbInstance, sourceDbInstance rds.DBInstance + var dbSnapshot rds.DBSnapshot rName := acctest.RandomWithPrefix("tf-acc-test") + sourceDbResourceName := "aws_db_instance.source" + snapshotResourceName := "aws_db_snapshot.test" resourceName := "aws_db_instance.test" resource.Test(t, resource.TestCase{ @@ -980,24 +1103,313 @@ func TestAccAWSDBInstance_EnabledCloudwatchLogsExports_Oracle(t *testing.T) { CheckDestroy: testAccCheckAWSDBInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSDBInstanceConfig_EnabledCloudwatchLogsExports_Oracle(rName), + Config: testAccAWSDBInstanceConfig_SnapshotIdentifier_VpcSecurityGroupIds_Tags(rName), Check: resource.ComposeTestCheckFunc( + testAccCheckAWSDBInstanceExists(sourceDbResourceName, &sourceDbInstance), + testAccCheckDbSnapshotExists(snapshotResourceName, &dbSnapshot), testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), - resource.TestCheckResourceAttr(resourceName, "enabled_cloudwatch_logs_exports.#", "3"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), ), }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"password"}, - }, }, }) } -func testAccCheckAWSDBInstanceDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*AWSClient).rdsconn +func TestAccAWSDBInstance_enhancedMonitoring(t *testing.T) { + var dbInstance rds.DBInstance + rName := acctest.RandString(5) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSDBInstanceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccSnapshotInstanceConfig_enhancedMonitoring(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSDBInstanceExists("aws_db_instance.enhanced_monitoring", &dbInstance), + resource.TestCheckResourceAttr( + "aws_db_instance.enhanced_monitoring", "monitoring_interval", "5"), + ), + }, + }, + }) +} + +// Regression test for https://github.com/hashicorp/terraform/issues/3760 . +// We apply a plan, then change just the iops. If the apply succeeds, we +// consider this a pass, as before in 3760 the request would fail +func TestAccAWSDBInstance_separate_iops_update(t *testing.T) { + var v rds.DBInstance + + rName := acctest.RandString(5) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSDBInstanceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccSnapshotInstanceConfig_iopsUpdate(rName, 1000), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v), + testAccCheckAWSDBInstanceAttributes(&v), + ), + }, + + { + Config: testAccSnapshotInstanceConfig_iopsUpdate(rName, 2000), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v), + testAccCheckAWSDBInstanceAttributes(&v), + ), + }, + }, + }) +} + +func TestAccAWSDBInstance_portUpdate(t *testing.T) { + var v rds.DBInstance + + rName := acctest.RandString(5) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSDBInstanceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccSnapshotInstanceConfig_mysqlPort(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v), + resource.TestCheckResourceAttr( + "aws_db_instance.bar", "port", "3306"), + ), + }, + + { + Config: testAccSnapshotInstanceConfig_updateMysqlPort(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v), + resource.TestCheckResourceAttr( + "aws_db_instance.bar", "port", "3305"), + ), + }, + }, + }) +} + +func TestAccAWSDBInstance_MSSQL_TZ(t *testing.T) { + var v rds.DBInstance + rInt := acctest.RandInt() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSDBInstanceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSDBMSSQL_timezone(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSDBInstanceExists("aws_db_instance.mssql", &v), + testAccCheckAWSDBInstanceAttributes_MSSQL(&v, ""), + resource.TestCheckResourceAttr( + "aws_db_instance.mssql", "allocated_storage", "20"), + resource.TestCheckResourceAttr( + "aws_db_instance.mssql", "engine", "sqlserver-ex"), + ), + }, + + { + Config: testAccAWSDBMSSQL_timezone_AKST(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSDBInstanceExists("aws_db_instance.mssql", &v), + testAccCheckAWSDBInstanceAttributes_MSSQL(&v, "Alaskan Standard Time"), + resource.TestCheckResourceAttr( + "aws_db_instance.mssql", "allocated_storage", "20"), + resource.TestCheckResourceAttr( + "aws_db_instance.mssql", "engine", "sqlserver-ex"), + ), + }, + }, + }) +} + +func TestAccAWSDBInstance_MinorVersion(t *testing.T) { + var v rds.DBInstance + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSDBInstanceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSDBInstanceConfigAutoMinorVersion, + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v), + ), + }, + }, + }) +} + +// See https://github.com/hashicorp/terraform/issues/11881 +func TestAccAWSDBInstance_diffSuppressInitialState(t *testing.T) { + var v rds.DBInstance + rInt := acctest.RandInt() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSDBInstanceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSDBInstanceConfigSuppressInitialState(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v), + ), + }, + }, + }) +} + +func TestAccAWSDBInstance_ec2Classic(t *testing.T) { + var v rds.DBInstance + + oldvar := os.Getenv("AWS_DEFAULT_REGION") + os.Setenv("AWS_DEFAULT_REGION", "us-east-1") + defer os.Setenv("AWS_DEFAULT_REGION", oldvar) + + rInt := acctest.RandInt() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccEC2ClassicPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSDBInstanceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSDBInstanceConfigEc2Classic(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v), + ), + }, + }, + }) +} + +func TestAccAWSDBInstance_cloudwatchLogsExportConfiguration(t *testing.T) { + var v rds.DBInstance + + rInt := acctest.RandInt() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSDBInstanceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSDBInstanceConfigCloudwatchLogsExportConfiguration(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v), + ), + }, + { + ResourceName: "aws_db_instance.bar", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"password"}, + }, + }, + }) +} + +func TestAccAWSDBInstance_cloudwatchLogsExportConfigurationUpdate(t *testing.T) { + var v rds.DBInstance + + rInt := acctest.RandInt() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSDBInstanceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSDBInstanceConfigCloudwatchLogsExportConfiguration(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v), + resource.TestCheckResourceAttr( + "aws_db_instance.bar", "enabled_cloudwatch_logs_exports.0", "audit"), + resource.TestCheckResourceAttr( + "aws_db_instance.bar", "enabled_cloudwatch_logs_exports.1", "error"), + ), + }, + { + Config: testAccAWSDBInstanceConfigCloudwatchLogsExportConfigurationAdd(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v), + resource.TestCheckResourceAttr( + "aws_db_instance.bar", "enabled_cloudwatch_logs_exports.0", "audit"), + resource.TestCheckResourceAttr( + "aws_db_instance.bar", "enabled_cloudwatch_logs_exports.1", "error"), + resource.TestCheckResourceAttr( + "aws_db_instance.bar", "enabled_cloudwatch_logs_exports.2", "general"), + ), + }, + { + Config: testAccAWSDBInstanceConfigCloudwatchLogsExportConfigurationModify(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v), + resource.TestCheckResourceAttr( + "aws_db_instance.bar", "enabled_cloudwatch_logs_exports.0", "audit"), + resource.TestCheckResourceAttr( + "aws_db_instance.bar", "enabled_cloudwatch_logs_exports.1", "general"), + resource.TestCheckResourceAttr( + "aws_db_instance.bar", "enabled_cloudwatch_logs_exports.2", "slowquery"), + ), + }, + { + Config: testAccAWSDBInstanceConfigCloudwatchLogsExportConfigurationDelete(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v), + resource.TestCheckResourceAttr( + "aws_db_instance.bar", "enabled_cloudwatch_logs_exports.#", "0"), + ), + }, + }, + }) +} + +func TestAccAWSDBInstance_EnabledCloudwatchLogsExports_Oracle(t *testing.T) { + var dbInstance rds.DBInstance + + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_db_instance.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSDBInstanceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSDBInstanceConfig_EnabledCloudwatchLogsExports_Oracle(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSDBInstanceExists(resourceName, &dbInstance), + resource.TestCheckResourceAttr(resourceName, "enabled_cloudwatch_logs_exports.#", "3"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"password"}, + }, + }, + }) +} + +func testAccCheckAWSDBInstanceDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).rdsconn for _, rs := range s.RootModule().Resources { if rs.Type != "aws_db_instance" { @@ -1066,6 +1478,21 @@ func testAccCheckAWSDBInstanceAttributes_MSSQL(v *rds.DBInstance, tz string) res } } +func testAccCheckAWSDBInstanceParameterApplyStatusInSync(dbInstance *rds.DBInstance) resource.TestCheckFunc { + return func(s *terraform.State) error { + for _, dbParameterGroup := range dbInstance.DBParameterGroups { + parameterApplyStatus := aws.StringValue(dbParameterGroup.ParameterApplyStatus) + if parameterApplyStatus != "in-sync" { + id := aws.StringValue(dbInstance.DBInstanceIdentifier) + parameterGroupName := aws.StringValue(dbParameterGroup.DBParameterGroupName) + return fmt.Errorf("expected DB Instance (%s) Parameter Group (%s) apply status to be: \"in-sync\", got: %q", id, parameterGroupName, parameterApplyStatus) + } + } + + return nil + } +} + func testAccCheckAWSDBInstanceReplicaAttributes(source, replica *rds.DBInstance) resource.TestCheckFunc { return func(s *terraform.State) error { @@ -1374,43 +1801,6 @@ resource "aws_db_instance" "bar" { }`, n) } -func testAccReplicaInstanceConfig(val int) string { - return fmt.Sprintf(` - resource "aws_db_instance" "bar" { - identifier = "foobarbaz-test-terraform-%d" - - allocated_storage = 5 - engine = "mysql" - engine_version = "5.6.35" - instance_class = "db.t2.micro" - name = "baz" - password = "barbarbarbar" - username = "foo" - - backup_retention_period = 1 - skip_final_snapshot = true - - parameter_group_name = "default.mysql5.6" - } - - resource "aws_db_instance" "replica" { - identifier = "tf-replica-db-%d" - backup_retention_period = 0 - replicate_source_db = "${aws_db_instance.bar.identifier}" - allocated_storage = "${aws_db_instance.bar.allocated_storage}" - engine = "${aws_db_instance.bar.engine}" - engine_version = "${aws_db_instance.bar.engine_version}" - instance_class = "${aws_db_instance.bar.instance_class}" - password = "${aws_db_instance.bar.password}" - username = "${aws_db_instance.bar.username}" - skip_final_snapshot = true - tags { - Name = "tf-replica-db" - } - } - `, val, val) -} - func testAccAWSDBInstanceConfig_FinalSnapshotIdentifier_SkipFinalSnapshot() string { return fmt.Sprintf(` resource "aws_db_instance" "snapshot" { @@ -1434,7 +1824,7 @@ resource "aws_db_instance" "snapshot" { }`, acctest.RandInt()) } -func testAccSnapshotInstanceConfigWithS3Import(bucketName string, bucketPrefix string, uniqueId string) string { +func testAccAWSDBInstanceConfig_S3Import(bucketName string, bucketPrefix string, uniqueId string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "xtrabackup" { @@ -1566,7 +1956,7 @@ resource "aws_db_instance" "s3" { `, bucketName, bucketPrefix, uniqueId, uniqueId, uniqueId, uniqueId, uniqueId, bucketPrefix) } -func testAccSnapshotInstanceConfigWithSnapshot(rInt int) string { +func testAccAWSDBInstanceConfig_FinalSnapshotIdentifier(rInt int) string { return fmt.Sprintf(` resource "aws_db_instance" "snapshot" { identifier = "tf-snapshot-%d" @@ -2089,15 +2479,75 @@ func testAccAWSDBInstanceConfigCloudwatchLogsExportConfiguration(rInt int) strin username = "foo" skip_final_snapshot = true - enabled_cloudwatch_logs_exports = [ - "audit", - "error", - ] - } - `, rInt, rInt) + enabled_cloudwatch_logs_exports = [ + "audit", + "error", + ] + } + `, rInt, rInt) +} + +func testAccAWSDBInstanceConfigCloudwatchLogsExportConfigurationAdd(rInt int) string { + return fmt.Sprintf(` + + resource "aws_vpc" "foo" { + cidr_block = "10.1.0.0/16" + enable_dns_hostnames = true + tags { + Name = "terraform-testacc-db-instance-enable-cloudwatch" + } + } + + resource "aws_db_subnet_group" "rds_one" { + name = "tf_acc_test_%d" + description = "db subnets for rds_one" + + subnet_ids = ["${aws_subnet.main.id}", "${aws_subnet.other.id}"] + } + + resource "aws_subnet" "main" { + vpc_id = "${aws_vpc.foo.id}" + availability_zone = "us-west-2a" + cidr_block = "10.1.1.0/24" + tags { + Name = "tf-acc-db-instance-enable-cloudwatch-main" + } + } + + resource "aws_subnet" "other" { + vpc_id = "${aws_vpc.foo.id}" + availability_zone = "us-west-2b" + cidr_block = "10.1.2.0/24" + tags { + Name = "tf-acc-db-instance-enable-cloudwatch-other" + } + } + + resource "aws_db_instance" "bar" { + identifier = "foobarbaz-test-terraform-%d" + + db_subnet_group_name = "${aws_db_subnet_group.rds_one.name}" + allocated_storage = 10 + engine = "MySQL" + engine_version = "5.6" + instance_class = "db.t2.micro" + name = "baz" + password = "barbarbarbar" + username = "foo" + skip_final_snapshot = true + + apply_immediately = true + + enabled_cloudwatch_logs_exports = [ + "audit", + "error", + "general", + ] + } + `, rInt, rInt) } -func testAccAWSDBInstanceConfigCloudwatchLogsExportConfigurationAdd(rInt int) string { +func testAccAWSDBInstanceConfigCloudwatchLogsExportConfigurationModify(rInt int) string { return fmt.Sprintf(` resource "aws_vpc" "foo" { @@ -2150,14 +2600,14 @@ func testAccAWSDBInstanceConfigCloudwatchLogsExportConfigurationAdd(rInt int) st enabled_cloudwatch_logs_exports = [ "audit", - "error", "general", + "slowquery", ] } `, rInt, rInt) } -func testAccAWSDBInstanceConfigCloudwatchLogsExportConfigurationModify(rInt int) string { +func testAccAWSDBInstanceConfigCloudwatchLogsExportConfigurationDelete(rInt int) string { return fmt.Sprintf(` resource "aws_vpc" "foo" { @@ -2196,154 +2646,523 @@ func testAccAWSDBInstanceConfigCloudwatchLogsExportConfigurationModify(rInt int) resource "aws_db_instance" "bar" { identifier = "foobarbaz-test-terraform-%d" - db_subnet_group_name = "${aws_db_subnet_group.rds_one.name}" - allocated_storage = 10 - engine = "MySQL" - engine_version = "5.6" - instance_class = "db.t2.micro" - name = "baz" - password = "barbarbarbar" - username = "foo" - skip_final_snapshot = true + db_subnet_group_name = "${aws_db_subnet_group.rds_one.name}" + allocated_storage = 10 + engine = "MySQL" + engine_version = "5.6" + instance_class = "db.t2.micro" + name = "baz" + password = "barbarbarbar" + username = "foo" + skip_final_snapshot = true + + apply_immediately = true + + } + `, rInt, rInt) +} + +func testAccAWSDBInstanceConfigEc2Classic(rInt int) string { + return fmt.Sprintf(` +resource "aws_db_instance" "bar" { + identifier = "foobarbaz-test-terraform-%d" + allocated_storage = 10 + engine = "mysql" + engine_version = "5.6" + instance_class = "db.m3.medium" + name = "baz" + password = "barbarbarbar" + username = "foo" + publicly_accessible = true + security_group_names = ["default"] + parameter_group_name = "default.mysql5.6" + skip_final_snapshot = true +} +`, rInt) +} + +func testAccAWSDBInstanceConfigSuppressInitialState(rInt int) string { + return fmt.Sprintf(` +resource "aws_db_instance" "bar" { + identifier = "foobarbaz-test-terraform-%d" + allocated_storage = 10 + engine = "MySQL" + instance_class = "db.t2.micro" + name = "baz" + password = "barbarbarbar" + username = "foo" + skip_final_snapshot = true +} + +data "template_file" "test" { + template = "" + vars = { + test_var = "${aws_db_instance.bar.engine_version}" + } +} +`, rInt) +} + +func testAccAWSDBInstanceConfig_MariaDB(rName string) string { + return fmt.Sprintf(` +resource "aws_db_instance" "test" { + allocated_storage = 5 + engine = "mariadb" + identifier = %q + instance_class = "db.t2.micro" + password = "avoid-plaintext-passwords" + username = "tfacctest" + skip_final_snapshot = true +} +`, rName) +} + +func testAccAWSDBInstanceConfig_EnabledCloudwatchLogsExports_Oracle(rName string) string { + return fmt.Sprintf(` +resource "aws_db_instance" "test" { + allocated_storage = 10 + enabled_cloudwatch_logs_exports = ["alert", "listener", "trace"] + engine = "oracle-se" + identifier = %q + instance_class = "db.t2.micro" + password = "avoid-plaintext-passwords" + username = "tfacctest" + skip_final_snapshot = true +} +`, rName) +} + +func testAccAWSDBInstanceConfig_ReplicateSourceDb(rName string) string { + return fmt.Sprintf(` +resource "aws_db_instance" "source" { + allocated_storage = 5 + backup_retention_period = 1 + engine = "mysql" + identifier = "%s-source" + instance_class = "db.t2.micro" + password = "avoid-plaintext-passwords" + username = "tfacctest" + skip_final_snapshot = true +} + +resource "aws_db_instance" "test" { + identifier = %q + instance_class = "${aws_db_instance.source.instance_class}" + replicate_source_db = "${aws_db_instance.source.id}" + skip_final_snapshot = true +} +`, rName, rName) +} + +func testAccAWSDBInstanceConfig_ReplicateSourceDb_AllocatedStorage(rName string, allocatedStorage int) string { + return fmt.Sprintf(` +resource "aws_db_instance" "source" { + allocated_storage = 5 + backup_retention_period = 1 + engine = "mysql" + identifier = "%s-source" + instance_class = "db.t2.micro" + password = "avoid-plaintext-passwords" + username = "tfacctest" + skip_final_snapshot = true +} + +resource "aws_db_instance" "test" { + allocated_storage = %d + identifier = %q + instance_class = "${aws_db_instance.source.instance_class}" + replicate_source_db = "${aws_db_instance.source.id}" + skip_final_snapshot = true +} +`, rName, allocatedStorage, rName) +} + +func testAccAWSDBInstanceConfig_ReplicateSourceDb_AutoMinorVersionUpgrade(rName string, autoMinorVersionUpgrade bool) string { + return fmt.Sprintf(` +resource "aws_db_instance" "source" { + allocated_storage = 5 + backup_retention_period = 1 + engine = "mysql" + identifier = "%s-source" + instance_class = "db.t2.micro" + password = "avoid-plaintext-passwords" + username = "tfacctest" + skip_final_snapshot = true +} + +resource "aws_db_instance" "test" { + auto_minor_version_upgrade = %t + identifier = %q + instance_class = "${aws_db_instance.source.instance_class}" + replicate_source_db = "${aws_db_instance.source.id}" + skip_final_snapshot = true +} +`, rName, autoMinorVersionUpgrade, rName) +} + +func testAccAWSDBInstanceConfig_ReplicateSourceDb_AvailabilityZone(rName string) string { + return fmt.Sprintf(` +data "aws_availability_zones" "available" {} + +resource "aws_db_instance" "source" { + allocated_storage = 5 + backup_retention_period = 1 + engine = "mysql" + identifier = "%s-source" + instance_class = "db.t2.micro" + password = "avoid-plaintext-passwords" + username = "tfacctest" + skip_final_snapshot = true +} + +resource "aws_db_instance" "test" { + availability_zone = "${data.aws_availability_zones.available.names[0]}" + identifier = %q + instance_class = "${aws_db_instance.source.instance_class}" + replicate_source_db = "${aws_db_instance.source.id}" + skip_final_snapshot = true +} +`, rName, rName) +} + +func testAccAWSDBInstanceConfig_ReplicateSourceDb_BackupRetentionPeriod(rName string, backupRetentionPeriod int) string { + return fmt.Sprintf(` +resource "aws_db_instance" "source" { + allocated_storage = 5 + backup_retention_period = 1 + engine = "mysql" + identifier = "%s-source" + instance_class = "db.t2.micro" + password = "avoid-plaintext-passwords" + username = "tfacctest" + skip_final_snapshot = true +} + +resource "aws_db_instance" "test" { + backup_retention_period = %d + identifier = %q + instance_class = "${aws_db_instance.source.instance_class}" + replicate_source_db = "${aws_db_instance.source.id}" + skip_final_snapshot = true +} +`, rName, backupRetentionPeriod, rName) +} + +func testAccAWSDBInstanceConfig_ReplicateSourceDb_BackupWindow(rName, backupWindow string) string { + return fmt.Sprintf(` +resource "aws_db_instance" "source" { + allocated_storage = 5 + backup_retention_period = 1 + engine = "mysql" + identifier = "%s-source" + instance_class = "db.t2.micro" + password = "avoid-plaintext-passwords" + username = "tfacctest" + skip_final_snapshot = true +} + +resource "aws_db_instance" "test" { + backup_window = %q + identifier = %q + instance_class = "${aws_db_instance.source.instance_class}" + replicate_source_db = "${aws_db_instance.source.id}" + skip_final_snapshot = true +} +`, rName, backupWindow, rName) +} + +func testAccAWSDBInstanceConfig_ReplicateSourceDb_IamDatabaseAuthenticationEnabled(rName string, iamDatabaseAuthenticationEnabled bool) string { + return fmt.Sprintf(` +resource "aws_db_instance" "source" { + allocated_storage = 5 + backup_retention_period = 1 + engine = "mysql" + identifier = "%s-source" + instance_class = "db.t2.micro" + password = "avoid-plaintext-passwords" + username = "tfacctest" + skip_final_snapshot = true +} + +resource "aws_db_instance" "test" { + iam_database_authentication_enabled = %t + identifier = %q + instance_class = "${aws_db_instance.source.instance_class}" + replicate_source_db = "${aws_db_instance.source.id}" + skip_final_snapshot = true +} +`, rName, iamDatabaseAuthenticationEnabled, rName) +} + +func testAccAWSDBInstanceConfig_ReplicateSourceDb_MaintenanceWindow(rName, maintenanceWindow string) string { + return fmt.Sprintf(` +resource "aws_db_instance" "source" { + allocated_storage = 5 + backup_retention_period = 1 + engine = "mysql" + identifier = "%s-source" + instance_class = "db.t2.micro" + password = "avoid-plaintext-passwords" + username = "tfacctest" + skip_final_snapshot = true +} + +resource "aws_db_instance" "test" { + identifier = %q + instance_class = "${aws_db_instance.source.instance_class}" + maintenance_window = %q + replicate_source_db = "${aws_db_instance.source.id}" + skip_final_snapshot = true +} +`, rName, rName, maintenanceWindow) +} + +func testAccAWSDBInstanceConfig_ReplicateSourceDb_Monitoring(rName string, monitoringInterval int) string { + return fmt.Sprintf(` +data "aws_partition" "current" {} + +resource "aws_iam_role" "test" { + name = %q + assume_role_policy = <