From de16b10555be979f4edc13e4ed39992d24a76fcb Mon Sep 17 00:00:00 2001 From: Rob Costanzo Date: Wed, 22 Oct 2014 14:22:30 -0700 Subject: [PATCH 1/5] Added new aws_db_parameter_group resource for creating RDS DB Parameter Groups. Added plumbing to allow an optional DBParameterGroupName to be passed when creating an RDS DB instance. --- builtin/providers/aws/provider.go | 1 + .../providers/aws/resource_aws_db_instance.go | 7 + .../aws/resource_aws_db_instance_test.go | 3 + .../aws/resource_aws_db_parameter_group.go | 176 ++++++++++++++ .../resource_aws_db_parameter_group_test.go | 218 ++++++++++++++++++ builtin/providers/aws/structure.go | 42 ++++ builtin/providers/aws/structure_test.go | 65 ++++++ .../providers/aws/r/db_instance.html.markdown | 2 + .../aws/r/db_parameter_group.html.markdown | 52 +++++ website/source/layouts/aws.erb | 4 + 10 files changed, 570 insertions(+) create mode 100644 builtin/providers/aws/resource_aws_db_parameter_group.go create mode 100644 builtin/providers/aws/resource_aws_db_parameter_group_test.go create mode 100644 website/source/docs/providers/aws/r/db_parameter_group.html.markdown diff --git a/builtin/providers/aws/provider.go b/builtin/providers/aws/provider.go index 54db9b4d69..569229ea17 100644 --- a/builtin/providers/aws/provider.go +++ b/builtin/providers/aws/provider.go @@ -50,6 +50,7 @@ func Provider() *schema.Provider { "aws_security_group": resourceAwsSecurityGroup(), "aws_db_subnet_group": resourceAwsDbSubnetGroup(), "aws_vpc": resourceAwsVpc(), + "aws_db_parameter_group": resourceAwsDbParameterGroup(), }, } } diff --git a/builtin/providers/aws/resource_aws_db_instance.go b/builtin/providers/aws/resource_aws_db_instance.go index 6c769a7a7d..49e6be5372 100644 --- a/builtin/providers/aws/resource_aws_db_instance.go +++ b/builtin/providers/aws/resource_aws_db_instance.go @@ -79,6 +79,10 @@ func resource_aws_db_instance_create( opts.DBSubnetGroupName = attr } + if attr = rs.Attributes["parameter_group_name"]; attr != "" { + opts.DBParameterGroupName = attr + } + if err != nil { return nil, fmt.Errorf("Error parsing configuration: %s", err) } @@ -227,6 +231,7 @@ func resource_aws_db_instance_diff( "vpc_security_group_ids": diff.AttrTypeCreate, "security_group_names": diff.AttrTypeCreate, "db_subnet_group_name": diff.AttrTypeCreate, + "parameter_group_name": diff.AttrTypeCreate, "skip_final_snapshot": diff.AttrTypeUpdate, "final_snapshot_identifier": diff.AttrTypeUpdate, }, @@ -270,6 +275,7 @@ func resource_aws_db_instance_update_state( s.Attributes["status"] = v.DBInstanceStatus s.Attributes["username"] = v.MasterUsername s.Attributes["db_subnet_group_name"] = v.DBSubnetGroup.Name + s.Attributes["parameter_group_name"] = v.DBParameterGroupName // Flatten our group values toFlatten := make(map[string]interface{}) @@ -340,6 +346,7 @@ func resource_aws_db_instance_validation() *config.Validator { "skip_final_snapshot", "security_group_names.*", "db_subnet_group_name", + "parameter_group_name", }, } } diff --git a/builtin/providers/aws/resource_aws_db_instance_test.go b/builtin/providers/aws/resource_aws_db_instance_test.go index 05073fe93b..ba6eebd664 100644 --- a/builtin/providers/aws/resource_aws_db_instance_test.go +++ b/builtin/providers/aws/resource_aws_db_instance_test.go @@ -43,6 +43,8 @@ func TestAccAWSDBInstance(t *testing.T) { "aws_db_instance.bar", "skip_final_snapshot", "true"), resource.TestCheckResourceAttr( "aws_db_instance.bar", "security_group_names.0", "secfoobarbaz-test-terraform"), + resource.TestCheckResourceAttr( + "aws_db_instance.bar", "parameter_group_name", "default.mysql5.6"), ), }, }, @@ -160,5 +162,6 @@ resource "aws_db_instance" "bar" { skip_final_snapshot = true security_group_names = ["${aws_db_security_group.bar.name}"] + parameter_group_name = "default.mysql5.6" } ` diff --git a/builtin/providers/aws/resource_aws_db_parameter_group.go b/builtin/providers/aws/resource_aws_db_parameter_group.go new file mode 100644 index 0000000000..bb2588c989 --- /dev/null +++ b/builtin/providers/aws/resource_aws_db_parameter_group.go @@ -0,0 +1,176 @@ +package aws + +import ( + "fmt" + "log" + "time" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + "github.com/mitchellh/goamz/rds" +) + +func resourceAwsDbParameterGroup() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsDbParameterGroupCreate, + Read: resourceAwsDbParameterGroupRead, + Update: nil, + Delete: resourceAwsDbParameterGroupDelete, + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + ForceNew: true, + Required: true, + }, + "family": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "description": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "parameter": &schema.Schema{ + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "apply_method": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "value": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + }, + } +} + +func resourceAwsDbParameterGroupCreate(d *schema.ResourceData, meta interface{}) error { + p := meta.(*ResourceProvider) + rdsconn := p.rdsconn + + createOpts := rds.CreateDBParameterGroup{ + DBParameterGroupName: d.Get("name").(string), + DBParameterGroupFamily: d.Get("family").(string), + Description: d.Get("description").(string), + } + + log.Printf("[DEBUG] Create DB Parameter Group: %#v", createOpts) + _, err := rdsconn.CreateDBParameterGroup(&createOpts) + if err != nil { + return fmt.Errorf("Error creating DB Parameter Group: %s", err) + } + + d.SetId(createOpts.DBParameterGroupName) + log.Printf("[INFO] DB Parameter Group ID: %s", d.Id()) + + if d.Get("parameter") != "" { + // Expand the "parameter" set to goamz compat []rds.Parameter + parameters, err := expandParameters(d.Get("parameter").([]interface{})) + if err != nil { + return err + } + + modifyOpts := rds.ModifyDBParameterGroup{ + DBParameterGroupName: d.Get("name").(string), + Parameters: parameters, + } + + log.Printf("[DEBUG] Modify DB Parameter Group: %#v", modifyOpts) + _, err = rdsconn.ModifyDBParameterGroup(&modifyOpts) + if err != nil { + return fmt.Errorf("Error modifying DB Parameter Group: %s", err) + } + } + + return resourceAwsDbParameterGroupRead(d, meta) +} + +func resourceAwsDbParameterGroupDelete(d *schema.ResourceData, meta interface{}) error { + stateConf := &resource.StateChangeConf{ + Pending: []string{"pending"}, + Target: "destroyed", + Refresh: resourceDbParameterGroupDeleteRefreshFunc(d, meta), + Timeout: 3 * time.Minute, + MinTimeout: 1 * time.Second, + } + _, err := stateConf.WaitForState() + return err +} + +func resourceAwsDbParameterGroupRead(d *schema.ResourceData, meta interface{}) error { + p := meta.(*ResourceProvider) + rdsconn := p.rdsconn + + describeOpts := rds.DescribeDBParameterGroups{ + DBParameterGroupName: d.Id(), + } + + describeResp, err := rdsconn.DescribeDBParameterGroups(&describeOpts) + if err != nil { + return err + } + + if len(describeResp.DBParameterGroups) != 1 || + describeResp.DBParameterGroups[0].DBParameterGroupName != d.Id() { + return fmt.Errorf("Unable to find Parameter Group: %#v", describeResp.DBParameterGroups) + } + + d.Set("name", describeResp.DBParameterGroups[0].DBParameterGroupName) + d.Set("family", describeResp.DBParameterGroups[0].DBParameterGroupFamily) + d.Set("description", describeResp.DBParameterGroups[0].Description) + + // Only include user customized parameters as there's hundreds of system/default ones + describeParametersOpts := rds.DescribeDBParameters{ + DBParameterGroupName: d.Id(), + Source: "user", + } + + describeParametersResp, err := rdsconn.DescribeDBParameters(&describeParametersOpts) + if err != nil { + return err + } + + d.Set("parameter", flattenParameters(describeParametersResp.Parameters)) + + return nil +} + +func resourceDbParameterGroupDeleteRefreshFunc( + d *schema.ResourceData, + meta interface{}) resource.StateRefreshFunc { + p := meta.(*ResourceProvider) + rdsconn := p.rdsconn + + return func() (interface{}, string, error) { + + deleteOpts := rds.DeleteDBParameterGroup{ + DBParameterGroupName: d.Id(), + } + + if _, err := rdsconn.DeleteDBParameterGroup(&deleteOpts); err != nil { + rdserr, ok := err.(*rds.Error) + if !ok { + return d, "error", err + } + + if rdserr.Code != "DBParameterGroupNotFoundFault" { + return d, "error", err + } + } + + return d, "destroyed", nil + } +} diff --git a/builtin/providers/aws/resource_aws_db_parameter_group_test.go b/builtin/providers/aws/resource_aws_db_parameter_group_test.go new file mode 100644 index 0000000000..a5f58fdd26 --- /dev/null +++ b/builtin/providers/aws/resource_aws_db_parameter_group_test.go @@ -0,0 +1,218 @@ +package aws + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/mitchellh/goamz/rds" +) + +func TestAccAWSDBParameterGroup(t *testing.T) { + var v rds.DBParameterGroup + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSDBParameterGroupDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAWSDBParameterGroupConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSDBParameterGroupExists("aws_db_parameter_group.bar", &v), + testAccCheckAWSDBParameterGroupAttributes(&v), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "name", "parameter-group-test-terraform"), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "family", "mysql5.6"), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "description", "Test parameter group for terraform"), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "parameter.0.name", "character_set_client"), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "parameter.0.value", "utf8"), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "parameter.0.apply_method", "immediate"), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "parameter.1.name", "character_set_results"), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "parameter.1.value", "utf8"), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "parameter.1.apply_method", "immediate"), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "parameter.2.name", "character_set_server"), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "parameter.2.value", "utf8"), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "parameter.2.apply_method", "immediate"), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "parameter.3.name", "collation_connection"), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "parameter.3.value", "utf8_unicode_ci"), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "parameter.3.apply_method", "immediate"), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "parameter.4.name", "collation_server"), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "parameter.4.value", "utf8_unicode_ci"), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "parameter.4.apply_method", "immediate"), + ), + }, + }, + }) +} + +func TestAccAWSDBParameterGroupOnly(t *testing.T) { + var v rds.DBParameterGroup + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSDBParameterGroupDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAWSDBParameterGroupOnlyConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSDBParameterGroupExists("aws_db_parameter_group.bar", &v), + testAccCheckAWSDBParameterGroupAttributes(&v), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "name", "parameter-group-test-terraform"), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "family", "mysql5.6"), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "description", "Test parameter group for terraform"), + ), + }, + }, + }) +} + +func testAccCheckAWSDBParameterGroupDestroy(s *terraform.State) error { + conn := testAccProvider.rdsconn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_db_parameter_group" { + continue + } + + // Try to find the Group + resp, err := conn.DescribeDBParameterGroups( + &rds.DescribeDBParameterGroups{ + DBParameterGroupName: rs.Primary.ID, + }) + + if err == nil { + if len(resp.DBParameterGroups) != 0 && + resp.DBParameterGroups[0].DBParameterGroupName == rs.Primary.ID { + return fmt.Errorf("DB Parameter Group still exists") + } + } + + // Verify the error + newerr, ok := err.(*rds.Error) + if !ok { + return err + } + if newerr.Code != "InvalidDBParameterGroup.NotFound" { + return err + } + } + + return nil +} + +func testAccCheckAWSDBParameterGroupAttributes(v *rds.DBParameterGroup) resource.TestCheckFunc { + return func(s *terraform.State) error { + + if v.DBParameterGroupName != "parameter-group-test-terraform" { + return fmt.Errorf("bad name: %#v", v.DBParameterGroupName) + } + + if v.DBParameterGroupFamily != "mysql5.6" { + return fmt.Errorf("bad family: %#v", v.DBParameterGroupFamily) + } + + if v.Description != "Test parameter group for terraform" { + return fmt.Errorf("bad description: %#v", v.Description) + } + + return nil + } +} + +func testAccCheckAWSDBParameterGroupExists(n string, v *rds.DBParameterGroup) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No DB Parameter Group ID is set") + } + + conn := testAccProvider.rdsconn + + opts := rds.DescribeDBParameterGroups{ + DBParameterGroupName: rs.Primary.ID, + } + + resp, err := conn.DescribeDBParameterGroups(&opts) + + if err != nil { + return err + } + + if len(resp.DBParameterGroups) != 1 || + resp.DBParameterGroups[0].DBParameterGroupName != rs.Primary.ID { + return fmt.Errorf("DB Parameter Group not found") + } + + *v = resp.DBParameterGroups[0] + + return nil + } +} + +const testAccAWSDBParameterGroupConfig = ` +resource "aws_db_parameter_group" "bar" { + name = "parameter-group-test-terraform" + family = "mysql5.6" + description = "Test parameter group for terraform" + parameter { + name = "character_set_server" + value = "utf8" + apply_method = "immediate" + } + parameter { + name = "character_set_client" + value = "utf8" + apply_method = "immediate" + } + parameter{ + name = "character_set_results" + value = "utf8" + apply_method = "immediate" + } + parameter { + name = "collation_server" + value = "utf8_unicode_ci" + apply_method = "immediate" + } + parameter { + name = "collation_connection" + value = "utf8_unicode_ci" + apply_method = "immediate" + } +} +` + +const testAccAWSDBParameterGroupOnlyConfig = ` +resource "aws_db_parameter_group" "bar" { + name = "parameter-group-test-terraform" + family = "mysql5.6" + description = "Test parameter group for terraform" +} +` diff --git a/builtin/providers/aws/structure.go b/builtin/providers/aws/structure.go index 3af176c2ab..49858992ea 100644 --- a/builtin/providers/aws/structure.go +++ b/builtin/providers/aws/structure.go @@ -1,11 +1,13 @@ package aws import ( + "sort" "strings" "github.com/hashicorp/terraform/helper/schema" "github.com/mitchellh/goamz/ec2" "github.com/mitchellh/goamz/elb" + "github.com/mitchellh/goamz/rds" ) // Takes the result of flatmap.Expand for an array of listeners and @@ -87,6 +89,28 @@ func expandIPPerms(id string, configured []interface{}) []ec2.IPPerm { return perms } +// Takes the result of flatmap.Expand for an array of parameters and +// returns Parameter API compatible objects +func expandParameters(configured []interface{}) ([]rds.Parameter, error) { + parameters := make([]rds.Parameter, 0, len(configured)) + + // Loop over our configured parameters and create + // an array of goamz compatabile objects + for _, pRaw := range configured { + data := pRaw.(map[string]interface{}) + + p := rds.Parameter{ + ApplyMethod: data["apply_method"].(string), + ParameterName: data["name"].(string), + ParameterValue: data["value"].(string), + } + + parameters = append(parameters, p) + } + + return parameters, nil +} + // Flattens an array of ipPerms into a list of primitives that // flatmap.Flatten() can handle func flattenIPPerms(list []ec2.IPPerm) []map[string]interface{} { @@ -162,6 +186,19 @@ func flattenListeners(list []elb.Listener) []map[string]interface{} { return result } +// Flattens and sorts by name an array of Parameters into a []map[string]interface{} +func flattenParameters(list []rds.Parameter) []map[string]interface{} { + sort.Sort(ByParameterName(list)) + result := make([]map[string]interface{}, 0, len(list)) + for _, i := range list { + result = append(result, map[string]interface{}{ + "name": strings.ToLower(i.ParameterName), + "value": strings.ToLower(i.ParameterValue), + }) + } + return result +} + // Takes the result of flatmap.Expand for an array of strings // and returns a []string func expandStringList(configured []interface{}) []string { @@ -171,3 +208,8 @@ func expandStringList(configured []interface{}) []string { } return vs } + +type ByParameterName []rds.Parameter +func (a ByParameterName) Len() int { return len(a) } +func (a ByParameterName) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a ByParameterName) Less(i, j int) bool { return a[i].ParameterName < a[j].ParameterName } diff --git a/builtin/providers/aws/structure_test.go b/builtin/providers/aws/structure_test.go index e230cdf919..860e7f2f04 100644 --- a/builtin/providers/aws/structure_test.go +++ b/builtin/providers/aws/structure_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/mitchellh/goamz/ec2" "github.com/mitchellh/goamz/elb" + "github.com/mitchellh/goamz/rds" ) // Returns test configuration @@ -254,3 +255,67 @@ func Test_expandStringList(t *testing.T) { } } + +func Test_expandParameters(t *testing.T) { + expanded := []interface{}{ + map[string]interface{}{ + "name": "character_set_client", + "value": "utf8", + "apply_method": "immediate", + }, + } + parameters, err := expandParameters(expanded) + if err != nil { + t.Fatalf("bad: %#v", err) + } + + expected := rds.Parameter{ + ParameterName: "character_set_client", + ParameterValue: "utf8", + ApplyMethod: "immediate", + } + + if !reflect.DeepEqual(parameters[0], expected) { + t.Fatalf( + "Got:\n\n%#v\n\nExpected:\n\n%#v\n", + parameters[0], + expected) + } +} + +func Test_flattenParameters(t *testing.T) { + cases := []struct { + Input []rds.Parameter + Output []map[string]interface{} + }{ + { + Input: []rds.Parameter{ + rds.Parameter{ + ParameterName: "character_set_client", + ParameterValue: "utf8", + }, + rds.Parameter{ + ParameterName: "character_set_aaaclient", + ParameterValue: "utf8", + }, + }, + Output: []map[string]interface{}{ + map[string]interface{}{ + "name": "character_set_aaaclient", + "value": "utf8", + }, + map[string]interface{}{ + "name": "character_set_client", + "value": "utf8", + }, + }, + }, + } + + for _, tc := range cases { + output := flattenParameters(tc.Input) + if !reflect.DeepEqual(output, tc.Output) { + t.Fatalf("Got:\n\n%#v\n\nExpected:\n\n%#v", output, tc.Output) + } + } +} diff --git a/website/source/docs/providers/aws/r/db_instance.html.markdown b/website/source/docs/providers/aws/r/db_instance.html.markdown index d0e96c9529..167c8823b5 100644 --- a/website/source/docs/providers/aws/r/db_instance.html.markdown +++ b/website/source/docs/providers/aws/r/db_instance.html.markdown @@ -24,6 +24,7 @@ resource "aws_db_instance" "default" { password = "bar" security_group_names = ["${aws_db_security_group.bar.name}"] db_subnet_group_name = "my_database_subnet_group" + parameter_group_name = "default.mysql5.6" } ``` @@ -53,6 +54,7 @@ The following arguments are supported: * `skip_final_snapshot` - (Optional) Enables skipping the final snapshot on deletion. * `security_group_names` - (Optional) List of DB Security Groups to associate. * `db_subnet_group_name` - (Optional) Name of DB subnet group +* `parameter_group_name` - (Optional) Name of the DB parameter group to associate. ## Attributes Reference diff --git a/website/source/docs/providers/aws/r/db_parameter_group.html.markdown b/website/source/docs/providers/aws/r/db_parameter_group.html.markdown new file mode 100644 index 0000000000..04982aa1e8 --- /dev/null +++ b/website/source/docs/providers/aws/r/db_parameter_group.html.markdown @@ -0,0 +1,52 @@ +--- +layout: "aws" +page_title: "AWS: aws_db_parameter_group" +sidebar_current: "docs-aws-resource-db-parameter-group" +--- + +# aws\_db\_parameter\_group + +Provides an RDS DB parameter group resource. + +## Example Usage + +``` +resource "aws_db_parameter_group" "default" { + name = "rds_pg" + family = "mysql5.6" + description = "RDS default parameter group" + + parameter { + name = "character_set_server" + value = "utf8" + apply_method = "immediate" + } + + parameter { + name = "character_set_client" + value = "utf8" + apply_method = "immediate" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the DB parameter group. +* `family` - (Required) The family of the DB parameter group. +* `description` - (Required) The description of the DB parameter group. +* `parameter` - (Optional) A list of DB parameters to apply. + +Parameter blocks support the following: + +* `name` - (Required) The name of the DB parameter. +* `value` - (Required) The value of the DB parameter. +* `apply_method` - (Required) Indicates when to apply parameter updates. Either immediate or pending-reboot. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The db parameter group name. diff --git a/website/source/layouts/aws.erb b/website/source/layouts/aws.erb index 2fe57f0d14..50bf07ffb1 100644 --- a/website/source/layouts/aws.erb +++ b/website/source/layouts/aws.erb @@ -29,6 +29,10 @@ aws_db_subnet_group + > + aws_db_parameter_group + + > aws_eip From 3b54001a1ba2db4633a0f0e42ccd7f8ef7e418b4 Mon Sep 17 00:00:00 2001 From: Rob Costanzo Date: Wed, 22 Oct 2014 17:03:57 -0700 Subject: [PATCH 2/5] Added missing update support for new aws_db_parameter_group resource --- .../aws/resource_aws_db_parameter_group.go | 58 ++++++++++++++----- .../resource_aws_db_parameter_group_test.go | 10 ++-- builtin/providers/aws/structure.go | 9 +-- builtin/providers/aws/structure_test.go | 8 --- 4 files changed, 51 insertions(+), 34 deletions(-) diff --git a/builtin/providers/aws/resource_aws_db_parameter_group.go b/builtin/providers/aws/resource_aws_db_parameter_group.go index bb2588c989..984e36ba9f 100644 --- a/builtin/providers/aws/resource_aws_db_parameter_group.go +++ b/builtin/providers/aws/resource_aws_db_parameter_group.go @@ -1,10 +1,12 @@ package aws import ( + "bytes" "fmt" "log" "time" + "github.com/hashicorp/terraform/helper/hashcode" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" "github.com/mitchellh/goamz/rds" @@ -14,7 +16,7 @@ func resourceAwsDbParameterGroup() *schema.Resource { return &schema.Resource{ Create: resourceAwsDbParameterGroupCreate, Read: resourceAwsDbParameterGroupRead, - Update: nil, + Update: resourceAwsDbParameterGroupUpdate, Delete: resourceAwsDbParameterGroupDelete, Schema: map[string]*schema.Schema{ "name": &schema.Schema{ @@ -33,7 +35,7 @@ func resourceAwsDbParameterGroup() *schema.Resource { ForceNew: true, }, "parameter": &schema.Schema{ - Type: schema.TypeList, + Type: schema.TypeSet, Optional: true, ForceNew: true, Elem: &schema.Resource{ @@ -52,11 +54,21 @@ func resourceAwsDbParameterGroup() *schema.Resource { }, }, }, + Set: resourceAwsDbParameterHash, }, }, } } +func resourceAwsDbParameterHash(v interface{}) int { + var buf bytes.Buffer + m := v.(map[string]interface{}) + buf.WriteString(fmt.Sprintf("%s-", m["name"].(string))) + buf.WriteString(fmt.Sprintf("%s-", m["value"].(string))) + + return hashcode.String(buf.String()) +} + func resourceAwsDbParameterGroupCreate(d *schema.ResourceData, meta interface{}) error { p := meta.(*ResourceProvider) rdsconn := p.rdsconn @@ -76,26 +88,46 @@ func resourceAwsDbParameterGroupCreate(d *schema.ResourceData, meta interface{}) d.SetId(createOpts.DBParameterGroupName) log.Printf("[INFO] DB Parameter Group ID: %s", d.Id()) - if d.Get("parameter") != "" { + return resourceAwsDbParameterGroupUpdate(d, meta) +} + +func resourceAwsDbParameterGroupUpdate(d *schema.ResourceData, meta interface{}) error { + p := meta.(*ResourceProvider) + rdsconn := p.rdsconn + + if d.HasChange("parameter") { + o, n := d.GetChange("parameter") + if o == nil { + o = new(schema.Set) + } + if n == nil { + n = new(schema.Set) + } + + os := o.(*schema.Set) + ns := n.(*schema.Set) + // Expand the "parameter" set to goamz compat []rds.Parameter - parameters, err := expandParameters(d.Get("parameter").([]interface{})) + parameters, err := expandParameters(ns.Difference(os).List()) if err != nil { return err } - modifyOpts := rds.ModifyDBParameterGroup{ - DBParameterGroupName: d.Get("name").(string), - Parameters: parameters, - } + if len(parameters) > 0 { + modifyOpts := rds.ModifyDBParameterGroup{ + DBParameterGroupName: d.Get("name").(string), + Parameters: parameters, + } - log.Printf("[DEBUG] Modify DB Parameter Group: %#v", modifyOpts) - _, err = rdsconn.ModifyDBParameterGroup(&modifyOpts) - if err != nil { - return fmt.Errorf("Error modifying DB Parameter Group: %s", err) + log.Printf("[DEBUG] Modify DB Parameter Group: %#v", modifyOpts) + _, err = rdsconn.ModifyDBParameterGroup(&modifyOpts) + if err != nil { + return fmt.Errorf("Error modifying DB Parameter Group: %s", err) + } } } - return resourceAwsDbParameterGroupRead(d, meta) + return nil } func resourceAwsDbParameterGroupDelete(d *schema.ResourceData, meta interface{}) error { diff --git a/builtin/providers/aws/resource_aws_db_parameter_group_test.go b/builtin/providers/aws/resource_aws_db_parameter_group_test.go index a5f58fdd26..4a6b25e8e3 100644 --- a/builtin/providers/aws/resource_aws_db_parameter_group_test.go +++ b/builtin/providers/aws/resource_aws_db_parameter_group_test.go @@ -29,9 +29,9 @@ func TestAccAWSDBParameterGroup(t *testing.T) { resource.TestCheckResourceAttr( "aws_db_parameter_group.bar", "description", "Test parameter group for terraform"), resource.TestCheckResourceAttr( - "aws_db_parameter_group.bar", "parameter.0.name", "character_set_client"), + "aws_db_parameter_group.bar", "parameter.0.name", "collation_connection"), resource.TestCheckResourceAttr( - "aws_db_parameter_group.bar", "parameter.0.value", "utf8"), + "aws_db_parameter_group.bar", "parameter.0.value", "utf8_unicode_ci"), resource.TestCheckResourceAttr( "aws_db_parameter_group.bar", "parameter.0.apply_method", "immediate"), resource.TestCheckResourceAttr( @@ -47,15 +47,15 @@ func TestAccAWSDBParameterGroup(t *testing.T) { resource.TestCheckResourceAttr( "aws_db_parameter_group.bar", "parameter.2.apply_method", "immediate"), resource.TestCheckResourceAttr( - "aws_db_parameter_group.bar", "parameter.3.name", "collation_connection"), + "aws_db_parameter_group.bar", "parameter.3.name", "collation_server"), resource.TestCheckResourceAttr( "aws_db_parameter_group.bar", "parameter.3.value", "utf8_unicode_ci"), resource.TestCheckResourceAttr( "aws_db_parameter_group.bar", "parameter.3.apply_method", "immediate"), resource.TestCheckResourceAttr( - "aws_db_parameter_group.bar", "parameter.4.name", "collation_server"), + "aws_db_parameter_group.bar", "parameter.4.name", "character_set_client"), resource.TestCheckResourceAttr( - "aws_db_parameter_group.bar", "parameter.4.value", "utf8_unicode_ci"), + "aws_db_parameter_group.bar", "parameter.4.value", "utf8"), resource.TestCheckResourceAttr( "aws_db_parameter_group.bar", "parameter.4.apply_method", "immediate"), ), diff --git a/builtin/providers/aws/structure.go b/builtin/providers/aws/structure.go index 49858992ea..288e9d46c5 100644 --- a/builtin/providers/aws/structure.go +++ b/builtin/providers/aws/structure.go @@ -1,7 +1,6 @@ package aws import ( - "sort" "strings" "github.com/hashicorp/terraform/helper/schema" @@ -186,9 +185,8 @@ func flattenListeners(list []elb.Listener) []map[string]interface{} { return result } -// Flattens and sorts by name an array of Parameters into a []map[string]interface{} +// Flattens an array of Parameters into a []map[string]interface{} func flattenParameters(list []rds.Parameter) []map[string]interface{} { - sort.Sort(ByParameterName(list)) result := make([]map[string]interface{}, 0, len(list)) for _, i := range list { result = append(result, map[string]interface{}{ @@ -208,8 +206,3 @@ func expandStringList(configured []interface{}) []string { } return vs } - -type ByParameterName []rds.Parameter -func (a ByParameterName) Len() int { return len(a) } -func (a ByParameterName) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a ByParameterName) Less(i, j int) bool { return a[i].ParameterName < a[j].ParameterName } diff --git a/builtin/providers/aws/structure_test.go b/builtin/providers/aws/structure_test.go index 860e7f2f04..46d013ef32 100644 --- a/builtin/providers/aws/structure_test.go +++ b/builtin/providers/aws/structure_test.go @@ -294,16 +294,8 @@ func Test_flattenParameters(t *testing.T) { ParameterName: "character_set_client", ParameterValue: "utf8", }, - rds.Parameter{ - ParameterName: "character_set_aaaclient", - ParameterValue: "utf8", - }, }, Output: []map[string]interface{}{ - map[string]interface{}{ - "name": "character_set_aaaclient", - "value": "utf8", - }, map[string]interface{}{ "name": "character_set_client", "value": "utf8", From 0e3afa6d3dc89b30ecd73eb9cc76cd5ca2e7f861 Mon Sep 17 00:00:00 2001 From: Rob Costanzo Date: Thu, 23 Oct 2014 11:16:39 -0700 Subject: [PATCH 3/5] Fixed incorrect ForcesNew settings for parameters and added better acceptance tests to ensure updates are working as expected --- .../aws/resource_aws_db_parameter_group.go | 18 ++++- .../resource_aws_db_parameter_group_test.go | 72 ++++++++++++++----- builtin/providers/aws/structure.go | 7 +- builtin/providers/aws/structure_test.go | 5 +- 4 files changed, 79 insertions(+), 23 deletions(-) diff --git a/builtin/providers/aws/resource_aws_db_parameter_group.go b/builtin/providers/aws/resource_aws_db_parameter_group.go index 984e36ba9f..93f0efa4f1 100644 --- a/builtin/providers/aws/resource_aws_db_parameter_group.go +++ b/builtin/providers/aws/resource_aws_db_parameter_group.go @@ -37,7 +37,7 @@ func resourceAwsDbParameterGroup() *schema.Resource { "parameter": &schema.Schema{ Type: schema.TypeSet, Optional: true, - ForceNew: true, + ForceNew: false, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "apply_method": &schema.Schema{ @@ -85,6 +85,12 @@ func resourceAwsDbParameterGroupCreate(d *schema.ResourceData, meta interface{}) return fmt.Errorf("Error creating DB Parameter Group: %s", err) } + d.Partial(true) + d.SetPartial("name") + d.SetPartial("family") + d.SetPartial("description") + d.Partial(false) + d.SetId(createOpts.DBParameterGroupName) log.Printf("[INFO] DB Parameter Group ID: %s", d.Id()) @@ -95,6 +101,8 @@ func resourceAwsDbParameterGroupUpdate(d *schema.ResourceData, meta interface{}) p := meta.(*ResourceProvider) rdsconn := p.rdsconn + d.Partial(true) + if d.HasChange("parameter") { o, n := d.GetChange("parameter") if o == nil { @@ -125,9 +133,12 @@ func resourceAwsDbParameterGroupUpdate(d *schema.ResourceData, meta interface{}) return fmt.Errorf("Error modifying DB Parameter Group: %s", err) } } + d.SetPartial("parameter") } - return nil + d.Partial(false) + + return resourceAwsDbParameterGroupRead(d, meta) } func resourceAwsDbParameterGroupDelete(d *schema.ResourceData, meta interface{}) error { @@ -175,6 +186,9 @@ func resourceAwsDbParameterGroupRead(d *schema.ResourceData, meta interface{}) e return err } + // apply_method is only relevant for creates and AWS does not maintain its state. + + d.Set("parameter", flattenParameters(describeParametersResp.Parameters)) return nil diff --git a/builtin/providers/aws/resource_aws_db_parameter_group_test.go b/builtin/providers/aws/resource_aws_db_parameter_group_test.go index 4a6b25e8e3..f406a39860 100644 --- a/builtin/providers/aws/resource_aws_db_parameter_group_test.go +++ b/builtin/providers/aws/resource_aws_db_parameter_group_test.go @@ -19,6 +19,31 @@ func TestAccAWSDBParameterGroup(t *testing.T) { Steps: []resource.TestStep{ resource.TestStep{ Config: testAccAWSDBParameterGroupConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSDBParameterGroupExists("aws_db_parameter_group.bar", &v), + testAccCheckAWSDBParameterGroupAttributes(&v), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "name", "parameter-group-test-terraform"), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "family", "mysql5.6"), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "description", "Test parameter group for terraform"), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "parameter.0.name", "character_set_results"), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "parameter.0.value", "utf8"), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "parameter.1.name", "character_set_server"), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "parameter.1.value", "utf8"), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "parameter.2.name", "character_set_client"), + resource.TestCheckResourceAttr( + "aws_db_parameter_group.bar", "parameter.2.value", "utf8"), + ), + }, + resource.TestStep{ + Config: testAccAWSDBParameterGroupAddParametersConfig, Check: resource.ComposeTestCheckFunc( testAccCheckAWSDBParameterGroupExists("aws_db_parameter_group.bar", &v), testAccCheckAWSDBParameterGroupAttributes(&v), @@ -32,32 +57,22 @@ func TestAccAWSDBParameterGroup(t *testing.T) { "aws_db_parameter_group.bar", "parameter.0.name", "collation_connection"), resource.TestCheckResourceAttr( "aws_db_parameter_group.bar", "parameter.0.value", "utf8_unicode_ci"), - resource.TestCheckResourceAttr( - "aws_db_parameter_group.bar", "parameter.0.apply_method", "immediate"), resource.TestCheckResourceAttr( "aws_db_parameter_group.bar", "parameter.1.name", "character_set_results"), resource.TestCheckResourceAttr( "aws_db_parameter_group.bar", "parameter.1.value", "utf8"), - resource.TestCheckResourceAttr( - "aws_db_parameter_group.bar", "parameter.1.apply_method", "immediate"), resource.TestCheckResourceAttr( "aws_db_parameter_group.bar", "parameter.2.name", "character_set_server"), resource.TestCheckResourceAttr( "aws_db_parameter_group.bar", "parameter.2.value", "utf8"), - resource.TestCheckResourceAttr( - "aws_db_parameter_group.bar", "parameter.2.apply_method", "immediate"), resource.TestCheckResourceAttr( "aws_db_parameter_group.bar", "parameter.3.name", "collation_server"), resource.TestCheckResourceAttr( "aws_db_parameter_group.bar", "parameter.3.value", "utf8_unicode_ci"), - resource.TestCheckResourceAttr( - "aws_db_parameter_group.bar", "parameter.3.apply_method", "immediate"), resource.TestCheckResourceAttr( "aws_db_parameter_group.bar", "parameter.4.name", "character_set_client"), resource.TestCheckResourceAttr( "aws_db_parameter_group.bar", "parameter.4.value", "utf8"), - resource.TestCheckResourceAttr( - "aws_db_parameter_group.bar", "parameter.4.apply_method", "immediate"), ), }, }, @@ -65,14 +80,14 @@ func TestAccAWSDBParameterGroup(t *testing.T) { } func TestAccAWSDBParameterGroupOnly(t *testing.T) { - var v rds.DBParameterGroup + var v rds.DBParameterGroup - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAWSDBParameterGroupDestroy, - Steps: []resource.TestStep{ - resource.TestStep{ + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSDBParameterGroupDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ Config: testAccAWSDBParameterGroupOnlyConfig, Check: resource.ComposeTestCheckFunc( testAccCheckAWSDBParameterGroupExists("aws_db_parameter_group.bar", &v), @@ -177,6 +192,29 @@ func testAccCheckAWSDBParameterGroupExists(n string, v *rds.DBParameterGroup) re } const testAccAWSDBParameterGroupConfig = ` +resource "aws_db_parameter_group" "bar" { + name = "parameter-group-test-terraform" + family = "mysql5.6" + description = "Test parameter group for terraform" + parameter { + name = "character_set_server" + value = "utf8" + apply_method = "immediate" + } + parameter { + name = "character_set_client" + value = "utf8" + apply_method = "immediate" + } + parameter{ + name = "character_set_results" + value = "utf8" + apply_method = "immediate" + } +} +` + +const testAccAWSDBParameterGroupAddParametersConfig = ` resource "aws_db_parameter_group" "bar" { name = "parameter-group-test-terraform" family = "mysql5.6" diff --git a/builtin/providers/aws/structure.go b/builtin/providers/aws/structure.go index 288e9d46c5..3e00a03082 100644 --- a/builtin/providers/aws/structure.go +++ b/builtin/providers/aws/structure.go @@ -190,8 +190,11 @@ func flattenParameters(list []rds.Parameter) []map[string]interface{} { result := make([]map[string]interface{}, 0, len(list)) for _, i := range list { result = append(result, map[string]interface{}{ - "name": strings.ToLower(i.ParameterName), - "value": strings.ToLower(i.ParameterValue), + "name": strings.ToLower(i.ParameterName), + "value": strings.ToLower(i.ParameterValue), + // apply_method is only used on create/modify and is not returned when reading from AWS. + // This is a dummy value to print out as it's not used when doing the state diff for updating + "apply_method": "applied", }) } return result diff --git a/builtin/providers/aws/structure_test.go b/builtin/providers/aws/structure_test.go index 46d013ef32..de72c59a39 100644 --- a/builtin/providers/aws/structure_test.go +++ b/builtin/providers/aws/structure_test.go @@ -297,8 +297,9 @@ func Test_flattenParameters(t *testing.T) { }, Output: []map[string]interface{}{ map[string]interface{}{ - "name": "character_set_client", - "value": "utf8", + "name": "character_set_client", + "value": "utf8", + "apply_method": "applied", }, }, }, From a14da63a3918e4011a0913247d704f2969c23c53 Mon Sep 17 00:00:00 2001 From: Rob Costanzo Date: Thu, 23 Oct 2014 14:07:31 -0700 Subject: [PATCH 4/5] Fixed bug with final_snapshot_identifier and skip_final_snapshot and removed apply_method as an option for now and am only supporting immediate mode --- builtin/providers/aws/resource_aws_db_instance.go | 2 ++ builtin/providers/aws/resource_aws_db_parameter_group.go | 7 ------- .../providers/aws/resource_aws_db_parameter_group_test.go | 8 -------- builtin/providers/aws/structure.go | 7 +++---- builtin/providers/aws/structure_test.go | 1 - .../docs/providers/aws/r/db_parameter_group.html.markdown | 3 --- 6 files changed, 5 insertions(+), 23 deletions(-) diff --git a/builtin/providers/aws/resource_aws_db_instance.go b/builtin/providers/aws/resource_aws_db_instance.go index 49e6be5372..9c02504f6d 100644 --- a/builtin/providers/aws/resource_aws_db_instance.go +++ b/builtin/providers/aws/resource_aws_db_instance.go @@ -347,6 +347,8 @@ func resource_aws_db_instance_validation() *config.Validator { "security_group_names.*", "db_subnet_group_name", "parameter_group_name", + "skip_final_snapshot", + "final_snapshot_identifier", }, } } diff --git a/builtin/providers/aws/resource_aws_db_parameter_group.go b/builtin/providers/aws/resource_aws_db_parameter_group.go index 93f0efa4f1..af5d0b32d3 100644 --- a/builtin/providers/aws/resource_aws_db_parameter_group.go +++ b/builtin/providers/aws/resource_aws_db_parameter_group.go @@ -40,10 +40,6 @@ func resourceAwsDbParameterGroup() *schema.Resource { ForceNew: false, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "apply_method": &schema.Schema{ - Type: schema.TypeString, - Required: true, - }, "name": &schema.Schema{ Type: schema.TypeString, Required: true, @@ -186,9 +182,6 @@ func resourceAwsDbParameterGroupRead(d *schema.ResourceData, meta interface{}) e return err } - // apply_method is only relevant for creates and AWS does not maintain its state. - - d.Set("parameter", flattenParameters(describeParametersResp.Parameters)) return nil diff --git a/builtin/providers/aws/resource_aws_db_parameter_group_test.go b/builtin/providers/aws/resource_aws_db_parameter_group_test.go index f406a39860..93f61cd68b 100644 --- a/builtin/providers/aws/resource_aws_db_parameter_group_test.go +++ b/builtin/providers/aws/resource_aws_db_parameter_group_test.go @@ -199,17 +199,14 @@ resource "aws_db_parameter_group" "bar" { parameter { name = "character_set_server" value = "utf8" - apply_method = "immediate" } parameter { name = "character_set_client" value = "utf8" - apply_method = "immediate" } parameter{ name = "character_set_results" value = "utf8" - apply_method = "immediate" } } ` @@ -222,27 +219,22 @@ resource "aws_db_parameter_group" "bar" { parameter { name = "character_set_server" value = "utf8" - apply_method = "immediate" } parameter { name = "character_set_client" value = "utf8" - apply_method = "immediate" } parameter{ name = "character_set_results" value = "utf8" - apply_method = "immediate" } parameter { name = "collation_server" value = "utf8_unicode_ci" - apply_method = "immediate" } parameter { name = "collation_connection" value = "utf8_unicode_ci" - apply_method = "immediate" } } ` diff --git a/builtin/providers/aws/structure.go b/builtin/providers/aws/structure.go index 3e00a03082..45ccbf093e 100644 --- a/builtin/providers/aws/structure.go +++ b/builtin/providers/aws/structure.go @@ -99,7 +99,9 @@ func expandParameters(configured []interface{}) ([]rds.Parameter, error) { data := pRaw.(map[string]interface{}) p := rds.Parameter{ - ApplyMethod: data["apply_method"].(string), + // Only immediate is supported for now; should add in pending-reboot at some point + // but gets tricky as the DescribeParameterGroups AWS call doesn't return this data + ApplyMethod: "immediate", ParameterName: data["name"].(string), ParameterValue: data["value"].(string), } @@ -192,9 +194,6 @@ func flattenParameters(list []rds.Parameter) []map[string]interface{} { result = append(result, map[string]interface{}{ "name": strings.ToLower(i.ParameterName), "value": strings.ToLower(i.ParameterValue), - // apply_method is only used on create/modify and is not returned when reading from AWS. - // This is a dummy value to print out as it's not used when doing the state diff for updating - "apply_method": "applied", }) } return result diff --git a/builtin/providers/aws/structure_test.go b/builtin/providers/aws/structure_test.go index de72c59a39..09ae987c8d 100644 --- a/builtin/providers/aws/structure_test.go +++ b/builtin/providers/aws/structure_test.go @@ -299,7 +299,6 @@ func Test_flattenParameters(t *testing.T) { map[string]interface{}{ "name": "character_set_client", "value": "utf8", - "apply_method": "applied", }, }, }, diff --git a/website/source/docs/providers/aws/r/db_parameter_group.html.markdown b/website/source/docs/providers/aws/r/db_parameter_group.html.markdown index 04982aa1e8..855665f66a 100644 --- a/website/source/docs/providers/aws/r/db_parameter_group.html.markdown +++ b/website/source/docs/providers/aws/r/db_parameter_group.html.markdown @@ -19,13 +19,11 @@ resource "aws_db_parameter_group" "default" { parameter { name = "character_set_server" value = "utf8" - apply_method = "immediate" } parameter { name = "character_set_client" value = "utf8" - apply_method = "immediate" } } ``` @@ -43,7 +41,6 @@ Parameter blocks support the following: * `name` - (Required) The name of the DB parameter. * `value` - (Required) The value of the DB parameter. -* `apply_method` - (Required) Indicates when to apply parameter updates. Either immediate or pending-reboot. ## Attributes Reference From 16b4dd44c153a4ede17f1d0c8a9d77352e643094 Mon Sep 17 00:00:00 2001 From: Rob Costanzo Date: Thu, 23 Oct 2014 14:27:38 -0700 Subject: [PATCH 5/5] Upped the RDS instance creation/destroy timeout to 20 minutes as it regularly takes 12+ minutes to create --- builtin/providers/aws/resource_aws_db_instance.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builtin/providers/aws/resource_aws_db_instance.go b/builtin/providers/aws/resource_aws_db_instance.go index 9c02504f6d..e2c1e60e62 100644 --- a/builtin/providers/aws/resource_aws_db_instance.go +++ b/builtin/providers/aws/resource_aws_db_instance.go @@ -121,7 +121,7 @@ func resource_aws_db_instance_create( Pending: []string{"creating", "backing-up", "modifying"}, Target: "available", Refresh: DBInstanceStateRefreshFunc(rs.ID, conn), - Timeout: 10 * time.Minute, + Timeout: 20 * time.Minute, MinTimeout: 10 * time.Second, Delay: 30 * time.Second, // Wait 30 secs before starting } @@ -175,7 +175,7 @@ func resource_aws_db_instance_destroy( "modifying", "deleting", "available"}, Target: "", Refresh: DBInstanceStateRefreshFunc(s.ID, conn), - Timeout: 10 * time.Minute, + Timeout: 20 * time.Minute, MinTimeout: 10 * time.Second, Delay: 30 * time.Second, // Wait 30 secs before starting }