Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

resource/aws_rds_cluster: Add backtrack_window argument and wait for updates to complete #4524

Merged
merged 3 commits into from
May 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 60 additions & 3 deletions aws/resource_aws_rds_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ func resourceAwsRDSCluster() *schema.Resource {
Set: schema.HashString,
},

"backtrack_window": {
Type: schema.TypeInt,
Optional: true,
ValidateFunc: validation.IntBetween(0, 259200),
},

"cluster_identifier": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -329,11 +335,17 @@ func resourceAwsRDSClusterCreate(d *schema.ResourceData, meta interface{}) error
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(d.Get("engine").(string)),
SnapshotIdentifier: aws.String(d.Get("snapshot_identifier").(string)),
Tags: tags,
}

// Need to check value > 0 due to:
// InvalidParameterValue: Backtrack is not enabled for the aurora-postgresql engine.
if v, ok := d.GetOk("backtrack_window"); ok && v.(int) > 0 {
opts.BacktrackWindow = aws.Int64(int64(v.(int)))
}

if attr, ok := d.GetOk("engine_version"); ok {
opts.EngineVersion = aws.String(attr.(string))
}
Expand Down Expand Up @@ -427,6 +439,12 @@ func resourceAwsRDSClusterCreate(d *schema.ResourceData, meta interface{}) error
Tags: tags,
}

// Need to check value > 0 due to:
// InvalidParameterValue: Backtrack is not enabled for the aurora-postgresql engine.
if v, ok := d.GetOk("backtrack_window"); ok && v.(int) > 0 {
createOpts.BacktrackWindow = aws.Int64(int64(v.(int)))
}

if attr, ok := d.GetOk("port"); ok {
createOpts.Port = aws.Int64(int64(attr.(int)))
}
Expand Down Expand Up @@ -503,13 +521,19 @@ func resourceAwsRDSClusterCreate(d *schema.ResourceData, meta interface{}) error
Engine: aws.String(d.Get("engine").(string)),
MasterUsername: aws.String(d.Get("master_username").(string)),
MasterUserPassword: aws.String(d.Get("master_password").(string)),
StorageEncrypted: aws.Bool(d.Get("storage_encrypted").(bool)),
Tags: tags,
S3BucketName: aws.String(s3_bucket["bucket_name"].(string)),
S3IngestionRoleArn: aws.String(s3_bucket["ingestion_role"].(string)),
S3Prefix: aws.String(s3_bucket["bucket_prefix"].(string)),
SourceEngine: aws.String(s3_bucket["source_engine"].(string)),
SourceEngineVersion: aws.String(s3_bucket["source_engine_version"].(string)),
StorageEncrypted: aws.Bool(d.Get("storage_encrypted").(bool)),
Tags: tags,
}

// Need to check value > 0 due to:
// InvalidParameterValue: Backtrack is not enabled for the aurora-postgresql engine.
if v, ok := d.GetOk("backtrack_window"); ok && v.(int) > 0 {
createOpts.BacktrackWindow = aws.Int64(int64(v.(int)))
}

if v := d.Get("database_name"); v.(string) != "" {
Expand Down Expand Up @@ -599,6 +623,12 @@ func resourceAwsRDSClusterCreate(d *schema.ResourceData, meta interface{}) error
Tags: tags,
}

// Need to check value > 0 due to:
// InvalidParameterValue: Backtrack is not enabled for the aurora-postgresql engine.
if v, ok := d.GetOk("backtrack_window"); ok && v.(int) > 0 {
createOpts.BacktrackWindow = aws.Int64(int64(v.(int)))
}

if v := d.Get("database_name"); v.(string) != "" {
createOpts.DatabaseName = aws.String(v.(string))
}
Expand Down Expand Up @@ -751,6 +781,7 @@ func flattenAwsRdsClusterResource(d *schema.ResourceData, meta interface{}, dbc
d.Set("database_name", dbc.DatabaseName)
}

d.Set("backtrack_window", int(aws.Int64Value(dbc.BacktrackWindow)))
d.Set("cluster_identifier", dbc.DBClusterIdentifier)
d.Set("cluster_resource_id", dbc.DbClusterResourceId)
d.Set("db_subnet_group_name", dbc.DBSubnetGroup)
Expand Down Expand Up @@ -819,6 +850,11 @@ func resourceAwsRDSClusterUpdate(d *schema.ResourceData, meta interface{}) error
DBClusterIdentifier: aws.String(d.Id()),
}

if d.HasChange("backtrack_window") {
req.BacktrackWindow = aws.Int64(int64(d.Get("backtrack_window").(int)))
requestUpdate = true
}

if d.HasChange("master_password") {
req.MasterUserPassword = aws.String(d.Get("master_password").(string))
requestUpdate = true
Expand Down Expand Up @@ -876,6 +912,21 @@ func resourceAwsRDSClusterUpdate(d *schema.ResourceData, meta interface{}) error
if err != nil {
return fmt.Errorf("Failed to modify RDS Cluster (%s): %s", d.Id(), err)
}

stateConf := &resource.StateChangeConf{
Pending: resourceAwsRdsClusterUpdatePendingStates,
Target: []string{"available"},
Refresh: resourceAwsRDSClusterStateRefreshFunc(d, meta),
Timeout: d.Timeout(schema.TimeoutUpdate),
MinTimeout: 10 * time.Second,
Delay: 10 * time.Second,
}

log.Printf("[INFO] Waiting for RDS Cluster (%s) to modify", d.Id())
_, err = stateConf.WaitForState()
if err != nil {
return fmt.Errorf("error waiting for RDS Cluster (%s) to modify: %s", d.Id(), err)
}
}

if d.HasChange("iam_roles") {
Expand Down Expand Up @@ -1059,3 +1110,9 @@ var resourceAwsRdsClusterDeletePendingStates = []string{
"backing-up",
"modifying",
}

var resourceAwsRdsClusterUpdatePendingStates = []string{
"backing-up",
"modifying",
"resetting-master-credentials",
}
52 changes: 52 additions & 0 deletions aws/resource_aws_rds_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func TestAccAWSRDSCluster_basic(t *testing.T) {
Config: testAccAWSClusterConfig(rInt),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSClusterExists(resourceName, &dbCluster),
resource.TestCheckResourceAttr(resourceName, "backtrack_window", "0"),
resource.TestCheckResourceAttr(resourceName, "storage_encrypted", "false"),
resource.TestCheckResourceAttr(resourceName, "db_cluster_parameter_group_name", "default.aurora5.6"),
resource.TestCheckResourceAttrSet(resourceName, "reader_endpoint"),
Expand All @@ -44,6 +45,44 @@ func TestAccAWSRDSCluster_basic(t *testing.T) {
})
}

func TestAccAWSRDSCluster_BacktrackWindow(t *testing.T) {
var dbCluster rds.DBCluster
resourceName := "aws_rds_cluster.test"

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSClusterDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSClusterConfig_BacktrackWindow(43200),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSClusterExists(resourceName, &dbCluster),
resource.TestCheckResourceAttr(resourceName, "backtrack_window", "43200"),
),
},
{
Config: testAccAWSClusterConfig_BacktrackWindow(86400),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSClusterExists(resourceName, &dbCluster),
resource.TestCheckResourceAttr(resourceName, "backtrack_window", "86400"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{
"apply_immediately",
"cluster_identifier_prefix",
"master_password",
"skip_final_snapshot",
},
},
},
})
}

func TestAccAWSRDSCluster_namePrefix(t *testing.T) {
var v rds.DBCluster

Expand Down Expand Up @@ -535,6 +574,19 @@ resource "aws_rds_cluster" "default" {
}`, n)
}

func testAccAWSClusterConfig_BacktrackWindow(backtrackWindow int) string {
return fmt.Sprintf(`
resource "aws_rds_cluster" "test" {
apply_immediately = true
backtrack_window = %d
cluster_identifier_prefix = "tf-acc-test-"
master_password = "mustbeeightcharaters"
master_username = "test"
skip_final_snapshot = true
}
`, backtrackWindow)
}

func testAccAWSClusterConfig_namePrefix(n int) string {
return fmt.Sprintf(`
resource "aws_rds_cluster" "test" {
Expand Down
4 changes: 2 additions & 2 deletions website/docs/r/rds_cluster.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ The following arguments are supported:
* `skip_final_snapshot` - (Optional) Determines whether a final DB snapshot is created before the DB cluster is deleted. If true is specified, no DB snapshot is created. If false is specified, a DB snapshot is created before the DB cluster is deleted, using the value from `final_snapshot_identifier`. Default is `false`.
* `availability_zones` - (Optional) A list of EC2 Availability Zones that
instances in the DB cluster can be created in
* `backup_retention_period` - (Optional) The days to retain backups for. Default
1
* `backtrack_window` - (Optional) The target backtrack window, in seconds. Only available for `aurora` or `aurora-mysql` engines. To disable backtracking, set this value to `0`. Defaults to `0`. Must be between `0` and `259200` (72 hours)
* `backup_retention_period` - (Optional) The days to retain backups for. Default `1`
* `preferred_backup_window` - (Optional) The daily time range during which automated backups are created if automated backups are enabled using the BackupRetentionPeriod parameter.Time in UTC
Default: A 30-minute window selected at random from an 8-hour block of time per region. e.g. 04:00-09:00
* `preferred_maintenance_window` - (Optional) The weekly time range during which system maintenance can occur, in (UTC) e.g. wed:04:00-wed:04:30
Expand Down