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

Support resetting of parameter group values #11540

Merged
merged 3 commits into from
Jan 14, 2020
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
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