Added support for `snapshot_identifier` parameter in aws_rds_cluster (#7158)

Made modifications to existing parameters to enable restoring a RDS cluster snapshot

document changes
This commit is contained in:
Kevin Crawley 2016-06-29 03:02:26 -05:00 committed by Paul Stack
parent b42c0d89e6
commit a049fb17aa
2 changed files with 151 additions and 57 deletions

View File

@ -121,13 +121,21 @@ func resourceAwsRDSCluster() *schema.Resource {
"master_username": &schema.Schema{
Type: schema.TypeString,
Required: true,
Computed: true,
Optional: true,
ForceNew: true,
},
"master_password": &schema.Schema{
Type: schema.TypeString,
Required: true,
Optional: true,
},
"snapshot_identifier": &schema.Schema{
Type: schema.TypeString,
Computed: false,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"port": &schema.Schema{
@ -191,63 +199,148 @@ func resourceAwsRDSCluster() *schema.Resource {
func resourceAwsRDSClusterCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).rdsconn
createOpts := &rds.CreateDBClusterInput{
DBClusterIdentifier: aws.String(d.Get("cluster_identifier").(string)),
Engine: aws.String("aurora"),
MasterUserPassword: aws.String(d.Get("master_password").(string)),
MasterUsername: aws.String(d.Get("master_username").(string)),
StorageEncrypted: aws.Bool(d.Get("storage_encrypted").(bool)),
if _, ok := d.GetOk("snapshot_identifier"); ok {
opts := rds.RestoreDBClusterFromSnapshotInput{
DBClusterIdentifier: aws.String(d.Get("cluster_identifier").(string)),
SnapshotIdentifier: aws.String(d.Get("snapshot_identifier").(string)),
Engine: aws.String("aurora"),
}
if attr := d.Get("availability_zones").(*schema.Set); attr.Len() > 0 {
opts.AvailabilityZones = expandStringList(attr.List())
}
if attr, ok := d.GetOk("db_subnet_group_name"); ok {
opts.DBSubnetGroupName = aws.String(attr.(string))
}
if attr, ok := d.GetOk("database_name"); ok {
opts.DatabaseName = aws.String(attr.(string))
}
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)))
}
var sgUpdate bool
if attr := d.Get("vpc_security_group_ids").(*schema.Set); attr.Len() > 0 {
sgUpdate = true
opts.VpcSecurityGroupIds = expandStringList(attr.List())
}
log.Printf("[DEBUG] RDS Cluster restore from snapshot configuration: %s", opts)
_, err := conn.RestoreDBClusterFromSnapshot(&opts)
if err != nil {
return fmt.Errorf("Error creating RDS Cluster: %s", err)
}
if sgUpdate {
log.Printf("[INFO] RDS Cluster is restoring from snapshot with default security, but custom security should be set, will now update after snapshot is restored!")
d.SetId(d.Get("cluster_identifier").(string))
log.Printf("[INFO] RDS Cluster Instance ID: %s", d.Id())
log.Println("[INFO] Waiting for RDS Cluster to be available")
stateConf := &resource.StateChangeConf{
Pending: []string{"creating", "backing-up", "modifying"},
Target: []string{"available"},
Refresh: resourceAwsRDSClusterStateRefreshFunc(d, meta),
Timeout: 5 * time.Minute,
MinTimeout: 3 * time.Second,
Delay: 30 * time.Second, // Wait 30 secs before starting
}
// Wait, catching any errors
_, err := stateConf.WaitForState()
if err != nil {
return err
}
err = resourceAwsRDSClusterInstanceUpdate(d, meta)
if err != nil {
return err
}
}
} else {
if _, ok := d.GetOk("master_password"); !ok {
return fmt.Errorf(`provider.aws: aws_rds_cluster: %s: "master_password": required field is not set`, d.Get("name").(string))
}
if _, ok := d.GetOk("master_username"); !ok {
return fmt.Errorf(`provider.aws: aws_rds_cluster: %s: "master_username": required field is not set`, d.Get("name").(string))
}
createOpts := &rds.CreateDBClusterInput{
DBClusterIdentifier: aws.String(d.Get("cluster_identifier").(string)),
Engine: aws.String("aurora"),
MasterUserPassword: aws.String(d.Get("master_password").(string)),
MasterUsername: aws.String(d.Get("master_username").(string)),
StorageEncrypted: aws.Bool(d.Get("storage_encrypted").(bool)),
}
if v := d.Get("database_name"); v.(string) != "" {
createOpts.DatabaseName = aws.String(v.(string))
}
if attr, ok := d.GetOk("port"); ok {
createOpts.Port = aws.Int64(int64(attr.(int)))
}
if attr, ok := d.GetOk("db_subnet_group_name"); ok {
createOpts.DBSubnetGroupName = aws.String(attr.(string))
}
if attr, ok := d.GetOk("parameter_group_name"); ok {
createOpts.DBClusterParameterGroupName = aws.String(attr.(string))
}
if attr, ok := d.GetOk("db_cluster_parameter_group_name"); ok {
createOpts.DBClusterParameterGroupName = aws.String(attr.(string))
}
if attr := d.Get("vpc_security_group_ids").(*schema.Set); attr.Len() > 0 {
createOpts.VpcSecurityGroupIds = expandStringList(attr.List())
}
if attr := d.Get("availability_zones").(*schema.Set); attr.Len() > 0 {
createOpts.AvailabilityZones = expandStringList(attr.List())
}
if v, ok := d.GetOk("backup_retention_period"); ok {
createOpts.BackupRetentionPeriod = aws.Int64(int64(v.(int)))
}
if v, ok := d.GetOk("preferred_backup_window"); ok {
createOpts.PreferredBackupWindow = aws.String(v.(string))
}
if v, ok := d.GetOk("preferred_maintenance_window"); ok {
createOpts.PreferredMaintenanceWindow = aws.String(v.(string))
}
log.Printf("[DEBUG] RDS Cluster create options: %s", createOpts)
resp, err := conn.CreateDBCluster(createOpts)
if err != nil {
log.Printf("[ERROR] Error creating RDS Cluster: %s", err)
return err
}
log.Printf("[DEBUG]: RDS Cluster create response: %s", resp)
}
if v := d.Get("database_name"); v.(string) != "" {
createOpts.DatabaseName = aws.String(v.(string))
}
d.SetId(d.Get("cluster_identifier").(string))
if attr, ok := d.GetOk("port"); ok {
createOpts.Port = aws.Int64(int64(attr.(int)))
}
log.Printf("[INFO] RDS Cluster ID: %s", d.Id())
if attr, ok := d.GetOk("db_subnet_group_name"); ok {
createOpts.DBSubnetGroupName = aws.String(attr.(string))
}
log.Println(
"[INFO] Waiting for RDS Cluster to be available")
if attr, ok := d.GetOk("parameter_group_name"); ok {
createOpts.DBClusterParameterGroupName = aws.String(attr.(string))
}
if attr, ok := d.GetOk("db_cluster_parameter_group_name"); ok {
createOpts.DBClusterParameterGroupName = aws.String(attr.(string))
}
if attr := d.Get("vpc_security_group_ids").(*schema.Set); attr.Len() > 0 {
createOpts.VpcSecurityGroupIds = expandStringList(attr.List())
}
if attr := d.Get("availability_zones").(*schema.Set); attr.Len() > 0 {
createOpts.AvailabilityZones = expandStringList(attr.List())
}
if v, ok := d.GetOk("backup_retention_period"); ok {
createOpts.BackupRetentionPeriod = aws.Int64(int64(v.(int)))
}
if v, ok := d.GetOk("preferred_backup_window"); ok {
createOpts.PreferredBackupWindow = aws.String(v.(string))
}
if v, ok := d.GetOk("preferred_maintenance_window"); ok {
createOpts.PreferredMaintenanceWindow = aws.String(v.(string))
}
log.Printf("[DEBUG] RDS Cluster create options: %s", createOpts)
resp, err := conn.CreateDBCluster(createOpts)
if err != nil {
log.Printf("[ERROR] Error creating RDS Cluster: %s", err)
return err
}
log.Printf("[DEBUG]: Cluster create response: %s", resp)
d.SetId(*resp.DBCluster.DBClusterIdentifier)
stateConf := &resource.StateChangeConf{
Pending: []string{"creating", "backing-up", "modifying"},
Target: []string{"available"},
@ -257,7 +350,7 @@ func resourceAwsRDSClusterCreate(d *schema.ResourceData, meta interface{}) error
}
// Wait, catching any errors
_, err = stateConf.WaitForState()
_, err := stateConf.WaitForState()
if err != nil {
return fmt.Errorf("[WARN] Error waiting for RDS Cluster state to be \"available\": %s", err)
}

View File

@ -55,9 +55,9 @@ string.
* `database_name` - (Optional) The name for your database of up to 8 alpha-numeric
characters. If you do not provide a name, Amazon RDS will not create a
database in the DB cluster you are creating
* `master_password` - (Required) Password for the master DB user. Note that this may
* `master_password` - (Required unless a `snapshot_identifier` is provided) Password for the master DB user. Note that this may
show up in logs, and it will be stored in the state file
* `master_username` - (Required) Username for the master DB user
* `master_username` - (Required unless a `snapshot_identifier` is provided) Username for the master DB user
* `final_snapshot_identifier` - (Optional) The name of your final DB snapshot
when this DB cluster is deleted. If omitted, no final snapshot will be
made.
@ -72,6 +72,7 @@ Default: A 30-minute window selected at random from an 8-hour block of time per
* `port` - (Optional) The port on which the DB accepts connections
* `vpc_security_group_ids` - (Optional) List of VPC security groups to associate
with the Cluster
* `snapshot_identifier` - (Optional) Specifies whether or not to create this cluster from a snapshot. This correlates to the snapshot ID you'd find in the RDS console, e.g: rds:production-2015-06-26-06-05.
* `storage_encrypted` - (Optional) Specifies whether the DB cluster is encrypted. The default is `false` if not specified.
* `apply_immediately` - (Optional) Specifies whether any cluster modifications
are applied immediately, or during the next maintenance window. Default is