func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).rdsconn tags := tagsFromMapRDS(d.Get("tags").(map[string]interface{})) identifier := d.Get("identifier").(string) // Generate a unique ID for the user if identifier == "" { identifier = resource.PrefixedUniqueId("tf-") // SQL Server identifier size is max 15 chars, so truncate if engine := d.Get("engine").(string); engine != "" { if strings.Contains(strings.ToLower(engine), "sqlserver") { identifier = identifier[:15] } } d.Set("identifier", identifier) } if v, ok := d.GetOk("replicate_source_db"); ok { opts := rds.CreateDBInstanceReadReplicaInput{ SourceDBInstanceIdentifier: aws.String(v.(string)), CopyTagsToSnapshot: aws.Bool(d.Get("copy_tags_to_snapshot").(bool)), DBInstanceClass: aws.String(d.Get("instance_class").(string)), DBInstanceIdentifier: aws.String(identifier), Tags: tags, } if attr, ok := d.GetOk("iops"); ok { opts.Iops = aws.Int64(int64(attr.(int))) } if attr, ok := d.GetOk("port"); ok { opts.Port = aws.Int64(int64(attr.(int))) } 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("publicly_accessible"); ok { opts.PubliclyAccessible = aws.Bool(attr.(bool)) } if attr, ok := d.GetOk("db_subnet_group_name"); ok { opts.DBSubnetGroupName = aws.String(attr.(string)) } if attr, ok := d.GetOk("monitoring_role_arn"); ok { opts.MonitoringRoleArn = aws.String(attr.(string)) } if attr, ok := d.GetOk("monitoring_interval"); ok { opts.MonitoringInterval = aws.Int64(int64(attr.(int))) } if attr, ok := d.GetOk("option_group_name"); ok { opts.OptionGroupName = aws.String(attr.(string)) } log.Printf("[DEBUG] DB Instance Replica create configuration: %#v", opts) _, err := conn.CreateDBInstanceReadReplica(&opts) if err != nil { return fmt.Errorf("Error creating DB Instance: %s", err) } } else if _, ok := d.GetOk("snapshot_identifier"); ok { opts := rds.RestoreDBInstanceFromDBSnapshotInput{ DBInstanceClass: aws.String(d.Get("instance_class").(string)), DBInstanceIdentifier: aws.String(d.Get("identifier").(string)), DBSnapshotIdentifier: aws.String(d.Get("snapshot_identifier").(string)), AutoMinorVersionUpgrade: aws.Bool(d.Get("auto_minor_version_upgrade").(bool)), Tags: tags, CopyTagsToSnapshot: aws.Bool(d.Get("copy_tags_to_snapshot").(bool)), } if attr, ok := d.GetOk("availability_zone"); ok { opts.AvailabilityZone = aws.String(attr.(string)) } if attr, ok := d.GetOk("db_subnet_group_name"); ok { opts.DBSubnetGroupName = aws.String(attr.(string)) } if attr, ok := d.GetOk("engine"); ok { opts.Engine = aws.String(attr.(string)) } if attr, ok := d.GetOk("iops"); ok { opts.Iops = aws.Int64(int64(attr.(int))) } if attr, ok := d.GetOk("license_model"); ok { opts.LicenseModel = 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("port"); ok { opts.Port = aws.Int64(int64(attr.(int))) } if attr, ok := d.GetOk("publicly_accessible"); ok { opts.PubliclyAccessible = aws.Bool(attr.(bool)) } if attr, ok := d.GetOk("tde_credential_arn"); ok { opts.TdeCredentialArn = aws.String(attr.(string)) } if attr, ok := d.GetOk("storage_type"); ok { opts.StorageType = aws.String(attr.(string)) } log.Printf("[DEBUG] DB Instance restore from snapshot configuration: %s", opts) _, err := conn.RestoreDBInstanceFromDBSnapshot(&opts) if err != nil { return fmt.Errorf("Error creating DB Instance: %s", err) } var sgUpdate bool if attr := d.Get("vpc_security_group_ids").(*schema.Set); attr.Len() > 0 { sgUpdate = true } if attr := d.Get("security_group_names").(*schema.Set); attr.Len() > 0 { sgUpdate = true } if sgUpdate { log.Printf("[INFO] DB is restoring from snapshot with default security, but custom security should be set, will now update after snapshot is restored!") // wait for instance to get up and then modify security 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: []string{"creating", "backing-up", "modifying", "resetting-master-credentials", "maintenance", "renaming", "rebooting", "upgrading"}, Target: []string{"available"}, Refresh: resourceAwsDbInstanceStateRefreshFunc(d, meta), Timeout: 40 * time.Minute, 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)) } if _, ok := d.GetOk("engine"); !ok { return fmt.Errorf(`provider.aws: aws_db_instance: %s: "engine": required field is not set`, d.Get("name").(string)) } if _, ok := d.GetOk("password"); !ok { return fmt.Errorf(`provider.aws: aws_db_instance: %s: "password": required field is not set`, d.Get("name").(string)) } if _, ok := d.GetOk("username"); !ok { return fmt.Errorf(`provider.aws: aws_db_instance: %s: "username": required field is not set`, d.Get("name").(string)) } opts := rds.CreateDBInstanceInput{ AllocatedStorage: aws.Int64(int64(d.Get("allocated_storage").(int))), DBName: aws.String(d.Get("name").(string)), DBInstanceClass: aws.String(d.Get("instance_class").(string)), DBInstanceIdentifier: aws.String(d.Get("identifier").(string)), MasterUsername: aws.String(d.Get("username").(string)), MasterUserPassword: aws.String(d.Get("password").(string)), Engine: aws.String(d.Get("engine").(string)), EngineVersion: aws.String(d.Get("engine_version").(string)), StorageEncrypted: aws.Bool(d.Get("storage_encrypted").(bool)), AutoMinorVersionUpgrade: aws.Bool(d.Get("auto_minor_version_upgrade").(bool)), Tags: tags, CopyTagsToSnapshot: aws.Bool(d.Get("copy_tags_to_snapshot").(bool)), } attr := d.Get("backup_retention_period") opts.BackupRetentionPeriod = aws.Int64(int64(attr.(int))) if attr, ok := d.GetOk("multi_az"); ok { opts.MultiAZ = aws.Bool(attr.(bool)) } if attr, ok := d.GetOk("character_set_name"); ok { opts.CharacterSetName = aws.String(attr.(string)) } if attr, ok := d.GetOk("maintenance_window"); ok { opts.PreferredMaintenanceWindow = aws.String(attr.(string)) } if attr, ok := d.GetOk("backup_window"); ok { opts.PreferredBackupWindow = aws.String(attr.(string)) } if attr, ok := d.GetOk("license_model"); ok { opts.LicenseModel = aws.String(attr.(string)) } if attr, ok := d.GetOk("parameter_group_name"); ok { opts.DBParameterGroupName = aws.String(attr.(string)) } 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))) } opts.VpcSecurityGroupIds = s } 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))) } opts.DBSecurityGroups = s } if attr, ok := d.GetOk("storage_type"); ok { opts.StorageType = aws.String(attr.(string)) } if attr, ok := d.GetOk("db_subnet_group_name"); ok { opts.DBSubnetGroupName = aws.String(attr.(string)) } if attr, ok := d.GetOk("iops"); ok { opts.Iops = aws.Int64(int64(attr.(int))) } if attr, ok := d.GetOk("port"); ok { opts.Port = aws.Int64(int64(attr.(int))) } if attr, ok := d.GetOk("availability_zone"); ok { opts.AvailabilityZone = aws.String(attr.(string)) } if attr, ok := d.GetOk("publicly_accessible"); ok { opts.PubliclyAccessible = aws.Bool(attr.(bool)) } if attr, ok := d.GetOk("monitoring_role_arn"); ok { opts.MonitoringRoleArn = aws.String(attr.(string)) } if attr, ok := d.GetOk("monitoring_interval"); ok { opts.MonitoringInterval = aws.Int64(int64(attr.(int))) } if attr, ok := d.GetOk("option_group_name"); ok { opts.OptionGroupName = aws.String(attr.(string)) } if attr, ok := d.GetOk("kms_key_id"); ok { opts.KmsKeyId = aws.String(attr.(string)) } log.Printf("[DEBUG] DB Instance create configuration: %#v", opts) var err error err = resource.Retry(5*time.Minute, func() *resource.RetryError { _, err = conn.CreateDBInstance(&opts) if err != nil { if awsErr, ok := err.(awserr.Error); ok { if awsErr.Code() == "InvalidParameterValue" && strings.Contains(awsErr.Message(), "ENHANCED_MONITORING") { return resource.RetryableError(awsErr) } } return resource.NonRetryableError(err) } return nil }) if err != nil { return fmt.Errorf("Error creating DB Instance: %s", err) } } 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: []string{"creating", "backing-up", "modifying", "resetting-master-credentials", "maintenance", "renaming", "rebooting", "upgrading"}, Target: []string{"available"}, Refresh: resourceAwsDbInstanceStateRefreshFunc(d, meta), Timeout: 40 * time.Minute, 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 } return resourceAwsDbInstanceRead(d, meta) }
Context("when has BackupRetentionPeriod", func() { BeforeEach(func() { dbInstanceDetails.BackupRetentionPeriod = 7 createDBInstanceInput.BackupRetentionPeriod = aws.Int64(7) }) It("does not return error", func() { err := rdsDBInstance.Create(dbInstanceIdentifier, dbInstanceDetails) Expect(err).ToNot(HaveOccurred()) }) }) Context("when has CharacterSetName", func() { BeforeEach(func() { dbInstanceDetails.CharacterSetName = "test-characterset-name" createDBInstanceInput.CharacterSetName = aws.String("test-characterset-name") }) It("does not return error", func() { err := rdsDBInstance.Create(dbInstanceIdentifier, dbInstanceDetails) Expect(err).ToNot(HaveOccurred()) }) }) Context("when has CopyTagsToSnapshot", func() { BeforeEach(func() { dbInstanceDetails.CopyTagsToSnapshot = true createDBInstanceInput.CopyTagsToSnapshot = aws.Bool(true) }) It("does not return error", func() {