From 33ded526859d75978fab016bcad3b286868b8df2 Mon Sep 17 00:00:00 2001 From: bill-rich Date: Thu, 29 Apr 2021 09:56:17 -0700 Subject: [PATCH 1/9] gomod --- go.mod | 2 ++ 1 file changed, 2 insertions(+) diff --git a/go.mod b/go.mod index c83c116f129..0288ff85c99 100644 --- a/go.mod +++ b/go.mod @@ -21,3 +21,5 @@ require ( github.com/pquerna/otp v1.3.0 gopkg.in/yaml.v2 v2.4.0 ) + +replace github.com/aws/aws-sdk-go => ../../aws/aws-sdk-go From 5467413fec1906cc6080d53124771517afdc9c00 Mon Sep 17 00:00:00 2001 From: bill-rich Date: Wed, 5 May 2021 23:08:44 -0700 Subject: [PATCH 2/9] Add support for predictive autoscaling. --- aws/resource_aws_autoscaling_policy.go | 142 +++++++++++++-- aws/resource_aws_autoscaling_policy_test.go | 168 ++++++++++++++++++ aws/structure.go | 140 +++++++++++++++ .../docs/r/autoscaling_policy.html.markdown | 42 ++++- 4 files changed, 481 insertions(+), 11 deletions(-) diff --git a/aws/resource_aws_autoscaling_policy.go b/aws/resource_aws_autoscaling_policy.go index 3b55f7b5bb4..97c6d6ee611 100644 --- a/aws/resource_aws_autoscaling_policy.go +++ b/aws/resource_aws_autoscaling_policy.go @@ -43,16 +43,6 @@ func resourceAwsAutoscalingPolicy() *schema.Resource { Required: true, ForceNew: true, }, - "policy_type": { - Type: schema.TypeString, - Optional: true, - Default: "SimpleScaling", // preserve AWS's default to make validation easier. - ValidateFunc: validation.StringInSlice([]string{ - "SimpleScaling", - "StepScaling", - "TargetTrackingScaling", - }, false), - }, "cooldown": { Type: schema.TypeInt, Optional: true, @@ -71,6 +61,131 @@ func resourceAwsAutoscalingPolicy() *schema.Resource { Optional: true, ValidateFunc: validation.IntAtLeast(1), }, + "policy_type": { + Type: schema.TypeString, + Optional: true, + Default: "SimpleScaling", // preserve AWS's default to make validation easier. + ValidateFunc: validation.StringInSlice([]string{ + "SimpleScaling", + "StepScaling", + "TargetTrackingScaling", + "PredictiveScaling", + }, false), + }, + "predictive_scaling_config": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "metric_specification": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "predefined_metric_pair_specification": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "predefined_metric_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + "ASGCPUUtilization", + "ASGNetworkIn", + "ASGNetworkOut", + "ALBRequestCount", + }, false), + }, + "resource_label": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + "predefined_scaling_metric_specification": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "predefined_metric_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + "ASGAverageCPUUtilization", + "ASGAverageNetworkIn", + "ASGAverageNetworkOut", + "ALBRequestCountPerTarget", + }, false), + }, + "resource_label": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + "predefined_load_metric_specification": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "predefined_metric_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + "ASGTotalCPUUtilization", + "ASGTotalNetworkIn", + "ASGTotalNetworkOut", + "ALBTargetGroupRequestCount", + }, false), + }, + "resource_label": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + "target_value": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + }, + "max_capacity_breach_behavior": { + Type: schema.TypeString, + Optional: true, + Default: "HonorMaxCapacity", + ValidateFunc: validation.StringInSlice([]string{ + "HonorMaxCapacity", + "IncreaseMaxCapacity", + }, false), + }, + "max_capacity_buffer": { + Type: schema.TypeInt, + Optional: true, + Default: 0, + ValidateFunc: validation.IntBetween(-1, 100), + }, + "mode": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + "ForecastOnly", + "ForecastAndScale", + }, false), + }, + "scheduling_buffer_time": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.IntAtLeast(0), + }, + }, + }, + }, "scaling_adjustment": { Type: schema.TypeInt, Optional: true, @@ -226,6 +341,9 @@ func resourceAwsAutoscalingPolicyRead(d *schema.ResourceData, meta interface{}) d.Set("arn", p.PolicyARN) d.Set("name", p.PolicyName) d.Set("scaling_adjustment", p.ScalingAdjustment) + if err := d.Set("predictive_scaling_config", flattenPredictiveScalingConfig(p.PredictiveScalingConfiguration)); err != nil { + return fmt.Errorf("error setting config: %s", err) + } if err := d.Set("step_adjustment", flattenStepAdjustments(p.StepAdjustments)); err != nil { return fmt.Errorf("error setting step_adjustment: %s", err) } @@ -309,6 +427,10 @@ func getAwsAutoscalingPutScalingPolicyInput(d *schema.ResourceData) (autoscaling params.AdjustmentType = aws.String(v.(string)) } + if predictiveScalingConfigFlat := d.Get("predictive_scaling_config").([]interface{}); len(predictiveScalingConfigFlat) > 0 { + params.PredictiveScalingConfiguration = expandPredictiveScalingConfig(predictiveScalingConfigFlat) + } + // This parameter is supported if the policy type is SimpleScaling. if v, ok := d.GetOkExists("cooldown"); ok { // 0 is allowed as placeholder even if policyType is not supported diff --git a/aws/resource_aws_autoscaling_policy_test.go b/aws/resource_aws_autoscaling_policy_test.go index c8f795f6654..152d3f8c9fa 100644 --- a/aws/resource_aws_autoscaling_policy_test.go +++ b/aws/resource_aws_autoscaling_policy_test.go @@ -103,6 +103,108 @@ func TestAccAWSAutoscalingPolicy_basic(t *testing.T) { }) } +func TestAccAWSAutoscalingPolicy_predictiveScaling(t *testing.T) { + var policy autoscaling.ScalingPolicy + + resourceSimpleName := "aws_autoscaling_policy.policy_predictive" + + name := fmt.Sprintf("terraform-testacc-asp-%s", acctest.RandString(5)) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ErrorCheck: testAccErrorCheck(t, autoscaling.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSAutoscalingPolicyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSAutoscalingPolicyConfig_predictiveScaling(name), + Check: resource.ComposeTestCheckFunc( + testAccCheckScalingPolicyExists(resourceSimpleName, &policy), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_config.#", "1"), + ), + }, + { + ResourceName: resourceSimpleName, + ImportState: true, + ImportStateIdFunc: testAccAWSAutoscalingPolicyImportStateIdFunc(resourceSimpleName), + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAWSAutoscalingPolicy_predictiveScalingRemoved(t *testing.T) { + var policy autoscaling.ScalingPolicy + + resourceSimpleName := "aws_autoscaling_policy.policy_predictive" + + name := fmt.Sprintf("terraform-testacc-asp-%s", acctest.RandString(5)) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ErrorCheck: testAccErrorCheck(t, autoscaling.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSAutoscalingPolicyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSAutoscalingPolicyConfig_predictiveScaling(name), + Check: resource.ComposeTestCheckFunc( + testAccCheckScalingPolicyExists(resourceSimpleName, &policy), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_config.#", "1"), + ), + }, + { + Config: testAccAWSAutoscalingPolicyConfig_predictiveScalingRemoved(name), + Check: resource.ComposeTestCheckFunc( + testAccCheckScalingPolicyExists(resourceSimpleName, &policy), + ), + }, + { + ResourceName: resourceSimpleName, + ImportState: true, + ImportStateIdFunc: testAccAWSAutoscalingPolicyImportStateIdFunc(resourceSimpleName), + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAWSAutoscalingPolicy_predictiveScalingUpdated(t *testing.T) { + var policy autoscaling.ScalingPolicy + + resourceSimpleName := "aws_autoscaling_policy.policy_predictive" + + name := fmt.Sprintf("terraform-testacc-asp-%s", acctest.RandString(5)) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ErrorCheck: testAccErrorCheck(t, autoscaling.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSAutoscalingPolicyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSAutoscalingPolicyConfig_predictiveScaling(name), + Check: resource.ComposeTestCheckFunc( + testAccCheckScalingPolicyExists(resourceSimpleName, &policy), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_config.#", "1"), + ), + }, + { + Config: testAccAWSAutoscalingPolicyConfig_predictiveScalingUpdated(name), + Check: resource.ComposeTestCheckFunc( + testAccCheckScalingPolicyExists(resourceSimpleName, &policy), + ), + }, + { + ResourceName: resourceSimpleName, + ImportState: true, + ImportStateIdFunc: testAccAWSAutoscalingPolicyImportStateIdFunc(resourceSimpleName), + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAWSAutoscalingPolicy_disappears(t *testing.T) { var policy autoscaling.ScalingPolicy @@ -433,6 +535,72 @@ resource "aws_autoscaling_policy" "foobar_target_tracking" { `, name, name, name) } +func testAccAWSAutoscalingPolicyConfig_predictiveScaling(name string) string { + return testAccAWSAutoscalingPolicyConfig_base(name) + fmt.Sprintf(` +resource "aws_autoscaling_policy" "policy_predictive" { + name = "%[1]s-policcy_predictive" + policy_type = "PredictiveScaling" + autoscaling_group_name = aws_autoscaling_group.test.name + predictive_scaling_config { + metric_specification { + target_value = 32 + predefined_scaling_metric_specification { + predefined_metric_type = "ASGAverageCPUUtilization" + resource_label = "testLabel" + } + predefined_load_metric_specification { + predefined_metric_type = "ASGTotalCPUUtilization" + resource_label = "testLabel" + } + } + mode = "ForecastAndScale" + scheduling_buffer_time = 10 + max_capacity_breach_behavior = "IncreaseMaxCapacity" + max_capacity_buffer = 10 + } +} +`, name) +} + +func testAccAWSAutoscalingPolicyConfig_predictiveScalingRemoved(name string) string { + return testAccAWSAutoscalingPolicyConfig_base(name) + fmt.Sprintf(` +resource "aws_autoscaling_policy" "policy_predictive" { + name = "%[1]s-foobar_simple" + adjustment_type = "ChangeInCapacity" + cooldown = 300 + policy_type = "SimpleScaling" + scaling_adjustment = 2 + autoscaling_group_name = aws_autoscaling_group.test.name +} +`, name) +} + +func testAccAWSAutoscalingPolicyConfig_predictiveScalingUpdated(name string) string { + return testAccAWSAutoscalingPolicyConfig_base(name) + fmt.Sprintf(` +resource "aws_autoscaling_policy" "policy_predictive" { + name = "%[1]s-policcy_predictive" + policy_type = "PredictiveScaling" + autoscaling_group_name = aws_autoscaling_group.test.name + predictive_scaling_config { + metric_specification { + target_value = 32 + predefined_scaling_metric_specification { + predefined_metric_type = "ASGAverageNetworkIn" + resource_label = "testLabel" + } + predefined_load_metric_specification { + predefined_metric_type = "ASGTotalNetworkIn" + resource_label = "testLabel" + } + } + mode = "ForecastOnly" + scheduling_buffer_time = 5 + max_capacity_breach_behavior = "HonorMaxCapacity" + } +} +`, name) +} + func testAccAWSAutoscalingPolicyConfig_basicUpdate(name string) string { return testAccAWSAutoscalingPolicyConfig_base(name) + fmt.Sprintf(` resource "aws_autoscaling_policy" "foobar_simple" { diff --git a/aws/structure.go b/aws/structure.go index f515bceca76..6cf00f837fd 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -523,6 +523,73 @@ func flattenAccessLog(l *elb.AccessLog) []map[string]interface{} { return result } +func expandPredictiveScalingConfig(predictiveScalingConfigSlice []interface{}) *autoscaling.PredictiveScalingConfiguration { + if predictiveScalingConfigSlice == nil || len(predictiveScalingConfigSlice) < 1 { + return nil + } + predictiveScalingConfigFlat := predictiveScalingConfigSlice[0].(map[string]interface{}) + predictiveScalingConfig := &autoscaling.PredictiveScalingConfiguration{ + MetricSpecifications: expandPredictiveScalingMetricSpecifications(predictiveScalingConfigFlat["metric_specification"].([]interface{})), + MaxCapacityBreachBehavior: aws.String(predictiveScalingConfigFlat["max_capacity_breach_behavior"].(string)), + Mode: aws.String(predictiveScalingConfigFlat["mode"].(string)), + SchedulingBufferTime: aws.Int64(int64(predictiveScalingConfigFlat["scheduling_buffer_time"].(int))), + } + if predictiveScalingConfigFlat["max_capacity_buffer"].(int) != 0 { + predictiveScalingConfig.MaxCapacityBuffer = aws.Int64(int64(predictiveScalingConfigFlat["max_capacity_buffer"].(int))) + } + return predictiveScalingConfig +} + +func expandPredictiveScalingMetricSpecifications(metricSpecificationsSlice []interface{}) []*autoscaling.PredictiveScalingMetricSpecification { + if metricSpecificationsSlice == nil || len(metricSpecificationsSlice) < 1 { + return nil + } + metricSpecificationsFlat := metricSpecificationsSlice[0].(map[string]interface{}) + metricSpecification := &autoscaling.PredictiveScalingMetricSpecification{ + PredefinedLoadMetricSpecification: expandPredefinedLoadMetricSpecification(metricSpecificationsFlat["predefined_load_metric_specification"].([]interface{})), + PredefinedMetricPairSpecification: expandPredefinedMetricPairSpecification(metricSpecificationsFlat["predefined_metric_pair_specification"].([]interface{})), + PredefinedScalingMetricSpecification: expandPredefinedScalingMetricSpecification(metricSpecificationsFlat["predefined_scaling_metric_specification"].([]interface{})), + TargetValue: aws.Float64(float64(metricSpecificationsFlat["target_value"].(int))), + } + return []*autoscaling.PredictiveScalingMetricSpecification{metricSpecification} +} + +func expandPredefinedLoadMetricSpecification(predefinedLoadMetricSpecificationSlice []interface{}) *autoscaling.PredefinedLoadMetricSpecification { + if predefinedLoadMetricSpecificationSlice == nil || len(predefinedLoadMetricSpecificationSlice) < 1 { + return nil + } + predefinedLoadMetricSpecificationFlat := predefinedLoadMetricSpecificationSlice[0].(map[string]interface{}) + predefinedLoadMetricSpecification := &autoscaling.PredefinedLoadMetricSpecification{ + PredefinedMetricType: aws.String(predefinedLoadMetricSpecificationFlat["predefined_metric_type"].(string)), + ResourceLabel: aws.String(predefinedLoadMetricSpecificationFlat["resource_label"].(string)), + } + return predefinedLoadMetricSpecification +} + +func expandPredefinedMetricPairSpecification(predefinedMetricPairSpecificationSlice []interface{}) *autoscaling.PredefinedMetricPairSpecification { + if predefinedMetricPairSpecificationSlice == nil || len(predefinedMetricPairSpecificationSlice) < 1 { + return nil + } + predefinedMetricPairSpecificationFlat := predefinedMetricPairSpecificationSlice[0].(map[string]interface{}) + predefinedMetricPairSpecification := &autoscaling.PredefinedMetricPairSpecification{ + PredefinedMetricType: aws.String(predefinedMetricPairSpecificationFlat["predefined_metric_type"].(string)), + ResourceLabel: aws.String(predefinedMetricPairSpecificationFlat["resource_label"].(string)), + } + return predefinedMetricPairSpecification +} + +func expandPredefinedScalingMetricSpecification(predefinedScalingMetricSpecificationSlice []interface{}) *autoscaling.PredefinedScalingMetricSpecification { + if predefinedScalingMetricSpecificationSlice == nil || len(predefinedScalingMetricSpecificationSlice) < 1 { + return nil + } + predefinedScalingMetricSpecificationFlat := predefinedScalingMetricSpecificationSlice[0].(map[string]interface{}) + predefinedScalingMetricSpecification := &autoscaling.PredefinedScalingMetricSpecification{ + PredefinedMetricType: aws.String(predefinedScalingMetricSpecificationFlat["predefined_metric_type"].(string)), + ResourceLabel: aws.String(predefinedScalingMetricSpecificationFlat["resource_label"].(string)), + } + return predefinedScalingMetricSpecification +} + // Takes the result of flatmap.Expand for an array of step adjustments and // returns a []*autoscaling.StepAdjustment. func expandStepAdjustments(configured []interface{}) ([]*autoscaling.StepAdjustment, error) { @@ -1221,6 +1288,79 @@ func flattenDaxSecurityGroupIds(securityGroups []*dax.SecurityGroupMembership) [ return result } +func flattenPredictiveScalingConfig(predictiveScalingConfig *autoscaling.PredictiveScalingConfiguration) []map[string]interface{} { + predictiveScalingConfigFlat := map[string]interface{}{} + if predictiveScalingConfig == nil { + return nil + } + if predictiveScalingConfig.MetricSpecifications != nil && len(predictiveScalingConfig.MetricSpecifications) > 0 { + predictiveScalingConfigFlat["metric_specification"] = flattenPredictiveScalingMetricSpecifications(predictiveScalingConfig.MetricSpecifications) + } + if predictiveScalingConfig.Mode != nil { + predictiveScalingConfigFlat["mode"] = aws.StringValue(predictiveScalingConfig.Mode) + } + if predictiveScalingConfig.SchedulingBufferTime != nil { + predictiveScalingConfigFlat["scheduling_buffer_time"] = aws.Int64Value(predictiveScalingConfig.SchedulingBufferTime) + } + if predictiveScalingConfig.MaxCapacityBreachBehavior != nil { + predictiveScalingConfigFlat["max_capacity_breach_behavior"] = aws.StringValue(predictiveScalingConfig.MaxCapacityBreachBehavior) + } + if predictiveScalingConfig.MaxCapacityBuffer != nil { + predictiveScalingConfigFlat["max_capacity_buffer"] = aws.Int64Value(predictiveScalingConfig.MaxCapacityBuffer) + } + return []map[string]interface{}{predictiveScalingConfigFlat} +} + +func flattenPredictiveScalingMetricSpecifications(metricSpecification []*autoscaling.PredictiveScalingMetricSpecification) []map[string]interface{} { + metricSpecificationFlat := map[string]interface{}{} + if metricSpecification == nil || len(metricSpecification) < 1 { + return []map[string]interface{}{metricSpecificationFlat} + } + if metricSpecification[0].TargetValue != nil { + metricSpecificationFlat["target_value"] = aws.Float64Value(metricSpecification[0].TargetValue) + } + if metricSpecification[0].PredefinedLoadMetricSpecification != nil { + metricSpecificationFlat["predefined_load_metric_specification"] = flattenPredefinedLoadMetricSpecification(metricSpecification[0].PredefinedLoadMetricSpecification) + } + if metricSpecification[0].PredefinedMetricPairSpecification != nil { + metricSpecificationFlat["predefined_metric_pair_specification"] = flattenPredefinedMetricPairSpecification(metricSpecification[0].PredefinedMetricPairSpecification) + } + if metricSpecification[0].PredefinedScalingMetricSpecification != nil { + metricSpecificationFlat["predefined_scaling_metric_specification"] = flattenPredefinedScalingMetricSpecification(metricSpecification[0].PredefinedScalingMetricSpecification) + } + return []map[string]interface{}{metricSpecificationFlat} +} + +func flattenPredefinedScalingMetricSpecification(predefinedScalingMetricSpecification *autoscaling.PredefinedScalingMetricSpecification) []map[string]interface{} { + predefinedScalingMetricSpecificationFlat := map[string]interface{}{} + if predefinedScalingMetricSpecification == nil { + return []map[string]interface{}{predefinedScalingMetricSpecificationFlat} + } + predefinedScalingMetricSpecificationFlat["predefined_metric_type"] = aws.StringValue(predefinedScalingMetricSpecification.PredefinedMetricType) + predefinedScalingMetricSpecificationFlat["resource_label"] = aws.StringValue(predefinedScalingMetricSpecification.ResourceLabel) + return []map[string]interface{}{predefinedScalingMetricSpecificationFlat} +} + +func flattenPredefinedLoadMetricSpecification(predefinedLoadMetricSpecification *autoscaling.PredefinedLoadMetricSpecification) []map[string]interface{} { + predefinedLoadMetricSpecificationFlat := map[string]interface{}{} + if predefinedLoadMetricSpecification == nil { + return []map[string]interface{}{predefinedLoadMetricSpecificationFlat} + } + predefinedLoadMetricSpecificationFlat["predefined_metric_type"] = aws.StringValue(predefinedLoadMetricSpecification.PredefinedMetricType) + predefinedLoadMetricSpecificationFlat["resource_label"] = aws.StringValue(predefinedLoadMetricSpecification.ResourceLabel) + return []map[string]interface{}{predefinedLoadMetricSpecificationFlat} +} + +func flattenPredefinedMetricPairSpecification(predefinedMetricPairSpecification *autoscaling.PredefinedMetricPairSpecification) []map[string]interface{} { + predefinedMetricPairSpecificationFlat := map[string]interface{}{} + if predefinedMetricPairSpecification == nil { + return []map[string]interface{}{predefinedMetricPairSpecificationFlat} + } + predefinedMetricPairSpecificationFlat["predefined_metric_type"] = aws.StringValue(predefinedMetricPairSpecification.PredefinedMetricType) + predefinedMetricPairSpecificationFlat["resource_label"] = aws.StringValue(predefinedMetricPairSpecification.ResourceLabel) + return []map[string]interface{}{predefinedMetricPairSpecificationFlat} +} + // Flattens step adjustments into a list of map[string]interface. func flattenStepAdjustments(adjustments []*autoscaling.StepAdjustment) []map[string]interface{} { result := make([]map[string]interface{}, 0, len(adjustments)) diff --git a/website/docs/r/autoscaling_policy.html.markdown b/website/docs/r/autoscaling_policy.html.markdown index 70c146513dc..62c3d9f446d 100644 --- a/website/docs/r/autoscaling_policy.html.markdown +++ b/website/docs/r/autoscaling_policy.html.markdown @@ -44,7 +44,8 @@ resource "aws_autoscaling_group" "bar" { * `name` - (Required) The name of the policy. * `autoscaling_group_name` - (Required) The name of the autoscaling group. * `adjustment_type` - (Optional) Specifies whether the adjustment is an absolute number or a percentage of the current capacity. Valid values are `ChangeInCapacity`, `ExactCapacity`, and `PercentChangeInCapacity`. -* `policy_type` - (Optional) The policy type, either "SimpleScaling", "StepScaling" or "TargetTrackingScaling". If this value isn't provided, AWS will default to "SimpleScaling." +* `policy_type` - (Optional) The policy type, either "SimpleScaling", "StepScaling", "TargetTrackingScaling", or "PredictiveScaling". If this value isn't provided, AWS will default to "SimpleScaling." +* `predictive_scaling_config` - (Optional) The predictive scaling policy configuration to use with Amazon EC2 Auto Scaling. * `estimated_instance_warmup` - (Optional) The estimated time, in seconds, until a newly launched instance will contribute CloudWatch metrics. Without a value, AWS will default to the group's specified cooldown period. The following argument is only available to "SimpleScaling" and "StepScaling" type policies: @@ -159,6 +160,45 @@ The following arguments are supported: * `name` - (Required) The name of the dimension. * `value` - (Required) The value of the dimension. +### predictive_scaling_config + +The following arguments are supported: + +* `max_capacity_breach_behavior` - (Optional) Defines the behavior that should be applied if the forecast capacity approaches or exceeds the maximum capacity of the Auto Scaling group. Valid values are `HonorMaxCapacity` or `IncreaseMaxCapacity`. Default is `HonorMaxCapacity`. +* `max_capacity_buffer` - (Optional) The size of the capacity buffer to use when the forecast capacity is close to or exceeds the maximum capacity. Valid range is `-1` to `100`. If set to `-1`, Amazon EC2 Auto Scaling may scale capacity higher than the maximum capacity to equal but not exceed forecast capacity. +* `metric_specification` - (Required) This structure includes the metrics and target utilization to use for predictive scaling. +* `mode` - (Optional) The predictive scaling mode. Valid values are `ForecastAndScale` and `ForecastOnly`. Default is `ForecastOnly`. +* `scheduling_buffer_time` - (Optional) The amount of time, in seconds, by which the instance launch time can be advanced. Minimum is `0`. + +#### metric_specification + +The following arguments are supported: + +* `predefined_load_metric_specification` - (Optional) The load metric specification. +* `predefined_metric_pair_specification` - (Optional) The metric pair specification from which Amazon EC2 Auto Scaling determines the appropriate scaling metric and load metric to use. +* `predefined_scaling_metric_specification` - (Optional) The scaling metric specification. + +##### predefined_load_metric_specification + +The following arguments are supported: + +* `predefinied_metric_type` - (Required) The metric type. Valid values are `ASGTotalCPUUtilization`, `ASGTotalNetworkIn`, `ASGTotalNetworkOut`, or `ALBTargetGroupRequestCount`. +* `resource_label` - (Optional) A label that uniquely identifies a specific Application Load Balancer target group from which to determine the request count served by your Auto Scaling group. + +##### predefined_metric_pair_specification + +The following arguments are supported: + +* `predefinied_metric_type` - (Required) Indicates which metrics to use. There are two different types of metrics for each metric type: one is a load metric and one is a scaling metric. For example, if the metric type is `ASGCPUUtilization`, the Auto Scaling group's total CPU metric is used as the load metric, and the average CPU metric is used for the scaling metric. Valid values are `ASGCPUUtilization`, `ASGNetworkIn`, `ASGNetworkOut`, or `ALBRequestCount`. +* `resource_label` - (Optional) A label that uniquely identifies a specific Application Load Balancer target group from which to determine the request count served by your Auto Scaling group. + +##### predefined_scaling_metric_specification + +The following arguments are supported: + +* `predefinied_metric_type` - (Required) Describes a scaling metric for a predictive scaling policy. Valid values are `ASGAverageCPUUtilization`, `ASGAverageNetworkIn`, `ASGAverageNetworkOut`, or `ALBRequestCountPerTarget`. +* `resource_label` - (Optional) A label that uniquely identifies a specific Application Load Balancer target group from which to determine the request count served by your Auto Scaling group. + ## Attributes Reference In addition to all arguments above, the following attributes are exported: From 8427d7ad5f918b36dbb42328cd5198b7aaa767c0 Mon Sep 17 00:00:00 2001 From: bill-rich Date: Fri, 7 May 2021 12:49:49 -0700 Subject: [PATCH 3/9] Fix formatting --- aws/resource_aws_autoscaling_policy_test.go | 30 ++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/aws/resource_aws_autoscaling_policy_test.go b/aws/resource_aws_autoscaling_policy_test.go index 152d3f8c9fa..4e17a49ec34 100644 --- a/aws/resource_aws_autoscaling_policy_test.go +++ b/aws/resource_aws_autoscaling_policy_test.go @@ -545,18 +545,18 @@ resource "aws_autoscaling_policy" "policy_predictive" { metric_specification { target_value = 32 predefined_scaling_metric_specification { - predefined_metric_type = "ASGAverageCPUUtilization" - resource_label = "testLabel" + predefined_metric_type = "ASGAverageCPUUtilization" + resource_label = "testLabel" } predefined_load_metric_specification { - predefined_metric_type = "ASGTotalCPUUtilization" - resource_label = "testLabel" + predefined_metric_type = "ASGTotalCPUUtilization" + resource_label = "testLabel" } } - mode = "ForecastAndScale" - scheduling_buffer_time = 10 - max_capacity_breach_behavior = "IncreaseMaxCapacity" - max_capacity_buffer = 10 + mode = "ForecastAndScale" + scheduling_buffer_time = 10 + max_capacity_breach_behavior = "IncreaseMaxCapacity" + max_capacity_buffer = 10 } } `, name) @@ -585,17 +585,17 @@ resource "aws_autoscaling_policy" "policy_predictive" { metric_specification { target_value = 32 predefined_scaling_metric_specification { - predefined_metric_type = "ASGAverageNetworkIn" - resource_label = "testLabel" + predefined_metric_type = "ASGAverageNetworkIn" + resource_label = "testLabel" } predefined_load_metric_specification { - predefined_metric_type = "ASGTotalNetworkIn" - resource_label = "testLabel" + predefined_metric_type = "ASGTotalNetworkIn" + resource_label = "testLabel" } } - mode = "ForecastOnly" - scheduling_buffer_time = 5 - max_capacity_breach_behavior = "HonorMaxCapacity" + mode = "ForecastOnly" + scheduling_buffer_time = 5 + max_capacity_breach_behavior = "HonorMaxCapacity" } } `, name) From 8e9db2a98aa632983dbb458a5440d65a104565a4 Mon Sep 17 00:00:00 2001 From: bill-rich Date: Mon, 10 May 2021 23:58:01 -0700 Subject: [PATCH 4/9] Address code review feedback --- aws/resource_aws_autoscaling_policy.go | 154 +++++++++++++++++- aws/resource_aws_autoscaling_policy_test.go | 69 +++++--- aws/structure.go | 140 ---------------- .../docs/r/autoscaling_policy.html.markdown | 10 +- 4 files changed, 202 insertions(+), 171 deletions(-) diff --git a/aws/resource_aws_autoscaling_policy.go b/aws/resource_aws_autoscaling_policy.go index 97c6d6ee611..b2866df34b2 100644 --- a/aws/resource_aws_autoscaling_policy.go +++ b/aws/resource_aws_autoscaling_policy.go @@ -72,19 +72,22 @@ func resourceAwsAutoscalingPolicy() *schema.Resource { "PredictiveScaling", }, false), }, - "predictive_scaling_config": { + "predictive_scaling_configuration": { Type: schema.TypeList, Optional: true, + MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "metric_specification": { Type: schema.TypeList, Required: true, + MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "predefined_metric_pair_specification": { Type: schema.TypeList, Optional: true, + MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "predefined_metric_type": { @@ -107,6 +110,7 @@ func resourceAwsAutoscalingPolicy() *schema.Resource { "predefined_scaling_metric_specification": { Type: schema.TypeList, Optional: true, + MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "predefined_metric_type": { @@ -129,6 +133,7 @@ func resourceAwsAutoscalingPolicy() *schema.Resource { "predefined_load_metric_specification": { Type: schema.TypeList, Optional: true, + MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "predefined_metric_type": { @@ -173,6 +178,7 @@ func resourceAwsAutoscalingPolicy() *schema.Resource { "mode": { Type: schema.TypeString, Optional: true, + Default: "ForecastOnly", ValidateFunc: validation.StringInSlice([]string{ "ForecastOnly", "ForecastAndScale", @@ -341,8 +347,8 @@ func resourceAwsAutoscalingPolicyRead(d *schema.ResourceData, meta interface{}) d.Set("arn", p.PolicyARN) d.Set("name", p.PolicyName) d.Set("scaling_adjustment", p.ScalingAdjustment) - if err := d.Set("predictive_scaling_config", flattenPredictiveScalingConfig(p.PredictiveScalingConfiguration)); err != nil { - return fmt.Errorf("error setting config: %s", err) + if err := d.Set("predictive_scaling_configuration", flattenPredictiveScalingConfig(p.PredictiveScalingConfiguration)); err != nil { + return fmt.Errorf("error setting predictive_scaling_configuration: %s", err) } if err := d.Set("step_adjustment", flattenStepAdjustments(p.StepAdjustments)); err != nil { return fmt.Errorf("error setting step_adjustment: %s", err) @@ -427,7 +433,7 @@ func getAwsAutoscalingPutScalingPolicyInput(d *schema.ResourceData) (autoscaling params.AdjustmentType = aws.String(v.(string)) } - if predictiveScalingConfigFlat := d.Get("predictive_scaling_config").([]interface{}); len(predictiveScalingConfigFlat) > 0 { + if predictiveScalingConfigFlat := d.Get("predictive_scaling_configuration").([]interface{}); len(predictiveScalingConfigFlat) > 0 { params.PredictiveScalingConfiguration = expandPredictiveScalingConfig(predictiveScalingConfigFlat) } @@ -604,6 +610,73 @@ func expandTargetTrackingConfiguration(configs []interface{}) *autoscaling.Targe return result } +func expandPredictiveScalingConfig(predictiveScalingConfigSlice []interface{}) *autoscaling.PredictiveScalingConfiguration { + if predictiveScalingConfigSlice == nil || len(predictiveScalingConfigSlice) < 1 { + return nil + } + predictiveScalingConfigFlat := predictiveScalingConfigSlice[0].(map[string]interface{}) + predictiveScalingConfig := &autoscaling.PredictiveScalingConfiguration{ + MetricSpecifications: expandPredictiveScalingMetricSpecifications(predictiveScalingConfigFlat["metric_specification"].([]interface{})), + MaxCapacityBreachBehavior: aws.String(predictiveScalingConfigFlat["max_capacity_breach_behavior"].(string)), + Mode: aws.String(predictiveScalingConfigFlat["mode"].(string)), + SchedulingBufferTime: aws.Int64(int64(predictiveScalingConfigFlat["scheduling_buffer_time"].(int))), + } + if predictiveScalingConfigFlat["max_capacity_buffer"].(int) != 0 { + predictiveScalingConfig.MaxCapacityBuffer = aws.Int64(int64(predictiveScalingConfigFlat["max_capacity_buffer"].(int))) + } + return predictiveScalingConfig +} + +func expandPredictiveScalingMetricSpecifications(metricSpecificationsSlice []interface{}) []*autoscaling.PredictiveScalingMetricSpecification { + if metricSpecificationsSlice == nil || len(metricSpecificationsSlice) < 1 { + return nil + } + metricSpecificationsFlat := metricSpecificationsSlice[0].(map[string]interface{}) + metricSpecification := &autoscaling.PredictiveScalingMetricSpecification{ + PredefinedLoadMetricSpecification: expandPredefinedLoadMetricSpecification(metricSpecificationsFlat["predefined_load_metric_specification"].([]interface{})), + PredefinedMetricPairSpecification: expandPredefinedMetricPairSpecification(metricSpecificationsFlat["predefined_metric_pair_specification"].([]interface{})), + PredefinedScalingMetricSpecification: expandPredefinedScalingMetricSpecification(metricSpecificationsFlat["predefined_scaling_metric_specification"].([]interface{})), + TargetValue: aws.Float64(float64(metricSpecificationsFlat["target_value"].(int))), + } + return []*autoscaling.PredictiveScalingMetricSpecification{metricSpecification} +} + +func expandPredefinedLoadMetricSpecification(predefinedLoadMetricSpecificationSlice []interface{}) *autoscaling.PredefinedLoadMetricSpecification { + if predefinedLoadMetricSpecificationSlice == nil || len(predefinedLoadMetricSpecificationSlice) < 1 { + return nil + } + predefinedLoadMetricSpecificationFlat := predefinedLoadMetricSpecificationSlice[0].(map[string]interface{}) + predefinedLoadMetricSpecification := &autoscaling.PredefinedLoadMetricSpecification{ + PredefinedMetricType: aws.String(predefinedLoadMetricSpecificationFlat["predefined_metric_type"].(string)), + ResourceLabel: aws.String(predefinedLoadMetricSpecificationFlat["resource_label"].(string)), + } + return predefinedLoadMetricSpecification +} + +func expandPredefinedMetricPairSpecification(predefinedMetricPairSpecificationSlice []interface{}) *autoscaling.PredefinedMetricPairSpecification { + if predefinedMetricPairSpecificationSlice == nil || len(predefinedMetricPairSpecificationSlice) < 1 { + return nil + } + predefinedMetricPairSpecificationFlat := predefinedMetricPairSpecificationSlice[0].(map[string]interface{}) + predefinedMetricPairSpecification := &autoscaling.PredefinedMetricPairSpecification{ + PredefinedMetricType: aws.String(predefinedMetricPairSpecificationFlat["predefined_metric_type"].(string)), + ResourceLabel: aws.String(predefinedMetricPairSpecificationFlat["resource_label"].(string)), + } + return predefinedMetricPairSpecification +} + +func expandPredefinedScalingMetricSpecification(predefinedScalingMetricSpecificationSlice []interface{}) *autoscaling.PredefinedScalingMetricSpecification { + if predefinedScalingMetricSpecificationSlice == nil || len(predefinedScalingMetricSpecificationSlice) < 1 { + return nil + } + predefinedScalingMetricSpecificationFlat := predefinedScalingMetricSpecificationSlice[0].(map[string]interface{}) + predefinedScalingMetricSpecification := &autoscaling.PredefinedScalingMetricSpecification{ + PredefinedMetricType: aws.String(predefinedScalingMetricSpecificationFlat["predefined_metric_type"].(string)), + ResourceLabel: aws.String(predefinedScalingMetricSpecificationFlat["resource_label"].(string)), + } + return predefinedScalingMetricSpecification +} + func flattenTargetTrackingConfiguration(config *autoscaling.TargetTrackingConfiguration) []interface{} { if config == nil { return []interface{}{} @@ -643,3 +716,76 @@ func flattenTargetTrackingConfiguration(config *autoscaling.TargetTrackingConfig } return []interface{}{result} } + +func flattenPredictiveScalingConfig(predictiveScalingConfig *autoscaling.PredictiveScalingConfiguration) []map[string]interface{} { + predictiveScalingConfigFlat := map[string]interface{}{} + if predictiveScalingConfig == nil { + return nil + } + if predictiveScalingConfig.MetricSpecifications != nil && len(predictiveScalingConfig.MetricSpecifications) > 0 { + predictiveScalingConfigFlat["metric_specification"] = flattenPredictiveScalingMetricSpecifications(predictiveScalingConfig.MetricSpecifications) + } + if predictiveScalingConfig.Mode != nil { + predictiveScalingConfigFlat["mode"] = aws.StringValue(predictiveScalingConfig.Mode) + } + if predictiveScalingConfig.SchedulingBufferTime != nil { + predictiveScalingConfigFlat["scheduling_buffer_time"] = aws.Int64Value(predictiveScalingConfig.SchedulingBufferTime) + } + if predictiveScalingConfig.MaxCapacityBreachBehavior != nil { + predictiveScalingConfigFlat["max_capacity_breach_behavior"] = aws.StringValue(predictiveScalingConfig.MaxCapacityBreachBehavior) + } + if predictiveScalingConfig.MaxCapacityBuffer != nil { + predictiveScalingConfigFlat["max_capacity_buffer"] = aws.Int64Value(predictiveScalingConfig.MaxCapacityBuffer) + } + return []map[string]interface{}{predictiveScalingConfigFlat} +} + +func flattenPredictiveScalingMetricSpecifications(metricSpecification []*autoscaling.PredictiveScalingMetricSpecification) []map[string]interface{} { + metricSpecificationFlat := map[string]interface{}{} + if metricSpecification == nil || len(metricSpecification) < 1 { + return []map[string]interface{}{metricSpecificationFlat} + } + if metricSpecification[0].TargetValue != nil { + metricSpecificationFlat["target_value"] = aws.Float64Value(metricSpecification[0].TargetValue) + } + if metricSpecification[0].PredefinedLoadMetricSpecification != nil { + metricSpecificationFlat["predefined_load_metric_specification"] = flattenPredefinedLoadMetricSpecification(metricSpecification[0].PredefinedLoadMetricSpecification) + } + if metricSpecification[0].PredefinedMetricPairSpecification != nil { + metricSpecificationFlat["predefined_metric_pair_specification"] = flattenPredefinedMetricPairSpecification(metricSpecification[0].PredefinedMetricPairSpecification) + } + if metricSpecification[0].PredefinedScalingMetricSpecification != nil { + metricSpecificationFlat["predefined_scaling_metric_specification"] = flattenPredefinedScalingMetricSpecification(metricSpecification[0].PredefinedScalingMetricSpecification) + } + return []map[string]interface{}{metricSpecificationFlat} +} + +func flattenPredefinedScalingMetricSpecification(predefinedScalingMetricSpecification *autoscaling.PredefinedScalingMetricSpecification) []map[string]interface{} { + predefinedScalingMetricSpecificationFlat := map[string]interface{}{} + if predefinedScalingMetricSpecification == nil { + return []map[string]interface{}{predefinedScalingMetricSpecificationFlat} + } + predefinedScalingMetricSpecificationFlat["predefined_metric_type"] = aws.StringValue(predefinedScalingMetricSpecification.PredefinedMetricType) + predefinedScalingMetricSpecificationFlat["resource_label"] = aws.StringValue(predefinedScalingMetricSpecification.ResourceLabel) + return []map[string]interface{}{predefinedScalingMetricSpecificationFlat} +} + +func flattenPredefinedLoadMetricSpecification(predefinedLoadMetricSpecification *autoscaling.PredefinedLoadMetricSpecification) []map[string]interface{} { + predefinedLoadMetricSpecificationFlat := map[string]interface{}{} + if predefinedLoadMetricSpecification == nil { + return []map[string]interface{}{predefinedLoadMetricSpecificationFlat} + } + predefinedLoadMetricSpecificationFlat["predefined_metric_type"] = aws.StringValue(predefinedLoadMetricSpecification.PredefinedMetricType) + predefinedLoadMetricSpecificationFlat["resource_label"] = aws.StringValue(predefinedLoadMetricSpecification.ResourceLabel) + return []map[string]interface{}{predefinedLoadMetricSpecificationFlat} +} + +func flattenPredefinedMetricPairSpecification(predefinedMetricPairSpecification *autoscaling.PredefinedMetricPairSpecification) []map[string]interface{} { + predefinedMetricPairSpecificationFlat := map[string]interface{}{} + if predefinedMetricPairSpecification == nil { + return []map[string]interface{}{predefinedMetricPairSpecificationFlat} + } + predefinedMetricPairSpecificationFlat["predefined_metric_type"] = aws.StringValue(predefinedMetricPairSpecification.PredefinedMetricType) + predefinedMetricPairSpecificationFlat["resource_label"] = aws.StringValue(predefinedMetricPairSpecification.ResourceLabel) + return []map[string]interface{}{predefinedMetricPairSpecificationFlat} +} diff --git a/aws/resource_aws_autoscaling_policy_test.go b/aws/resource_aws_autoscaling_policy_test.go index 4e17a49ec34..db8223e878d 100644 --- a/aws/resource_aws_autoscaling_policy_test.go +++ b/aws/resource_aws_autoscaling_policy_test.go @@ -106,9 +106,9 @@ func TestAccAWSAutoscalingPolicy_basic(t *testing.T) { func TestAccAWSAutoscalingPolicy_predictiveScaling(t *testing.T) { var policy autoscaling.ScalingPolicy - resourceSimpleName := "aws_autoscaling_policy.policy_predictive" + resourceSimpleName := "aws_autoscaling_policy.test" - name := fmt.Sprintf("terraform-testacc-asp-%s", acctest.RandString(5)) + name := acctest.RandomWithPrefix("terraform-testacc-asp") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -120,7 +120,15 @@ func TestAccAWSAutoscalingPolicy_predictiveScaling(t *testing.T) { Config: testAccAWSAutoscalingPolicyConfig_predictiveScaling(name), Check: resource.ComposeTestCheckFunc( testAccCheckScalingPolicyExists(resourceSimpleName, &policy), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_config.#", "1"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.mode", "ForecastAndScale"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.scheduling_buffer_time", "10"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.max_capacity_breach_behavior", "IncreaseMaxCapacity"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.max_capacity_buffer", "10"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.target_value", "32"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_scaling_metric_specification.0.predefined_metric_type", "ASGAverageCPUUtilization"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_scaling_metric_specification.0.resource_label", "testLabel"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_load_metric_specification.0.predefined_metric_type", "ASGTotalCPUUtilization"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_load_metric_specification.0.resource_label", "testLabel"), ), }, { @@ -136,9 +144,9 @@ func TestAccAWSAutoscalingPolicy_predictiveScaling(t *testing.T) { func TestAccAWSAutoscalingPolicy_predictiveScalingRemoved(t *testing.T) { var policy autoscaling.ScalingPolicy - resourceSimpleName := "aws_autoscaling_policy.policy_predictive" + resourceSimpleName := "aws_autoscaling_policy.test" - name := fmt.Sprintf("terraform-testacc-asp-%s", acctest.RandString(5)) + name := acctest.RandomWithPrefix("terraform-testacc-asp") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -150,13 +158,14 @@ func TestAccAWSAutoscalingPolicy_predictiveScalingRemoved(t *testing.T) { Config: testAccAWSAutoscalingPolicyConfig_predictiveScaling(name), Check: resource.ComposeTestCheckFunc( testAccCheckScalingPolicyExists(resourceSimpleName, &policy), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_config.#", "1"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.#", "1"), ), }, { Config: testAccAWSAutoscalingPolicyConfig_predictiveScalingRemoved(name), Check: resource.ComposeTestCheckFunc( testAccCheckScalingPolicyExists(resourceSimpleName, &policy), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.#", "0"), ), }, { @@ -172,9 +181,9 @@ func TestAccAWSAutoscalingPolicy_predictiveScalingRemoved(t *testing.T) { func TestAccAWSAutoscalingPolicy_predictiveScalingUpdated(t *testing.T) { var policy autoscaling.ScalingPolicy - resourceSimpleName := "aws_autoscaling_policy.policy_predictive" + resourceSimpleName := "aws_autoscaling_policy.test" - name := fmt.Sprintf("terraform-testacc-asp-%s", acctest.RandString(5)) + name := acctest.RandomWithPrefix("terraform-testacc-asp") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -186,13 +195,29 @@ func TestAccAWSAutoscalingPolicy_predictiveScalingUpdated(t *testing.T) { Config: testAccAWSAutoscalingPolicyConfig_predictiveScaling(name), Check: resource.ComposeTestCheckFunc( testAccCheckScalingPolicyExists(resourceSimpleName, &policy), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_config.#", "1"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.mode", "ForecastAndScale"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.scheduling_buffer_time", "10"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.max_capacity_breach_behavior", "IncreaseMaxCapacity"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.max_capacity_buffer", "10"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.target_value", "32"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_scaling_metric_specification.0.predefined_metric_type", "ASGAverageCPUUtilization"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_scaling_metric_specification.0.resource_label", "testLabel"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_load_metric_specification.0.predefined_metric_type", "ASGTotalCPUUtilization"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_load_metric_specification.0.resource_label", "testLabel"), ), }, { Config: testAccAWSAutoscalingPolicyConfig_predictiveScalingUpdated(name), Check: resource.ComposeTestCheckFunc( testAccCheckScalingPolicyExists(resourceSimpleName, &policy), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.mode", "ForecastOnly"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.scheduling_buffer_time", "5"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.max_capacity_breach_behavior", "HonorMaxCapacity"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.target_value", "32"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_scaling_metric_specification.0.predefined_metric_type", "ASGAverageNetworkIn"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_scaling_metric_specification.0.resource_label", "testLabel"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_load_metric_specification.0.predefined_metric_type", "ASGTotalNetworkIn"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_load_metric_specification.0.resource_label", "testLabel"), ), }, { @@ -494,7 +519,7 @@ resource "aws_autoscaling_group" "test" { } func testAccAWSAutoscalingPolicyConfig_basic(name string) string { - return testAccAWSAutoscalingPolicyConfig_base(name) + fmt.Sprintf(` + return composeConfig(testAccAWSAutoscalingPolicyConfig_base(name), fmt.Sprintf(` resource "aws_autoscaling_policy" "foobar_simple" { name = "%s-foobar_simple" adjustment_type = "ChangeInCapacity" @@ -532,16 +557,16 @@ resource "aws_autoscaling_policy" "foobar_target_tracking" { target_value = 40.0 } } -`, name, name, name) +`, name, name, name)) } func testAccAWSAutoscalingPolicyConfig_predictiveScaling(name string) string { - return testAccAWSAutoscalingPolicyConfig_base(name) + fmt.Sprintf(` -resource "aws_autoscaling_policy" "policy_predictive" { - name = "%[1]s-policcy_predictive" + return composeConfig(testAccAWSAutoscalingPolicyConfig_base(name), fmt.Sprintf(` +resource "aws_autoscaling_policy" "test" { + name = "%[1]s-policy_predictive" policy_type = "PredictiveScaling" autoscaling_group_name = aws_autoscaling_group.test.name - predictive_scaling_config { + predictive_scaling_configuration { metric_specification { target_value = 32 predefined_scaling_metric_specification { @@ -559,12 +584,12 @@ resource "aws_autoscaling_policy" "policy_predictive" { max_capacity_buffer = 10 } } -`, name) +`, name)) } func testAccAWSAutoscalingPolicyConfig_predictiveScalingRemoved(name string) string { - return testAccAWSAutoscalingPolicyConfig_base(name) + fmt.Sprintf(` -resource "aws_autoscaling_policy" "policy_predictive" { + return composeConfig(testAccAWSAutoscalingPolicyConfig_base(name), fmt.Sprintf(` +resource "aws_autoscaling_policy" "test" { name = "%[1]s-foobar_simple" adjustment_type = "ChangeInCapacity" cooldown = 300 @@ -572,16 +597,16 @@ resource "aws_autoscaling_policy" "policy_predictive" { scaling_adjustment = 2 autoscaling_group_name = aws_autoscaling_group.test.name } -`, name) +`, name)) } func testAccAWSAutoscalingPolicyConfig_predictiveScalingUpdated(name string) string { return testAccAWSAutoscalingPolicyConfig_base(name) + fmt.Sprintf(` -resource "aws_autoscaling_policy" "policy_predictive" { - name = "%[1]s-policcy_predictive" +resource "aws_autoscaling_policy" "test" { + name = "%[1]s-policy_predictive" policy_type = "PredictiveScaling" autoscaling_group_name = aws_autoscaling_group.test.name - predictive_scaling_config { + predictive_scaling_configuration { metric_specification { target_value = 32 predefined_scaling_metric_specification { diff --git a/aws/structure.go b/aws/structure.go index 6cf00f837fd..f515bceca76 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -523,73 +523,6 @@ func flattenAccessLog(l *elb.AccessLog) []map[string]interface{} { return result } -func expandPredictiveScalingConfig(predictiveScalingConfigSlice []interface{}) *autoscaling.PredictiveScalingConfiguration { - if predictiveScalingConfigSlice == nil || len(predictiveScalingConfigSlice) < 1 { - return nil - } - predictiveScalingConfigFlat := predictiveScalingConfigSlice[0].(map[string]interface{}) - predictiveScalingConfig := &autoscaling.PredictiveScalingConfiguration{ - MetricSpecifications: expandPredictiveScalingMetricSpecifications(predictiveScalingConfigFlat["metric_specification"].([]interface{})), - MaxCapacityBreachBehavior: aws.String(predictiveScalingConfigFlat["max_capacity_breach_behavior"].(string)), - Mode: aws.String(predictiveScalingConfigFlat["mode"].(string)), - SchedulingBufferTime: aws.Int64(int64(predictiveScalingConfigFlat["scheduling_buffer_time"].(int))), - } - if predictiveScalingConfigFlat["max_capacity_buffer"].(int) != 0 { - predictiveScalingConfig.MaxCapacityBuffer = aws.Int64(int64(predictiveScalingConfigFlat["max_capacity_buffer"].(int))) - } - return predictiveScalingConfig -} - -func expandPredictiveScalingMetricSpecifications(metricSpecificationsSlice []interface{}) []*autoscaling.PredictiveScalingMetricSpecification { - if metricSpecificationsSlice == nil || len(metricSpecificationsSlice) < 1 { - return nil - } - metricSpecificationsFlat := metricSpecificationsSlice[0].(map[string]interface{}) - metricSpecification := &autoscaling.PredictiveScalingMetricSpecification{ - PredefinedLoadMetricSpecification: expandPredefinedLoadMetricSpecification(metricSpecificationsFlat["predefined_load_metric_specification"].([]interface{})), - PredefinedMetricPairSpecification: expandPredefinedMetricPairSpecification(metricSpecificationsFlat["predefined_metric_pair_specification"].([]interface{})), - PredefinedScalingMetricSpecification: expandPredefinedScalingMetricSpecification(metricSpecificationsFlat["predefined_scaling_metric_specification"].([]interface{})), - TargetValue: aws.Float64(float64(metricSpecificationsFlat["target_value"].(int))), - } - return []*autoscaling.PredictiveScalingMetricSpecification{metricSpecification} -} - -func expandPredefinedLoadMetricSpecification(predefinedLoadMetricSpecificationSlice []interface{}) *autoscaling.PredefinedLoadMetricSpecification { - if predefinedLoadMetricSpecificationSlice == nil || len(predefinedLoadMetricSpecificationSlice) < 1 { - return nil - } - predefinedLoadMetricSpecificationFlat := predefinedLoadMetricSpecificationSlice[0].(map[string]interface{}) - predefinedLoadMetricSpecification := &autoscaling.PredefinedLoadMetricSpecification{ - PredefinedMetricType: aws.String(predefinedLoadMetricSpecificationFlat["predefined_metric_type"].(string)), - ResourceLabel: aws.String(predefinedLoadMetricSpecificationFlat["resource_label"].(string)), - } - return predefinedLoadMetricSpecification -} - -func expandPredefinedMetricPairSpecification(predefinedMetricPairSpecificationSlice []interface{}) *autoscaling.PredefinedMetricPairSpecification { - if predefinedMetricPairSpecificationSlice == nil || len(predefinedMetricPairSpecificationSlice) < 1 { - return nil - } - predefinedMetricPairSpecificationFlat := predefinedMetricPairSpecificationSlice[0].(map[string]interface{}) - predefinedMetricPairSpecification := &autoscaling.PredefinedMetricPairSpecification{ - PredefinedMetricType: aws.String(predefinedMetricPairSpecificationFlat["predefined_metric_type"].(string)), - ResourceLabel: aws.String(predefinedMetricPairSpecificationFlat["resource_label"].(string)), - } - return predefinedMetricPairSpecification -} - -func expandPredefinedScalingMetricSpecification(predefinedScalingMetricSpecificationSlice []interface{}) *autoscaling.PredefinedScalingMetricSpecification { - if predefinedScalingMetricSpecificationSlice == nil || len(predefinedScalingMetricSpecificationSlice) < 1 { - return nil - } - predefinedScalingMetricSpecificationFlat := predefinedScalingMetricSpecificationSlice[0].(map[string]interface{}) - predefinedScalingMetricSpecification := &autoscaling.PredefinedScalingMetricSpecification{ - PredefinedMetricType: aws.String(predefinedScalingMetricSpecificationFlat["predefined_metric_type"].(string)), - ResourceLabel: aws.String(predefinedScalingMetricSpecificationFlat["resource_label"].(string)), - } - return predefinedScalingMetricSpecification -} - // Takes the result of flatmap.Expand for an array of step adjustments and // returns a []*autoscaling.StepAdjustment. func expandStepAdjustments(configured []interface{}) ([]*autoscaling.StepAdjustment, error) { @@ -1288,79 +1221,6 @@ func flattenDaxSecurityGroupIds(securityGroups []*dax.SecurityGroupMembership) [ return result } -func flattenPredictiveScalingConfig(predictiveScalingConfig *autoscaling.PredictiveScalingConfiguration) []map[string]interface{} { - predictiveScalingConfigFlat := map[string]interface{}{} - if predictiveScalingConfig == nil { - return nil - } - if predictiveScalingConfig.MetricSpecifications != nil && len(predictiveScalingConfig.MetricSpecifications) > 0 { - predictiveScalingConfigFlat["metric_specification"] = flattenPredictiveScalingMetricSpecifications(predictiveScalingConfig.MetricSpecifications) - } - if predictiveScalingConfig.Mode != nil { - predictiveScalingConfigFlat["mode"] = aws.StringValue(predictiveScalingConfig.Mode) - } - if predictiveScalingConfig.SchedulingBufferTime != nil { - predictiveScalingConfigFlat["scheduling_buffer_time"] = aws.Int64Value(predictiveScalingConfig.SchedulingBufferTime) - } - if predictiveScalingConfig.MaxCapacityBreachBehavior != nil { - predictiveScalingConfigFlat["max_capacity_breach_behavior"] = aws.StringValue(predictiveScalingConfig.MaxCapacityBreachBehavior) - } - if predictiveScalingConfig.MaxCapacityBuffer != nil { - predictiveScalingConfigFlat["max_capacity_buffer"] = aws.Int64Value(predictiveScalingConfig.MaxCapacityBuffer) - } - return []map[string]interface{}{predictiveScalingConfigFlat} -} - -func flattenPredictiveScalingMetricSpecifications(metricSpecification []*autoscaling.PredictiveScalingMetricSpecification) []map[string]interface{} { - metricSpecificationFlat := map[string]interface{}{} - if metricSpecification == nil || len(metricSpecification) < 1 { - return []map[string]interface{}{metricSpecificationFlat} - } - if metricSpecification[0].TargetValue != nil { - metricSpecificationFlat["target_value"] = aws.Float64Value(metricSpecification[0].TargetValue) - } - if metricSpecification[0].PredefinedLoadMetricSpecification != nil { - metricSpecificationFlat["predefined_load_metric_specification"] = flattenPredefinedLoadMetricSpecification(metricSpecification[0].PredefinedLoadMetricSpecification) - } - if metricSpecification[0].PredefinedMetricPairSpecification != nil { - metricSpecificationFlat["predefined_metric_pair_specification"] = flattenPredefinedMetricPairSpecification(metricSpecification[0].PredefinedMetricPairSpecification) - } - if metricSpecification[0].PredefinedScalingMetricSpecification != nil { - metricSpecificationFlat["predefined_scaling_metric_specification"] = flattenPredefinedScalingMetricSpecification(metricSpecification[0].PredefinedScalingMetricSpecification) - } - return []map[string]interface{}{metricSpecificationFlat} -} - -func flattenPredefinedScalingMetricSpecification(predefinedScalingMetricSpecification *autoscaling.PredefinedScalingMetricSpecification) []map[string]interface{} { - predefinedScalingMetricSpecificationFlat := map[string]interface{}{} - if predefinedScalingMetricSpecification == nil { - return []map[string]interface{}{predefinedScalingMetricSpecificationFlat} - } - predefinedScalingMetricSpecificationFlat["predefined_metric_type"] = aws.StringValue(predefinedScalingMetricSpecification.PredefinedMetricType) - predefinedScalingMetricSpecificationFlat["resource_label"] = aws.StringValue(predefinedScalingMetricSpecification.ResourceLabel) - return []map[string]interface{}{predefinedScalingMetricSpecificationFlat} -} - -func flattenPredefinedLoadMetricSpecification(predefinedLoadMetricSpecification *autoscaling.PredefinedLoadMetricSpecification) []map[string]interface{} { - predefinedLoadMetricSpecificationFlat := map[string]interface{}{} - if predefinedLoadMetricSpecification == nil { - return []map[string]interface{}{predefinedLoadMetricSpecificationFlat} - } - predefinedLoadMetricSpecificationFlat["predefined_metric_type"] = aws.StringValue(predefinedLoadMetricSpecification.PredefinedMetricType) - predefinedLoadMetricSpecificationFlat["resource_label"] = aws.StringValue(predefinedLoadMetricSpecification.ResourceLabel) - return []map[string]interface{}{predefinedLoadMetricSpecificationFlat} -} - -func flattenPredefinedMetricPairSpecification(predefinedMetricPairSpecification *autoscaling.PredefinedMetricPairSpecification) []map[string]interface{} { - predefinedMetricPairSpecificationFlat := map[string]interface{}{} - if predefinedMetricPairSpecification == nil { - return []map[string]interface{}{predefinedMetricPairSpecificationFlat} - } - predefinedMetricPairSpecificationFlat["predefined_metric_type"] = aws.StringValue(predefinedMetricPairSpecification.PredefinedMetricType) - predefinedMetricPairSpecificationFlat["resource_label"] = aws.StringValue(predefinedMetricPairSpecification.ResourceLabel) - return []map[string]interface{}{predefinedMetricPairSpecificationFlat} -} - // Flattens step adjustments into a list of map[string]interface. func flattenStepAdjustments(adjustments []*autoscaling.StepAdjustment) []map[string]interface{} { result := make([]map[string]interface{}, 0, len(adjustments)) diff --git a/website/docs/r/autoscaling_policy.html.markdown b/website/docs/r/autoscaling_policy.html.markdown index 62c3d9f446d..d3bf4cb8f5d 100644 --- a/website/docs/r/autoscaling_policy.html.markdown +++ b/website/docs/r/autoscaling_policy.html.markdown @@ -45,7 +45,7 @@ resource "aws_autoscaling_group" "bar" { * `autoscaling_group_name` - (Required) The name of the autoscaling group. * `adjustment_type` - (Optional) Specifies whether the adjustment is an absolute number or a percentage of the current capacity. Valid values are `ChangeInCapacity`, `ExactCapacity`, and `PercentChangeInCapacity`. * `policy_type` - (Optional) The policy type, either "SimpleScaling", "StepScaling", "TargetTrackingScaling", or "PredictiveScaling". If this value isn't provided, AWS will default to "SimpleScaling." -* `predictive_scaling_config` - (Optional) The predictive scaling policy configuration to use with Amazon EC2 Auto Scaling. +* `predictive_scaling_configuration` - (Optional) The predictive scaling policy configuration to use with Amazon EC2 Auto Scaling. * `estimated_instance_warmup` - (Optional) The estimated time, in seconds, until a newly launched instance will contribute CloudWatch metrics. Without a value, AWS will default to the group's specified cooldown period. The following argument is only available to "SimpleScaling" and "StepScaling" type policies: @@ -160,7 +160,7 @@ The following arguments are supported: * `name` - (Required) The name of the dimension. * `value` - (Required) The value of the dimension. -### predictive_scaling_config +### predictive_scaling_configuration The following arguments are supported: @@ -182,21 +182,21 @@ The following arguments are supported: The following arguments are supported: -* `predefinied_metric_type` - (Required) The metric type. Valid values are `ASGTotalCPUUtilization`, `ASGTotalNetworkIn`, `ASGTotalNetworkOut`, or `ALBTargetGroupRequestCount`. +* `predefined_metric_type` - (Required) The metric type. Valid values are `ASGTotalCPUUtilization`, `ASGTotalNetworkIn`, `ASGTotalNetworkOut`, or `ALBTargetGroupRequestCount`. * `resource_label` - (Optional) A label that uniquely identifies a specific Application Load Balancer target group from which to determine the request count served by your Auto Scaling group. ##### predefined_metric_pair_specification The following arguments are supported: -* `predefinied_metric_type` - (Required) Indicates which metrics to use. There are two different types of metrics for each metric type: one is a load metric and one is a scaling metric. For example, if the metric type is `ASGCPUUtilization`, the Auto Scaling group's total CPU metric is used as the load metric, and the average CPU metric is used for the scaling metric. Valid values are `ASGCPUUtilization`, `ASGNetworkIn`, `ASGNetworkOut`, or `ALBRequestCount`. +* `predefined_metric_type` - (Required) Indicates which metrics to use. There are two different types of metrics for each metric type: one is a load metric and one is a scaling metric. For example, if the metric type is `ASGCPUUtilization`, the Auto Scaling group's total CPU metric is used as the load metric, and the average CPU metric is used for the scaling metric. Valid values are `ASGCPUUtilization`, `ASGNetworkIn`, `ASGNetworkOut`, or `ALBRequestCount`. * `resource_label` - (Optional) A label that uniquely identifies a specific Application Load Balancer target group from which to determine the request count served by your Auto Scaling group. ##### predefined_scaling_metric_specification The following arguments are supported: -* `predefinied_metric_type` - (Required) Describes a scaling metric for a predictive scaling policy. Valid values are `ASGAverageCPUUtilization`, `ASGAverageNetworkIn`, `ASGAverageNetworkOut`, or `ALBRequestCountPerTarget`. +* `predefined_metric_type` - (Required) Describes a scaling metric for a predictive scaling policy. Valid values are `ASGAverageCPUUtilization`, `ASGAverageNetworkIn`, `ASGAverageNetworkOut`, or `ALBRequestCountPerTarget`. * `resource_label` - (Optional) A label that uniquely identifies a specific Application Load Balancer target group from which to determine the request count served by your Auto Scaling group. ## Attributes Reference From 19d4b0780b92fe6cb9e12effd51a59c740e2afa8 Mon Sep 17 00:00:00 2001 From: bill-rich Date: Wed, 19 May 2021 15:47:11 -0700 Subject: [PATCH 5/9] Update names to match final SDK --- aws/resource_aws_autoscaling_policy.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/aws/resource_aws_autoscaling_policy.go b/aws/resource_aws_autoscaling_policy.go index b2866df34b2..fae0c350313 100644 --- a/aws/resource_aws_autoscaling_policy.go +++ b/aws/resource_aws_autoscaling_policy.go @@ -641,36 +641,36 @@ func expandPredictiveScalingMetricSpecifications(metricSpecificationsSlice []int return []*autoscaling.PredictiveScalingMetricSpecification{metricSpecification} } -func expandPredefinedLoadMetricSpecification(predefinedLoadMetricSpecificationSlice []interface{}) *autoscaling.PredefinedLoadMetricSpecification { +func expandPredefinedLoadMetricSpecification(predefinedLoadMetricSpecificationSlice []interface{}) *autoscaling.PredictiveScalingPredefinedLoadMetric { if predefinedLoadMetricSpecificationSlice == nil || len(predefinedLoadMetricSpecificationSlice) < 1 { return nil } predefinedLoadMetricSpecificationFlat := predefinedLoadMetricSpecificationSlice[0].(map[string]interface{}) - predefinedLoadMetricSpecification := &autoscaling.PredefinedLoadMetricSpecification{ + predefinedLoadMetricSpecification := &autoscaling.PredictiveScalingPredefinedLoadMetric{ PredefinedMetricType: aws.String(predefinedLoadMetricSpecificationFlat["predefined_metric_type"].(string)), ResourceLabel: aws.String(predefinedLoadMetricSpecificationFlat["resource_label"].(string)), } return predefinedLoadMetricSpecification } -func expandPredefinedMetricPairSpecification(predefinedMetricPairSpecificationSlice []interface{}) *autoscaling.PredefinedMetricPairSpecification { +func expandPredefinedMetricPairSpecification(predefinedMetricPairSpecificationSlice []interface{}) *autoscaling.PredictiveScalingPredefinedMetricPair { if predefinedMetricPairSpecificationSlice == nil || len(predefinedMetricPairSpecificationSlice) < 1 { return nil } predefinedMetricPairSpecificationFlat := predefinedMetricPairSpecificationSlice[0].(map[string]interface{}) - predefinedMetricPairSpecification := &autoscaling.PredefinedMetricPairSpecification{ + predefinedMetricPairSpecification := &autoscaling.PredictiveScalingPredefinedMetricPair{ PredefinedMetricType: aws.String(predefinedMetricPairSpecificationFlat["predefined_metric_type"].(string)), ResourceLabel: aws.String(predefinedMetricPairSpecificationFlat["resource_label"].(string)), } return predefinedMetricPairSpecification } -func expandPredefinedScalingMetricSpecification(predefinedScalingMetricSpecificationSlice []interface{}) *autoscaling.PredefinedScalingMetricSpecification { +func expandPredefinedScalingMetricSpecification(predefinedScalingMetricSpecificationSlice []interface{}) *autoscaling.PredictiveScalingPredefinedScalingMetric { if predefinedScalingMetricSpecificationSlice == nil || len(predefinedScalingMetricSpecificationSlice) < 1 { return nil } predefinedScalingMetricSpecificationFlat := predefinedScalingMetricSpecificationSlice[0].(map[string]interface{}) - predefinedScalingMetricSpecification := &autoscaling.PredefinedScalingMetricSpecification{ + predefinedScalingMetricSpecification := &autoscaling.PredictiveScalingPredefinedScalingMetric{ PredefinedMetricType: aws.String(predefinedScalingMetricSpecificationFlat["predefined_metric_type"].(string)), ResourceLabel: aws.String(predefinedScalingMetricSpecificationFlat["resource_label"].(string)), } @@ -760,7 +760,7 @@ func flattenPredictiveScalingMetricSpecifications(metricSpecification []*autosca return []map[string]interface{}{metricSpecificationFlat} } -func flattenPredefinedScalingMetricSpecification(predefinedScalingMetricSpecification *autoscaling.PredefinedScalingMetricSpecification) []map[string]interface{} { +func flattenPredefinedScalingMetricSpecification(predefinedScalingMetricSpecification *autoscaling.PredictiveScalingPredefinedScalingMetric) []map[string]interface{} { predefinedScalingMetricSpecificationFlat := map[string]interface{}{} if predefinedScalingMetricSpecification == nil { return []map[string]interface{}{predefinedScalingMetricSpecificationFlat} @@ -770,7 +770,7 @@ func flattenPredefinedScalingMetricSpecification(predefinedScalingMetricSpecific return []map[string]interface{}{predefinedScalingMetricSpecificationFlat} } -func flattenPredefinedLoadMetricSpecification(predefinedLoadMetricSpecification *autoscaling.PredefinedLoadMetricSpecification) []map[string]interface{} { +func flattenPredefinedLoadMetricSpecification(predefinedLoadMetricSpecification *autoscaling.PredictiveScalingPredefinedLoadMetric) []map[string]interface{} { predefinedLoadMetricSpecificationFlat := map[string]interface{}{} if predefinedLoadMetricSpecification == nil { return []map[string]interface{}{predefinedLoadMetricSpecificationFlat} @@ -780,7 +780,7 @@ func flattenPredefinedLoadMetricSpecification(predefinedLoadMetricSpecification return []map[string]interface{}{predefinedLoadMetricSpecificationFlat} } -func flattenPredefinedMetricPairSpecification(predefinedMetricPairSpecification *autoscaling.PredefinedMetricPairSpecification) []map[string]interface{} { +func flattenPredefinedMetricPairSpecification(predefinedMetricPairSpecification *autoscaling.PredictiveScalingPredefinedMetricPair) []map[string]interface{} { predefinedMetricPairSpecificationFlat := map[string]interface{}{} if predefinedMetricPairSpecification == nil { return []map[string]interface{}{predefinedMetricPairSpecificationFlat} From 74b04a17471c3d0d85437f3ea466e87b0abea21c Mon Sep 17 00:00:00 2001 From: bill-rich Date: Wed, 19 May 2021 16:01:13 -0700 Subject: [PATCH 6/9] Remove go.mod changes and add CHANGELOG entry --- .changelog/19447.txt | 3 +++ go.mod | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 .changelog/19447.txt diff --git a/.changelog/19447.txt b/.changelog/19447.txt new file mode 100644 index 00000000000..bb9a46e08b1 --- /dev/null +++ b/.changelog/19447.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_autoscaling_policy: Add `PredictiveScaling` `policy_type` and `predictive_scaling_configuration` argument +``` diff --git a/go.mod b/go.mod index 0288ff85c99..c83c116f129 100644 --- a/go.mod +++ b/go.mod @@ -21,5 +21,3 @@ require ( github.com/pquerna/otp v1.3.0 gopkg.in/yaml.v2 v2.4.0 ) - -replace github.com/aws/aws-sdk-go => ../../aws/aws-sdk-go From 17dde15a196b118192124e4c9576e935f996ea6a Mon Sep 17 00:00:00 2001 From: bill-rich Date: Wed, 19 May 2021 17:15:01 -0700 Subject: [PATCH 7/9] Use nullables --- aws/internal/experimental/nullable/int.go | 28 ++++++ aws/resource_aws_autoscaling_policy.go | 22 +++-- aws/resource_aws_autoscaling_policy_test.go | 98 ++++++++++++++++++--- 3 files changed, 129 insertions(+), 19 deletions(-) diff --git a/aws/internal/experimental/nullable/int.go b/aws/internal/experimental/nullable/int.go index 53981603485..25feb8112bb 100644 --- a/aws/internal/experimental/nullable/int.go +++ b/aws/internal/experimental/nullable/int.go @@ -76,3 +76,31 @@ func ValidateTypeStringNullableIntAtLeast(min int) schema.SchemaValidateFunc { return } } + +// ValidateTypeStringNullableIntBetween provides custom error messaging for TypeString ints +// Some arguments require an int value or unspecified, empty field. +func ValidateTypeStringNullableIntBetween(min int, max int) schema.SchemaValidateFunc { + return func(i interface{}, k string) (ws []string, es []error) { + value, ok := i.(string) + if !ok { + es = append(es, fmt.Errorf("expected type of %s to be string", k)) + return + } + + if value == "" { + return + } + + v, err := strconv.ParseInt(value, 10, 64) + if err != nil { + es = append(es, fmt.Errorf("%s: cannot parse '%s' as int: %w", k, value, err)) + return + } + + if v < int64(min) || v > int64(max) { + es = append(es, fmt.Errorf("expected %s to be at between (%d) and (%d), got %d", k, min, max, v)) + } + + return + } +} diff --git a/aws/resource_aws_autoscaling_policy.go b/aws/resource_aws_autoscaling_policy.go index fae0c350313..f06d94b4bb9 100644 --- a/aws/resource_aws_autoscaling_policy.go +++ b/aws/resource_aws_autoscaling_policy.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" "log" + "strconv" "strings" "github.com/aws/aws-sdk-go/aws" @@ -11,6 +12,7 @@ import ( "github.com/aws/aws-sdk-go/service/autoscaling" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/experimental/nullable" "github.com/terraform-providers/terraform-provider-aws/aws/internal/hashcode" ) @@ -170,10 +172,10 @@ func resourceAwsAutoscalingPolicy() *schema.Resource { }, false), }, "max_capacity_buffer": { - Type: schema.TypeInt, + Type: nullable.TypeNullableInt, Optional: true, Default: 0, - ValidateFunc: validation.IntBetween(-1, 100), + ValidateFunc: nullable.ValidateTypeStringNullableIntBetween(0, 100), }, "mode": { Type: schema.TypeString, @@ -185,9 +187,9 @@ func resourceAwsAutoscalingPolicy() *schema.Resource { }, false), }, "scheduling_buffer_time": { - Type: schema.TypeInt, + Type: nullable.TypeNullableInt, Optional: true, - ValidateFunc: validation.IntAtLeast(0), + ValidateFunc: nullable.ValidateTypeStringNullableIntAtLeast(0), }, }, }, @@ -619,10 +621,12 @@ func expandPredictiveScalingConfig(predictiveScalingConfigSlice []interface{}) * MetricSpecifications: expandPredictiveScalingMetricSpecifications(predictiveScalingConfigFlat["metric_specification"].([]interface{})), MaxCapacityBreachBehavior: aws.String(predictiveScalingConfigFlat["max_capacity_breach_behavior"].(string)), Mode: aws.String(predictiveScalingConfigFlat["mode"].(string)), - SchedulingBufferTime: aws.Int64(int64(predictiveScalingConfigFlat["scheduling_buffer_time"].(int))), } - if predictiveScalingConfigFlat["max_capacity_buffer"].(int) != 0 { - predictiveScalingConfig.MaxCapacityBuffer = aws.Int64(int64(predictiveScalingConfigFlat["max_capacity_buffer"].(int))) + if v, null, _ := nullable.Int(predictiveScalingConfigFlat["max_capacity_buffer"].(string)).Value(); !null { + predictiveScalingConfig.MaxCapacityBuffer = aws.Int64(v) + } + if v, null, _ := nullable.Int(predictiveScalingConfigFlat["scheduling_buffer_time"].(string)).Value(); !null { + predictiveScalingConfig.SchedulingBufferTime = aws.Int64(v) } return predictiveScalingConfig } @@ -729,13 +733,13 @@ func flattenPredictiveScalingConfig(predictiveScalingConfig *autoscaling.Predict predictiveScalingConfigFlat["mode"] = aws.StringValue(predictiveScalingConfig.Mode) } if predictiveScalingConfig.SchedulingBufferTime != nil { - predictiveScalingConfigFlat["scheduling_buffer_time"] = aws.Int64Value(predictiveScalingConfig.SchedulingBufferTime) + predictiveScalingConfigFlat["scheduling_buffer_time"] = strconv.FormatInt(aws.Int64Value(predictiveScalingConfig.SchedulingBufferTime), 10) } if predictiveScalingConfig.MaxCapacityBreachBehavior != nil { predictiveScalingConfigFlat["max_capacity_breach_behavior"] = aws.StringValue(predictiveScalingConfig.MaxCapacityBreachBehavior) } if predictiveScalingConfig.MaxCapacityBuffer != nil { - predictiveScalingConfigFlat["max_capacity_buffer"] = aws.Int64Value(predictiveScalingConfig.MaxCapacityBuffer) + predictiveScalingConfigFlat["max_capacity_buffer"] = strconv.FormatInt(aws.Int64Value(predictiveScalingConfig.MaxCapacityBuffer), 10) } return []map[string]interface{}{predictiveScalingConfigFlat} } diff --git a/aws/resource_aws_autoscaling_policy_test.go b/aws/resource_aws_autoscaling_policy_test.go index db8223e878d..bbbb89d161b 100644 --- a/aws/resource_aws_autoscaling_policy_test.go +++ b/aws/resource_aws_autoscaling_policy_test.go @@ -123,7 +123,7 @@ func TestAccAWSAutoscalingPolicy_predictiveScaling(t *testing.T) { resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.mode", "ForecastAndScale"), resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.scheduling_buffer_time", "10"), resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.max_capacity_breach_behavior", "IncreaseMaxCapacity"), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.max_capacity_buffer", "10"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.max_capacity_buffer", "0"), resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.target_value", "32"), resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_scaling_metric_specification.0.predefined_metric_type", "ASGAverageCPUUtilization"), resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_scaling_metric_specification.0.resource_label", "testLabel"), @@ -191,6 +191,20 @@ func TestAccAWSAutoscalingPolicy_predictiveScalingUpdated(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccCheckAWSAutoscalingPolicyDestroy, Steps: []resource.TestStep{ + { + Config: testaccawsautoscalingpolicyconfigPredictivescalingUpdate(name), + Check: resource.ComposeTestCheckFunc( + testAccCheckScalingPolicyExists(resourceSimpleName, &policy), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.mode", "ForecastOnly"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.scheduling_buffer_time", "5"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.max_capacity_breach_behavior", "HonorMaxCapacity"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.target_value", "32"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_scaling_metric_specification.0.predefined_metric_type", "ASGAverageNetworkIn"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_scaling_metric_specification.0.resource_label", "testLabel"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_load_metric_specification.0.predefined_metric_type", "ASGTotalNetworkIn"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_load_metric_specification.0.resource_label", "testLabel"), + ), + }, { Config: testAccAWSAutoscalingPolicyConfig_predictiveScaling(name), Check: resource.ComposeTestCheckFunc( @@ -198,7 +212,7 @@ func TestAccAWSAutoscalingPolicy_predictiveScalingUpdated(t *testing.T) { resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.mode", "ForecastAndScale"), resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.scheduling_buffer_time", "10"), resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.max_capacity_breach_behavior", "IncreaseMaxCapacity"), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.max_capacity_buffer", "10"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.max_capacity_buffer", "0"), resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.target_value", "32"), resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_scaling_metric_specification.0.predefined_metric_type", "ASGAverageCPUUtilization"), resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_scaling_metric_specification.0.resource_label", "testLabel"), @@ -207,16 +221,55 @@ func TestAccAWSAutoscalingPolicy_predictiveScalingUpdated(t *testing.T) { ), }, { - Config: testAccAWSAutoscalingPolicyConfig_predictiveScalingUpdated(name), + ResourceName: resourceSimpleName, + ImportState: true, + ImportStateIdFunc: testAccAWSAutoscalingPolicyImportStateIdFunc(resourceSimpleName), + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAWSAutoscalingPolicy_predictiveScalingNullable(t *testing.T) { + var policy autoscaling.ScalingPolicy + + resourceSimpleName := "aws_autoscaling_policy.test" + + name := acctest.RandomWithPrefix("terraform-testacc-asp") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ErrorCheck: testAccErrorCheck(t, autoscaling.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSAutoscalingPolicyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSAutoscalingPolicyConfig_predictiveScaling(name), Check: resource.ComposeTestCheckFunc( testAccCheckScalingPolicyExists(resourceSimpleName, &policy), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.mode", "ForecastOnly"), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.scheduling_buffer_time", "5"), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.max_capacity_breach_behavior", "HonorMaxCapacity"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.mode", "ForecastAndScale"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.scheduling_buffer_time", "10"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.max_capacity_breach_behavior", "IncreaseMaxCapacity"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.max_capacity_buffer", "0"), resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.target_value", "32"), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_scaling_metric_specification.0.predefined_metric_type", "ASGAverageNetworkIn"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_scaling_metric_specification.0.predefined_metric_type", "ASGAverageCPUUtilization"), resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_scaling_metric_specification.0.resource_label", "testLabel"), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_load_metric_specification.0.predefined_metric_type", "ASGTotalNetworkIn"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_load_metric_specification.0.predefined_metric_type", "ASGTotalCPUUtilization"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_load_metric_specification.0.resource_label", "testLabel"), + ), + }, + { + Config: testAccAWSAutoscalingPolicyConfig_predictiveScalingUnsetNullables(name), + Check: resource.ComposeTestCheckFunc( + testAccCheckScalingPolicyExists(resourceSimpleName, &policy), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.mode", "ForecastAndScale"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.scheduling_buffer_time", ""), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.max_capacity_breach_behavior", "IncreaseMaxCapacity"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.max_capacity_buffer", "0"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.target_value", "32"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_scaling_metric_specification.0.predefined_metric_type", "ASGAverageCPUUtilization"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_scaling_metric_specification.0.resource_label", "testLabel"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_load_metric_specification.0.predefined_metric_type", "ASGTotalCPUUtilization"), resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_load_metric_specification.0.resource_label", "testLabel"), ), }, @@ -581,7 +634,32 @@ resource "aws_autoscaling_policy" "test" { mode = "ForecastAndScale" scheduling_buffer_time = 10 max_capacity_breach_behavior = "IncreaseMaxCapacity" - max_capacity_buffer = 10 + max_capacity_buffer = 0 + } +} +`, name)) +} + +func testAccAWSAutoscalingPolicyConfig_predictiveScalingUnsetNullables(name string) string { + return composeConfig(testAccAWSAutoscalingPolicyConfig_base(name), fmt.Sprintf(` +resource "aws_autoscaling_policy" "test" { + name = "%[1]s-policy_predictive" + policy_type = "PredictiveScaling" + autoscaling_group_name = aws_autoscaling_group.test.name + predictive_scaling_configuration { + metric_specification { + target_value = 32 + predefined_scaling_metric_specification { + predefined_metric_type = "ASGAverageCPUUtilization" + resource_label = "testLabel" + } + predefined_load_metric_specification { + predefined_metric_type = "ASGTotalCPUUtilization" + resource_label = "testLabel" + } + } + mode = "ForecastAndScale" + max_capacity_breach_behavior = "IncreaseMaxCapacity" } } `, name)) @@ -600,7 +678,7 @@ resource "aws_autoscaling_policy" "test" { `, name)) } -func testAccAWSAutoscalingPolicyConfig_predictiveScalingUpdated(name string) string { +func testaccawsautoscalingpolicyconfigPredictivescalingUpdate(name string) string { return testAccAWSAutoscalingPolicyConfig_base(name) + fmt.Sprintf(` resource "aws_autoscaling_policy" "test" { name = "%[1]s-policy_predictive" From d8e10d1bbb1161fafed89593595e0de6f18db0c1 Mon Sep 17 00:00:00 2001 From: bill-rich Date: Wed, 19 May 2021 17:32:48 -0700 Subject: [PATCH 8/9] Remove max_capacity_buffer default --- aws/resource_aws_autoscaling_policy.go | 1 - aws/resource_aws_autoscaling_policy_test.go | 67 +++------------------ 2 files changed, 7 insertions(+), 61 deletions(-) diff --git a/aws/resource_aws_autoscaling_policy.go b/aws/resource_aws_autoscaling_policy.go index f06d94b4bb9..443ccecb208 100644 --- a/aws/resource_aws_autoscaling_policy.go +++ b/aws/resource_aws_autoscaling_policy.go @@ -174,7 +174,6 @@ func resourceAwsAutoscalingPolicy() *schema.Resource { "max_capacity_buffer": { Type: nullable.TypeNullableInt, Optional: true, - Default: 0, ValidateFunc: nullable.ValidateTypeStringNullableIntBetween(0, 100), }, "mode": { diff --git a/aws/resource_aws_autoscaling_policy_test.go b/aws/resource_aws_autoscaling_policy_test.go index bbbb89d161b..b9fa6629a40 100644 --- a/aws/resource_aws_autoscaling_policy_test.go +++ b/aws/resource_aws_autoscaling_policy_test.go @@ -185,58 +185,6 @@ func TestAccAWSAutoscalingPolicy_predictiveScalingUpdated(t *testing.T) { name := acctest.RandomWithPrefix("terraform-testacc-asp") - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ErrorCheck: testAccErrorCheck(t, autoscaling.EndpointsID), - Providers: testAccProviders, - CheckDestroy: testAccCheckAWSAutoscalingPolicyDestroy, - Steps: []resource.TestStep{ - { - Config: testaccawsautoscalingpolicyconfigPredictivescalingUpdate(name), - Check: resource.ComposeTestCheckFunc( - testAccCheckScalingPolicyExists(resourceSimpleName, &policy), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.mode", "ForecastOnly"), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.scheduling_buffer_time", "5"), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.max_capacity_breach_behavior", "HonorMaxCapacity"), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.target_value", "32"), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_scaling_metric_specification.0.predefined_metric_type", "ASGAverageNetworkIn"), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_scaling_metric_specification.0.resource_label", "testLabel"), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_load_metric_specification.0.predefined_metric_type", "ASGTotalNetworkIn"), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_load_metric_specification.0.resource_label", "testLabel"), - ), - }, - { - Config: testAccAWSAutoscalingPolicyConfig_predictiveScaling(name), - Check: resource.ComposeTestCheckFunc( - testAccCheckScalingPolicyExists(resourceSimpleName, &policy), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.mode", "ForecastAndScale"), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.scheduling_buffer_time", "10"), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.max_capacity_breach_behavior", "IncreaseMaxCapacity"), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.max_capacity_buffer", "0"), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.target_value", "32"), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_scaling_metric_specification.0.predefined_metric_type", "ASGAverageCPUUtilization"), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_scaling_metric_specification.0.resource_label", "testLabel"), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_load_metric_specification.0.predefined_metric_type", "ASGTotalCPUUtilization"), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_load_metric_specification.0.resource_label", "testLabel"), - ), - }, - { - ResourceName: resourceSimpleName, - ImportState: true, - ImportStateIdFunc: testAccAWSAutoscalingPolicyImportStateIdFunc(resourceSimpleName), - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccAWSAutoscalingPolicy_predictiveScalingNullable(t *testing.T) { - var policy autoscaling.ScalingPolicy - - resourceSimpleName := "aws_autoscaling_policy.test" - - name := acctest.RandomWithPrefix("terraform-testacc-asp") - resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, ErrorCheck: testAccErrorCheck(t, autoscaling.EndpointsID), @@ -259,17 +207,17 @@ func TestAccAWSAutoscalingPolicy_predictiveScalingNullable(t *testing.T) { ), }, { - Config: testAccAWSAutoscalingPolicyConfig_predictiveScalingUnsetNullables(name), + Config: testaccawsautoscalingpolicyconfigPredictivescalingUpdated(name), Check: resource.ComposeTestCheckFunc( testAccCheckScalingPolicyExists(resourceSimpleName, &policy), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.mode", "ForecastAndScale"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.mode", "ForecastOnly"), resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.scheduling_buffer_time", ""), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.max_capacity_breach_behavior", "IncreaseMaxCapacity"), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.max_capacity_buffer", "0"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.max_capacity_buffer", ""), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.max_capacity_breach_behavior", "HonorMaxCapacity"), resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.target_value", "32"), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_scaling_metric_specification.0.predefined_metric_type", "ASGAverageCPUUtilization"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_scaling_metric_specification.0.predefined_metric_type", "ASGAverageNetworkIn"), resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_scaling_metric_specification.0.resource_label", "testLabel"), - resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_load_metric_specification.0.predefined_metric_type", "ASGTotalCPUUtilization"), + resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_load_metric_specification.0.predefined_metric_type", "ASGTotalNetworkIn"), resource.TestCheckResourceAttr(resourceSimpleName, "predictive_scaling_configuration.0.metric_specification.0.predefined_load_metric_specification.0.resource_label", "testLabel"), ), }, @@ -678,7 +626,7 @@ resource "aws_autoscaling_policy" "test" { `, name)) } -func testaccawsautoscalingpolicyconfigPredictivescalingUpdate(name string) string { +func testaccawsautoscalingpolicyconfigPredictivescalingUpdated(name string) string { return testAccAWSAutoscalingPolicyConfig_base(name) + fmt.Sprintf(` resource "aws_autoscaling_policy" "test" { name = "%[1]s-policy_predictive" @@ -697,7 +645,6 @@ resource "aws_autoscaling_policy" "test" { } } mode = "ForecastOnly" - scheduling_buffer_time = 5 max_capacity_breach_behavior = "HonorMaxCapacity" } } From 335f45efc26c42a0d9d660b02528d76e1c2158ee Mon Sep 17 00:00:00 2001 From: bill-rich Date: Wed, 19 May 2021 17:57:32 -0700 Subject: [PATCH 9/9] Fix linter and docs --- aws/resource_aws_autoscaling_policy_test.go | 25 ------------------- .../docs/r/autoscaling_policy.html.markdown | 2 +- 2 files changed, 1 insertion(+), 26 deletions(-) diff --git a/aws/resource_aws_autoscaling_policy_test.go b/aws/resource_aws_autoscaling_policy_test.go index b9fa6629a40..61294e13d46 100644 --- a/aws/resource_aws_autoscaling_policy_test.go +++ b/aws/resource_aws_autoscaling_policy_test.go @@ -588,31 +588,6 @@ resource "aws_autoscaling_policy" "test" { `, name)) } -func testAccAWSAutoscalingPolicyConfig_predictiveScalingUnsetNullables(name string) string { - return composeConfig(testAccAWSAutoscalingPolicyConfig_base(name), fmt.Sprintf(` -resource "aws_autoscaling_policy" "test" { - name = "%[1]s-policy_predictive" - policy_type = "PredictiveScaling" - autoscaling_group_name = aws_autoscaling_group.test.name - predictive_scaling_configuration { - metric_specification { - target_value = 32 - predefined_scaling_metric_specification { - predefined_metric_type = "ASGAverageCPUUtilization" - resource_label = "testLabel" - } - predefined_load_metric_specification { - predefined_metric_type = "ASGTotalCPUUtilization" - resource_label = "testLabel" - } - } - mode = "ForecastAndScale" - max_capacity_breach_behavior = "IncreaseMaxCapacity" - } -} -`, name)) -} - func testAccAWSAutoscalingPolicyConfig_predictiveScalingRemoved(name string) string { return composeConfig(testAccAWSAutoscalingPolicyConfig_base(name), fmt.Sprintf(` resource "aws_autoscaling_policy" "test" { diff --git a/website/docs/r/autoscaling_policy.html.markdown b/website/docs/r/autoscaling_policy.html.markdown index d3bf4cb8f5d..b28b4bf0603 100644 --- a/website/docs/r/autoscaling_policy.html.markdown +++ b/website/docs/r/autoscaling_policy.html.markdown @@ -165,7 +165,7 @@ The following arguments are supported: The following arguments are supported: * `max_capacity_breach_behavior` - (Optional) Defines the behavior that should be applied if the forecast capacity approaches or exceeds the maximum capacity of the Auto Scaling group. Valid values are `HonorMaxCapacity` or `IncreaseMaxCapacity`. Default is `HonorMaxCapacity`. -* `max_capacity_buffer` - (Optional) The size of the capacity buffer to use when the forecast capacity is close to or exceeds the maximum capacity. Valid range is `-1` to `100`. If set to `-1`, Amazon EC2 Auto Scaling may scale capacity higher than the maximum capacity to equal but not exceed forecast capacity. +* `max_capacity_buffer` - (Optional) The size of the capacity buffer to use when the forecast capacity is close to or exceeds the maximum capacity. Valid range is `0` to `100`. If set to `0`, Amazon EC2 Auto Scaling may scale capacity higher than the maximum capacity to equal but not exceed forecast capacity. * `metric_specification` - (Required) This structure includes the metrics and target utilization to use for predictive scaling. * `mode` - (Optional) The predictive scaling mode. Valid values are `ForecastAndScale` and `ForecastOnly`. Default is `ForecastOnly`. * `scheduling_buffer_time` - (Optional) The amount of time, in seconds, by which the instance launch time can be advanced. Minimum is `0`.