Merge pull request #3757 from stack72/f-aws-rds-cluster-backup
provider/aws: RDS Cluster additions
This commit is contained in:
commit
cb52e23226
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
@ -122,6 +123,38 @@ func resourceAwsRDSCluster() *schema.Resource {
|
||||||
Elem: &schema.Schema{Type: schema.TypeString},
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
Set: schema.HashString,
|
Set: schema.HashString,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"preferred_backup_window": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"preferred_maintenance_window": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
StateFunc: func(val interface{}) string {
|
||||||
|
if val == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return strings.ToLower(val.(string))
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
"backup_retention_period": &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Default: 1,
|
||||||
|
ValidateFunc: func(v interface{}, k string) (ws []string, es []error) {
|
||||||
|
value := v.(int)
|
||||||
|
if value > 35 {
|
||||||
|
es = append(es, fmt.Errorf(
|
||||||
|
"backup retention period cannot be more than 35 days"))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,6 +189,18 @@ func resourceAwsRDSClusterCreate(d *schema.ResourceData, meta interface{}) error
|
||||||
createOpts.AvailabilityZones = expandStringList(attr.List())
|
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)
|
log.Printf("[DEBUG] RDS Cluster create options: %s", createOpts)
|
||||||
resp, err := conn.CreateDBCluster(createOpts)
|
resp, err := conn.CreateDBCluster(createOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -223,6 +268,9 @@ func resourceAwsRDSClusterRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
d.Set("engine", dbc.Engine)
|
d.Set("engine", dbc.Engine)
|
||||||
d.Set("master_username", dbc.MasterUsername)
|
d.Set("master_username", dbc.MasterUsername)
|
||||||
d.Set("port", dbc.Port)
|
d.Set("port", dbc.Port)
|
||||||
|
d.Set("backup_retention_period", dbc.BackupRetentionPeriod)
|
||||||
|
d.Set("preferred_backup_window", dbc.PreferredBackupWindow)
|
||||||
|
d.Set("preferred_maintenance_window", dbc.PreferredMaintenanceWindow)
|
||||||
|
|
||||||
var vpcg []string
|
var vpcg []string
|
||||||
for _, g := range dbc.VpcSecurityGroups {
|
for _, g := range dbc.VpcSecurityGroups {
|
||||||
|
@ -263,6 +311,18 @@ func resourceAwsRDSClusterUpdate(d *schema.ResourceData, meta interface{}) error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if d.HasChange("preferred_backup_window") {
|
||||||
|
req.PreferredBackupWindow = aws.String(d.Get("preferred_backup_window").(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.HasChange("preferred_maintenance_window") {
|
||||||
|
req.PreferredMaintenanceWindow = aws.String(d.Get("preferred_maintenance_window").(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.HasChange("backup_retention_period") {
|
||||||
|
req.BackupRetentionPeriod = aws.Int64(int64(d.Get("backup_retention_period").(int)))
|
||||||
|
}
|
||||||
|
|
||||||
_, err := conn.ModifyDBCluster(req)
|
_, err := conn.ModifyDBCluster(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("[WARN] Error modifying RDS Cluster (%s): %s", d.Id(), err)
|
return fmt.Errorf("[WARN] Error modifying RDS Cluster (%s): %s", d.Id(), err)
|
||||||
|
|
|
@ -17,13 +17,16 @@ import (
|
||||||
func TestAccAWSRDSCluster_basic(t *testing.T) {
|
func TestAccAWSRDSCluster_basic(t *testing.T) {
|
||||||
var v rds.DBCluster
|
var v rds.DBCluster
|
||||||
|
|
||||||
|
ri := rand.New(rand.NewSource(time.Now().UnixNano())).Int()
|
||||||
|
config := fmt.Sprintf(testAccAWSClusterConfig, ri)
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
resource.Test(t, resource.TestCase{
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
Providers: testAccProviders,
|
Providers: testAccProviders,
|
||||||
CheckDestroy: testAccCheckAWSClusterDestroy,
|
CheckDestroy: testAccCheckAWSClusterDestroy,
|
||||||
Steps: []resource.TestStep{
|
Steps: []resource.TestStep{
|
||||||
resource.TestStep{
|
resource.TestStep{
|
||||||
Config: testAccAWSClusterConfig,
|
Config: config,
|
||||||
Check: resource.ComposeTestCheckFunc(
|
Check: resource.ComposeTestCheckFunc(
|
||||||
testAccCheckAWSClusterExists("aws_rds_cluster.default", &v),
|
testAccCheckAWSClusterExists("aws_rds_cluster.default", &v),
|
||||||
),
|
),
|
||||||
|
@ -32,6 +35,47 @@ func TestAccAWSRDSCluster_basic(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAccAWSRDSCluster_backupsUpdate(t *testing.T) {
|
||||||
|
var v rds.DBCluster
|
||||||
|
|
||||||
|
ri := rand.New(rand.NewSource(time.Now().UnixNano())).Int()
|
||||||
|
preConfig := fmt.Sprintf(testAccAWSClusterConfig_backups, ri)
|
||||||
|
postConfig := fmt.Sprintf(testAccAWSClusterConfig_backupsUpdate, ri)
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSClusterDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: preConfig,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSClusterExists("aws_rds_cluster.default", &v),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_rds_cluster.default", "preferred_backup_window", "07:00-09:00"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_rds_cluster.default", "backup_retention_period", "5"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_rds_cluster.default", "preferred_maintenance_window", "tue:04:00-tue:04:30"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
|
||||||
|
resource.TestStep{
|
||||||
|
Config: postConfig,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSClusterExists("aws_rds_cluster.default", &v),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_rds_cluster.default", "preferred_backup_window", "03:00-09:00"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_rds_cluster.default", "backup_retention_period", "10"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_rds_cluster.default", "preferred_maintenance_window", "wed:01:00-wed:01:30"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func testAccCheckAWSClusterDestroy(s *terraform.State) error {
|
func testAccCheckAWSClusterDestroy(s *terraform.State) error {
|
||||||
for _, rs := range s.RootModule().Resources {
|
for _, rs := range s.RootModule().Resources {
|
||||||
if rs.Type != "aws_rds_cluster" {
|
if rs.Type != "aws_rds_cluster" {
|
||||||
|
@ -97,12 +141,36 @@ func testAccCheckAWSClusterExists(n string, v *rds.DBCluster) resource.TestCheck
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add some random to the name, to avoid collision
|
var testAccAWSClusterConfig = `
|
||||||
var testAccAWSClusterConfig = fmt.Sprintf(`
|
|
||||||
resource "aws_rds_cluster" "default" {
|
resource "aws_rds_cluster" "default" {
|
||||||
cluster_identifier = "tf-aurora-cluster-%d"
|
cluster_identifier = "tf-aurora-cluster-%d"
|
||||||
availability_zones = ["us-west-2a","us-west-2b","us-west-2c"]
|
availability_zones = ["us-west-2a","us-west-2b","us-west-2c"]
|
||||||
database_name = "mydb"
|
database_name = "mydb"
|
||||||
master_username = "foo"
|
master_username = "foo"
|
||||||
master_password = "mustbeeightcharaters"
|
master_password = "mustbeeightcharaters"
|
||||||
}`, rand.New(rand.NewSource(time.Now().UnixNano())).Int())
|
}`
|
||||||
|
|
||||||
|
var testAccAWSClusterConfig_backups = `
|
||||||
|
resource "aws_rds_cluster" "default" {
|
||||||
|
cluster_identifier = "tf-aurora-cluster-%d"
|
||||||
|
availability_zones = ["us-west-2a","us-west-2b","us-west-2c"]
|
||||||
|
database_name = "mydb"
|
||||||
|
master_username = "foo"
|
||||||
|
master_password = "mustbeeightcharaters"
|
||||||
|
backup_retention_period = 5
|
||||||
|
preferred_backup_window = "07:00-09:00"
|
||||||
|
preferred_maintenance_window = "tue:04:00-tue:04:30"
|
||||||
|
}`
|
||||||
|
|
||||||
|
var testAccAWSClusterConfig_backupsUpdate = `
|
||||||
|
resource "aws_rds_cluster" "default" {
|
||||||
|
cluster_identifier = "tf-aurora-cluster-%d"
|
||||||
|
availability_zones = ["us-west-2a","us-west-2b","us-west-2c"]
|
||||||
|
database_name = "mydb"
|
||||||
|
master_username = "foo"
|
||||||
|
master_password = "mustbeeightcharaters"
|
||||||
|
backup_retention_period = 10
|
||||||
|
preferred_backup_window = "03:00-09:00"
|
||||||
|
preferred_maintenance_window = "wed:01:00-wed:01:30"
|
||||||
|
apply_immediately = true
|
||||||
|
}`
|
||||||
|
|
|
@ -24,6 +24,8 @@ resource "aws_rds_cluster" "default" {
|
||||||
database_name = "mydb"
|
database_name = "mydb"
|
||||||
master_username = "foo"
|
master_username = "foo"
|
||||||
master_password = "bar"
|
master_password = "bar"
|
||||||
|
backup_retention_period = 5
|
||||||
|
preferred_backup_window = "07:00-09:00"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -52,6 +54,9 @@ string.
|
||||||
instances in the DB cluster can be created in
|
instances in the DB cluster can be created in
|
||||||
* `backup_retention_period` - (Optional) The days to retain backups for. Default
|
* `backup_retention_period` - (Optional) The days to retain backups for. Default
|
||||||
1
|
1
|
||||||
|
* `preferred_backup_window` - (Optional) The daily time range during which automated backups are created if automated backups are enabled using the BackupRetentionPeriod parameter.
|
||||||
|
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
|
||||||
* `port` - (Optional) The port on which the DB accepts connections
|
* `port` - (Optional) The port on which the DB accepts connections
|
||||||
* `vpc_security_group_ids` - (Optional) List of VPC security groups to associate
|
* `vpc_security_group_ids` - (Optional) List of VPC security groups to associate
|
||||||
with the Cluster
|
with the Cluster
|
||||||
|
@ -70,7 +75,8 @@ The following attributes are exported:
|
||||||
* `allocated_storage` - The amount of allocated storage
|
* `allocated_storage` - The amount of allocated storage
|
||||||
* `availability_zones` - The availability zone of the instance
|
* `availability_zones` - The availability zone of the instance
|
||||||
* `backup_retention_period` - The backup retention period
|
* `backup_retention_period` - The backup retention period
|
||||||
* `backup_window` - The backup window
|
* `preferred_backup_window` - The backup window
|
||||||
|
* `preferred_maintenance_window` - The maintenance window
|
||||||
* `endpoint` - The primary, writeable connection endpoint
|
* `endpoint` - The primary, writeable connection endpoint
|
||||||
* `engine` - The database engine
|
* `engine` - The database engine
|
||||||
* `engine_version` - The database engine version
|
* `engine_version` - The database engine version
|
||||||
|
@ -80,6 +86,7 @@ The following attributes are exported:
|
||||||
* `status` - The RDS instance status
|
* `status` - The RDS instance status
|
||||||
* `username` - The master username for the database
|
* `username` - The master username for the database
|
||||||
* `storage_encrypted` - Specifies whether the DB instance is encrypted
|
* `storage_encrypted` - Specifies whether the DB instance is encrypted
|
||||||
|
* `preferred_backup_window` - The daily time range during which the backups happen
|
||||||
|
|
||||||
[1]: http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.Replication.html
|
[1]: http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.Replication.html
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue