Skip to content

Commit

Permalink
Merge pull request #1808 from terraform-providers/b-app-autoscaling-d…
Browse files Browse the repository at this point in the history
…imension

r/appautoscaling_*: Use dimension to uniquely identify target/policy
  • Loading branch information
radeksimko authored Oct 11, 2017
2 parents 30b3818 + ab5f66a commit 9b67079
Show file tree
Hide file tree
Showing 4 changed files with 273 additions and 25 deletions.
12 changes: 6 additions & 6 deletions aws/resource_aws_appautoscaling_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ func resourceAwsAppautoscalingPolicyCreate(d *schema.ResourceData, meta interfac
return nil
})
if err != nil {
return err
return fmt.Errorf("Failed to create scaling policy: %s", err)
}

d.Set("arn", resp.PolicyARN)
Expand Down Expand Up @@ -317,7 +317,7 @@ func resourceAwsAppautoscalingPolicyUpdate(d *schema.ResourceData, meta interfac
log.Printf("[DEBUG] Application Autoscaling Update Scaling Policy: %#v", params)
_, err := conn.PutScalingPolicy(&params)
if err != nil {
return err
return fmt.Errorf("Failed to update scaling policy: %s", err)
}

return resourceAwsAppautoscalingPolicyRead(d, meta)
Expand All @@ -341,7 +341,7 @@ func resourceAwsAppautoscalingPolicyDelete(d *schema.ResourceData, meta interfac
}
log.Printf("[DEBUG] Deleting Application AutoScaling Policy opts: %#v", params)
if _, err := conn.DeleteScalingPolicy(&params); err != nil {
return fmt.Errorf("Application AutoScaling Policy: %s", err)
return fmt.Errorf("Failed to delete autoscaling policy: %s", err)
}

d.SetId("")
Expand Down Expand Up @@ -571,14 +571,14 @@ func getAwsAppautoscalingPolicy(d *schema.ResourceData, meta interface{}) (*appl
}

// find scaling policy
name := d.Get("name")
name := d.Get("name").(string)
dimension := d.Get("scalable_dimension").(string)
for idx, sp := range resp.ScalingPolicies {
if *sp.PolicyName == name {
if *sp.PolicyName == name && *sp.ScalableDimension == dimension {
return resp.ScalingPolicies[idx], nil
}
}

// policy not found
return nil, nil
}

Expand Down
140 changes: 140 additions & 0 deletions aws/resource_aws_appautoscaling_policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,36 @@ func TestAccAWSAppautoScalingPolicy_dynamoDb(t *testing.T) {
})
}

func TestAccAWSAppautoScalingPolicy_multiplePolicies(t *testing.T) {
var readPolicy applicationautoscaling.ScalingPolicy
var writePolicy applicationautoscaling.ScalingPolicy

tableName := fmt.Sprintf("tf-autoscaled-table-%s", acctest.RandString(5))
namePrefix := fmt.Sprintf("tf-appautoscaling-policy-%s", acctest.RandString(5))

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSAppautoscalingPolicyDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSAppautoscalingPolicy_multiplePolicies(tableName, namePrefix),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSAppautoscalingPolicyExists("aws_appautoscaling_policy.read", &readPolicy),
resource.TestCheckResourceAttr("aws_appautoscaling_policy.read", "name", namePrefix+"-read"),
resource.TestCheckResourceAttr("aws_appautoscaling_policy.read", "service_namespace", "dynamodb"),
resource.TestCheckResourceAttr("aws_appautoscaling_policy.read", "scalable_dimension", "dynamodb:table:ReadCapacityUnits"),

testAccCheckAWSAppautoscalingPolicyExists("aws_appautoscaling_policy.write", &writePolicy),
resource.TestCheckResourceAttr("aws_appautoscaling_policy.write", "name", namePrefix+"-write"),
resource.TestCheckResourceAttr("aws_appautoscaling_policy.write", "service_namespace", "dynamodb"),
resource.TestCheckResourceAttr("aws_appautoscaling_policy.write", "scalable_dimension", "dynamodb:table:WriteCapacityUnits"),
),
},
},
})
}

func testAccCheckAWSAppautoscalingPolicyExists(n string, policy *applicationautoscaling.ScalingPolicy) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
Expand Down Expand Up @@ -525,3 +555,113 @@ resource "aws_appautoscaling_policy" "dynamo_test" {
}
`, randPolicyName, randPolicyName)
}

func testAccAWSAppautoscalingPolicy_multiplePolicies(tableName, namePrefix string) string {
return fmt.Sprintf(`
resource "aws_dynamodb_table" "dynamodb_table_test" {
name = "%s"
read_capacity = 5
write_capacity = 5
hash_key = "FooKey"
attribute {
name = "FooKey"
type = "S"
}
}
resource "aws_iam_role" "autoscale_role" {
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "application-autoscaling.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
resource "aws_iam_role_policy" "p" {
role = "${aws_iam_role.autoscale_role.name}"
policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:DescribeTable",
"dynamodb:UpdateTable",
"cloudwatch:PutMetricAlarm",
"cloudwatch:DescribeAlarms",
"cloudwatch:DeleteAlarms"
],
"Resource": "*"
}
]
}
POLICY
}
resource "aws_appautoscaling_target" "write" {
service_namespace = "dynamodb"
resource_id = "table/${aws_dynamodb_table.dynamodb_table_test.name}"
scalable_dimension = "dynamodb:table:WriteCapacityUnits"
role_arn = "${aws_iam_role.autoscale_role.arn}"
min_capacity = 1
max_capacity = 10
depends_on = ["aws_iam_role_policy.p"]
}
resource "aws_appautoscaling_policy" "write" {
name = "%s-write"
policy_type = "TargetTrackingScaling"
service_namespace = "dynamodb"
resource_id = "table/${aws_dynamodb_table.dynamodb_table_test.name}"
scalable_dimension = "dynamodb:table:WriteCapacityUnits"
target_tracking_scaling_policy_configuration {
predefined_metric_specification {
predefined_metric_type = "DynamoDBWriteCapacityUtilization"
}
scale_in_cooldown = 10
scale_out_cooldown = 10
target_value = 70
}
depends_on = ["aws_appautoscaling_target.write"]
}
resource "aws_appautoscaling_target" "read" {
service_namespace = "dynamodb"
resource_id = "table/${aws_dynamodb_table.dynamodb_table_test.name}"
scalable_dimension = "dynamodb:table:ReadCapacityUnits"
role_arn = "${aws_iam_role.autoscale_role.arn}"
min_capacity = 1
max_capacity = 10
depends_on = ["aws_iam_role_policy.p"]
}
resource "aws_appautoscaling_policy" "read" {
name = "%s-read"
policy_type = "TargetTrackingScaling"
service_namespace = "dynamodb"
resource_id = "table/${aws_dynamodb_table.dynamodb_table_test.name}"
scalable_dimension = "dynamodb:table:ReadCapacityUnits"
target_tracking_scaling_policy_configuration {
predefined_metric_specification {
predefined_metric_type = "DynamoDBReadCapacityUtilization"
}
scale_in_cooldown = 10
scale_out_cooldown = 10
target_value = 70
}
depends_on = ["aws_appautoscaling_target.read"]
}
`, tableName, namePrefix, namePrefix)
}
21 changes: 12 additions & 9 deletions aws/resource_aws_appautoscaling_target.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ func resourceAwsAppautoscalingTargetCreate(d *schema.ResourceData, meta interfac
func resourceAwsAppautoscalingTargetRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).appautoscalingconn

t, err := getAwsAppautoscalingTarget(d, conn)
namespace := d.Get("service_namespace").(string)
dimension := d.Get("scalable_dimension").(string)
t, err := getAwsAppautoscalingTarget(d.Id(), namespace, dimension, conn)
if err != nil {
return err
}
Expand All @@ -119,7 +121,10 @@ func resourceAwsAppautoscalingTargetRead(d *schema.ResourceData, meta interface{
func resourceAwsAppautoscalingTargetDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).appautoscalingconn

t, err := getAwsAppautoscalingTarget(d, conn)
namespace := d.Get("service_namespace").(string)
dimension := d.Get("scalable_dimension").(string)

t, err := getAwsAppautoscalingTarget(d.Id(), namespace, dimension, conn)
if err != nil {
return err
}
Expand Down Expand Up @@ -153,22 +158,20 @@ func resourceAwsAppautoscalingTargetDelete(d *schema.ResourceData, meta interfac
}

return resource.Retry(5*time.Minute, func() *resource.RetryError {
if t, _ = getAwsAppautoscalingTarget(d, conn); t != nil {
if t, _ = getAwsAppautoscalingTarget(d.Id(), namespace, dimension, conn); t != nil {
return resource.RetryableError(
fmt.Errorf("Application AutoScaling Target still exists"))
}
return nil
})
}

func getAwsAppautoscalingTarget(
d *schema.ResourceData,
func getAwsAppautoscalingTarget(resourceId, namespace, dimension string,
conn *applicationautoscaling.ApplicationAutoScaling) (*applicationautoscaling.ScalableTarget, error) {

tgtName := d.Id()
describeOpts := applicationautoscaling.DescribeScalableTargetsInput{
ResourceIds: []*string{aws.String(tgtName)},
ServiceNamespace: aws.String(d.Get("service_namespace").(string)),
ResourceIds: []*string{aws.String(resourceId)},
ServiceNamespace: aws.String(namespace),
}

log.Printf("[DEBUG] Application AutoScaling Target describe configuration: %#v", describeOpts)
Expand All @@ -181,7 +184,7 @@ func getAwsAppautoscalingTarget(
}

for idx, tgt := range describeTargets.ScalableTargets {
if *tgt.ResourceId == tgtName {
if *tgt.ResourceId == resourceId && *tgt.ScalableDimension == dimension {
return describeTargets.ScalableTargets[idx], nil
}
}
Expand Down
Loading

0 comments on commit 9b67079

Please sign in to comment.