Skip to content

Commit

Permalink
Merge pull request #11540 from terraform-providers/f-stefansundin-res…
Browse files Browse the repository at this point in the history
…et-parameter-groups

Support resetting of parameter group values
  • Loading branch information
ryndaniels authored Jan 14, 2020
2 parents 3716d83 + d1155af commit d0c5124
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 24 deletions.
31 changes: 30 additions & 1 deletion aws/resource_aws_db_parameter_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,36 @@ func resourceAwsDbParameterGroupUpdate(d *schema.ResourceData, meta interface{})
return fmt.Errorf("Error modifying DB Parameter Group: %s", err)
}
}
d.SetPartial("parameter")
}

// Reset parameters that have been removed
resetParameters, err := expandParameters(os.Difference(ns).List())
if err != nil {
return err
}
if len(resetParameters) > 0 {
maxParams := 20
for resetParameters != nil {
var paramsToReset []*rds.Parameter
if len(resetParameters) <= maxParams {
paramsToReset, resetParameters = resetParameters[:], nil
} else {
paramsToReset, resetParameters = resetParameters[:maxParams], resetParameters[maxParams:]
}

parameterGroupName := d.Get("name").(string)
resetOpts := rds.ResetDBParameterGroupInput{
DBParameterGroupName: aws.String(parameterGroupName),
Parameters: paramsToReset,
ResetAllParameters: aws.Bool(false),
}

log.Printf("[DEBUG] Reset DB Parameter Group: %s", resetOpts)
_, err = rdsconn.ResetDBParameterGroup(&resetOpts)
if err != nil {
return fmt.Errorf("Error resetting DB Parameter Group: %s", err)
}
}
}
}

Expand Down
68 changes: 48 additions & 20 deletions aws/resource_aws_db_parameter_group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,6 @@ func TestAccAWSDBParameterGroup_basic(t *testing.T) {
resourceName, "name", groupName),
resource.TestCheckResourceAttr(
resourceName, "family", "mysql5.6"),
resource.TestCheckResourceAttr(
resourceName, "description", "Managed by Terraform"),
resource.TestCheckResourceAttr(
resourceName, "parameter.1708034931.name", "character_set_results"),
resource.TestCheckResourceAttr(
Expand All @@ -106,8 +104,6 @@ func TestAccAWSDBParameterGroup_basic(t *testing.T) {
resourceName, "parameter.2478663599.name", "character_set_client"),
resource.TestCheckResourceAttr(
resourceName, "parameter.2478663599.value", "utf8"),
resource.TestCheckResourceAttr(
resourceName, "tags.%", "1"),
resource.TestMatchResourceAttr(
resourceName, "arn", regexp.MustCompile(fmt.Sprintf("^arn:[^:]+:rds:[^:]+:\\d{12}:pg:%s", groupName))),
),
Expand All @@ -126,8 +122,6 @@ func TestAccAWSDBParameterGroup_basic(t *testing.T) {
resourceName, "name", groupName),
resource.TestCheckResourceAttr(
resourceName, "family", "mysql5.6"),
resource.TestCheckResourceAttr(
resourceName, "description", "Test parameter group for terraform"),
resource.TestCheckResourceAttr(
resourceName, "parameter.1706463059.name", "collation_connection"),
resource.TestCheckResourceAttr(
Expand All @@ -148,12 +142,21 @@ func TestAccAWSDBParameterGroup_basic(t *testing.T) {
resourceName, "parameter.2478663599.name", "character_set_client"),
resource.TestCheckResourceAttr(
resourceName, "parameter.2478663599.value", "utf8"),
resource.TestCheckResourceAttr(
resourceName, "tags.%", "2"),
resource.TestMatchResourceAttr(
resourceName, "arn", regexp.MustCompile(fmt.Sprintf("^arn:[^:]+:rds:[^:]+:\\d{12}:pg:%s", groupName))),
),
},
{
Config: testAccAWSDBParameterGroupConfig(groupName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSDBParameterGroupExists(resourceName, &v),
testAccCheckAWSDBParameterGroupAttributes(&v, groupName),
testAccCheckAWSDBParameterNotUserDefined(resourceName, "collation_connection"),
testAccCheckAWSDBParameterNotUserDefined(resourceName, "collation_server"),
resource.TestCheckNoResourceAttr(resourceName, "parameter.2475805061.value"),
resource.TestCheckNoResourceAttr(resourceName, "parameter.1706463059.value"),
),
},
},
})
}
Expand All @@ -176,7 +179,6 @@ func TestAccAWSDBParameterGroup_limit(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "name", groupName),
resource.TestCheckResourceAttr(resourceName, "family", "mysql5.6"),
resource.TestCheckResourceAttr(resourceName, "description", "RDS default parameter group: Exceed default AWS parameter group limit of twenty"),

resource.TestCheckResourceAttr(resourceName, "parameter.2421266705.name", "character_set_server"),
resource.TestCheckResourceAttr(resourceName, "parameter.2421266705.value", "utf8"),
resource.TestCheckResourceAttr(resourceName, "parameter.2478663599.name", "character_set_client"),
Expand Down Expand Up @@ -274,7 +276,6 @@ func TestAccAWSDBParameterGroup_limit(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "name", groupName),
resource.TestCheckResourceAttr(resourceName, "family", "mysql5.6"),
resource.TestCheckResourceAttr(resourceName, "description", "Updated RDS default parameter group: Exceed default AWS parameter group limit of twenty"),

resource.TestCheckResourceAttr(resourceName, "parameter.2421266705.name", "character_set_server"),
resource.TestCheckResourceAttr(resourceName, "parameter.2421266705.value", "utf8"),
resource.TestCheckResourceAttr(resourceName, "parameter.2478663599.name", "character_set_client"),
Expand Down Expand Up @@ -627,6 +628,43 @@ func testAccCheckAWSDBParameterGroupExists(n string, v *rds.DBParameterGroup) re
}
}

func testAccCheckAWSDBParameterNotUserDefined(n, paramName string) 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.Meta().(*AWSClient).rdsconn

opts := rds.DescribeDBParametersInput{
DBParameterGroupName: aws.String(rs.Primary.ID),
Source: aws.String("user"),
}

userDefined := false
err := conn.DescribeDBParametersPages(&opts, func(page *rds.DescribeDBParametersOutput, lastPage bool) bool {
for _, param := range page.Parameters {
if *param.ParameterName == paramName {
userDefined = true
return false
}
}
return true
})

if userDefined {
return fmt.Errorf("DB Parameter is user defined")
}

return err
}
}

func testAccAWSDBParameterGroupConfig(n string) string {
return fmt.Sprintf(`
resource "aws_db_parameter_group" "test" {
Expand All @@ -647,10 +685,6 @@ resource "aws_db_parameter_group" "test" {
name = "character_set_results"
value = "utf8"
}
tags = {
foo = "test"
}
}
`, n)
}
Expand Down Expand Up @@ -684,7 +718,6 @@ func testAccAWSDBParameterGroupAddParametersConfig(n string) string {
resource "aws_db_parameter_group" "test" {
name = "%s"
family = "mysql5.6"
description = "Test parameter group for terraform"
parameter {
name = "character_set_server"
Expand All @@ -710,11 +743,6 @@ resource "aws_db_parameter_group" "test" {
name = "collation_connection"
value = "utf8_unicode_ci"
}
tags = {
foo = "test"
baz = "foo"
}
}
`, n)
}
Expand Down
45 changes: 42 additions & 3 deletions aws/resource_aws_rds_cluster_parameter_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,9 @@ func resourceAwsRDSClusterParameterGroupRead(d *schema.ResourceData, meta interf
return err
}

d.Set("parameter", flattenParameters(describeParametersResp.Parameters))
if err := d.Set("parameter", flattenParameters(describeParametersResp.Parameters)); err != nil {
return fmt.Errorf("error setting parameters: %s", err)
}

resp, err := rdsconn.ListTagsForResource(&rds.ListTagsForResourceInput{
ResourceName: aws.String(arn),
Expand Down Expand Up @@ -219,10 +221,47 @@ func resourceAwsRDSClusterParameterGroupUpdate(d *schema.ResourceData, meta inte
log.Printf("[DEBUG] Modify DB Cluster Parameter Group: %s", modifyOpts)
_, err = rdsconn.ModifyDBClusterParameterGroup(&modifyOpts)
if err != nil {
return fmt.Errorf("Error modifying DB Cluster Parameter Group: %s", err)
return fmt.Errorf("error modifying DB Cluster Parameter Group: %s", err)
}
}
}

// Reset parameters that have been removed
parameters, err = expandParameters(os.Difference(ns).List())
if err != nil {
return err
}
if len(parameters) > 0 {
for parameters != nil {
parameterGroupName := d.Get("name").(string)
var paramsToReset []*rds.Parameter
if len(parameters) <= rdsClusterParameterGroupMaxParamsBulkEdit {
paramsToReset, parameters = parameters[:], nil
} else {
paramsToReset, parameters = parameters[:rdsClusterParameterGroupMaxParamsBulkEdit], parameters[rdsClusterParameterGroupMaxParamsBulkEdit:]
}

resetOpts := rds.ResetDBClusterParameterGroupInput{
DBClusterParameterGroupName: aws.String(parameterGroupName),
Parameters: paramsToReset,
ResetAllParameters: aws.Bool(false),
}

log.Printf("[DEBUG] Reset DB Cluster Parameter Group: %s", resetOpts)
err := resource.Retry(3*time.Minute, func() *resource.RetryError {
_, err := rdsconn.ResetDBClusterParameterGroup(&resetOpts)
if err != nil {
if isAWSErr(err, "InvalidDBParameterGroupState", "has pending changes") {
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
if err != nil {
return fmt.Errorf("error resetting DB Cluster Parameter Group: %s", err)
}
}
d.SetPartial("parameter")
}
}

Expand Down
44 changes: 44 additions & 0 deletions aws/resource_aws_rds_cluster_parameter_group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,17 @@ func TestAccAWSDBClusterParameterGroup_basic(t *testing.T) {
resourceName, "tags.%", "2"),
),
},
{
Config: testAccAWSDBClusterParameterGroupConfig(parameterGroupName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSDBClusterParameterGroupExists(resourceName, &v),
testAccCheckAWSDBClusterParameterGroupAttributes(&v, parameterGroupName),
testAccCheckAWSRDSClusterParameterNotUserDefined(resourceName, "collation_connection"),
testAccCheckAWSRDSClusterParameterNotUserDefined(resourceName, "collation_server"),
resource.TestCheckNoResourceAttr(resourceName, "parameter.2475805061.value"),
resource.TestCheckNoResourceAttr(resourceName, "parameter.1706463059.value"),
),
},
},
})
}
Expand Down Expand Up @@ -401,6 +412,39 @@ func testAccCheckAWSDBClusterParameterGroupDestroy(s *terraform.State) error {
return nil
}

func testAccCheckAWSRDSClusterParameterNotUserDefined(n, paramName string) 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.Meta().(*AWSClient).rdsconn

opts := rds.DescribeDBClusterParametersInput{
DBClusterParameterGroupName: aws.String(rs.Primary.ID),
}

userDefined := false
out, err := conn.DescribeDBClusterParameters(&opts)
for _, param := range out.Parameters {
if *param.ParameterName == paramName && aws.StringValue(param.ParameterValue) != "" {
// Some of these resets leave the parameter name present but with a nil value
userDefined = true
}
}

if userDefined {
return fmt.Errorf("DB Parameter %s is user defined", paramName)
}
return err
}
}

func testAccCheckAWSDBClusterParameterGroupAttributes(v *rds.DBClusterParameterGroup, name string) resource.TestCheckFunc {
return func(s *terraform.State) error {

Expand Down

0 comments on commit d0c5124

Please sign in to comment.