diff --git a/builtin/providers/aws/resource_aws_rds_cluster.go b/builtin/providers/aws/resource_aws_rds_cluster.go index 0e3d9339a..897fe31ed 100644 --- a/builtin/providers/aws/resource_aws_rds_cluster.go +++ b/builtin/providers/aws/resource_aws_rds_cluster.go @@ -3,6 +3,7 @@ package aws import ( "fmt" "log" + "regexp" "time" "github.com/aws/aws-sdk-go/aws" @@ -69,6 +70,25 @@ func resourceAwsRDSCluster() *schema.Resource { Computed: true, }, + "final_snapshot_identifier": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ValidateFunc: func(v interface{}, k string) (ws []string, es []error) { + value := v.(string) + if !regexp.MustCompile(`^[0-9A-Za-z-]+$`).MatchString(value) { + es = append(es, fmt.Errorf( + "only alphanumeric characters and hyphens allowed in %q", k)) + } + if regexp.MustCompile(`--`).MatchString(value) { + es = append(es, fmt.Errorf("%q cannot contain two consecutive hyphens", k)) + } + if regexp.MustCompile(`-$`).MatchString(value) { + es = append(es, fmt.Errorf("%q cannot end in a hyphen", k)) + } + return + }, + }, + "master_username": &schema.Schema{ Type: schema.TypeString, Required: true, @@ -167,7 +187,6 @@ func resourceAwsRDSClusterRead(d *schema.ResourceData, meta interface{}) error { resp, err := conn.DescribeDBClusters(&rds.DescribeDBClustersInput{ DBClusterIdentifier: aws.String(d.Id()), - // final snapshot identifier }) if err != nil { @@ -256,11 +275,20 @@ func resourceAwsRDSClusterDelete(d *schema.ResourceData, meta interface{}) error conn := meta.(*AWSClient).rdsconn log.Printf("[DEBUG] Destroying RDS Cluster (%s)", d.Id()) - _, err := conn.DeleteDBCluster(&rds.DeleteDBClusterInput{ + deleteOpts := rds.DeleteDBClusterInput{ DBClusterIdentifier: aws.String(d.Id()), - SkipFinalSnapshot: aws.Bool(true), - // final snapshot identifier - }) + } + + finalSnapshot := d.Get("final_snapshot_identifier").(string) + if finalSnapshot == "" { + deleteOpts.SkipFinalSnapshot = aws.Bool(true) + } else { + deleteOpts.FinalDBSnapshotIdentifier = aws.String(finalSnapshot) + deleteOpts.SkipFinalSnapshot = aws.Bool(false) + } + + log.Printf("[DEBUG] RDS Cluster delete options: %s", deleteOpts) + _, err := conn.DeleteDBCluster(&deleteOpts) stateConf := &resource.StateChangeConf{ Pending: []string{"deleting", "backing-up", "modifying"}, diff --git a/builtin/providers/aws/resource_aws_rds_cluster_instance_test.go b/builtin/providers/aws/resource_aws_rds_cluster_instance_test.go index aff6aa786..f923c1712 100644 --- a/builtin/providers/aws/resource_aws_rds_cluster_instance_test.go +++ b/builtin/providers/aws/resource_aws_rds_cluster_instance_test.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/terraform/terraform" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/rds" ) @@ -54,7 +55,13 @@ func testAccCheckAWSClusterInstanceDestroy(s *terraform.State) error { } } - //check for an expected "Cluster not found" type error + // Return nil if the Cluster Instance is already destroyed + if awsErr, ok := err.(awserr.Error); ok { + if awsErr.Code() == "DBInstanceNotFound" { + return nil + } + } + return err } diff --git a/builtin/providers/aws/resource_aws_rds_cluster_test.go b/builtin/providers/aws/resource_aws_rds_cluster_test.go index 18ffa7bf2..2fd768949 100644 --- a/builtin/providers/aws/resource_aws_rds_cluster_test.go +++ b/builtin/providers/aws/resource_aws_rds_cluster_test.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform/terraform" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/rds" ) @@ -52,9 +53,14 @@ func testAccCheckAWSClusterDestroy(s *terraform.State) error { } } - // check for an expected "Cluster not found" type error - return err + // Return nil if the cluster is already destroyed + if awsErr, ok := err.(awserr.Error); ok { + if awsErr.Code() == "DBClusterNotFound" { + return nil + } + } + return err } return nil diff --git a/website/source/docs/providers/aws/r/rds_cluster.html.markdown b/website/source/docs/providers/aws/r/rds_cluster.html.markdown index 64870b889..c45814f46 100644 --- a/website/source/docs/providers/aws/r/rds_cluster.html.markdown +++ b/website/source/docs/providers/aws/r/rds_cluster.html.markdown @@ -45,6 +45,9 @@ string. * `master_password` - (Required) 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 +* `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. * `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 diff --git a/website/source/docs/providers/aws/r/rds_cluster_instance.html.markdown b/website/source/docs/providers/aws/r/rds_cluster_instance.html.markdown index 1571beab7..76792cc51 100644 --- a/website/source/docs/providers/aws/r/rds_cluster_instance.html.markdown +++ b/website/source/docs/providers/aws/r/rds_cluster_instance.html.markdown @@ -47,8 +47,8 @@ the [AWS official documentation](http://docs.aws.amazon.com/AmazonRDS/latest/Com The following arguments are supported: -* `identifier` - (Required) The Instance Identifier. Must be a lower case -string. +* `identifier` - (Optional) The Instance Identifier. Must be a lower case +string. If omited, a unique identifier will be generated. * `cluster_identifier` - (Required) The Cluster Identifier for this Instance to join. Must be a lower case string.