Skip to content

Commit

Permalink
Merge branch 'upstream'
Browse files Browse the repository at this point in the history
  • Loading branch information
jocgir committed Sep 26, 2017
2 parents c3047e8 + 90d698c commit 50f7481
Show file tree
Hide file tree
Showing 6 changed files with 454 additions and 4 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ IMPROVEMENTS:
* provider: Add support for Task Roles when running on ECS or CodeBuild [GH-1425]
* resource/aws_instance: New `user_data_base64` attribute that allows non-UTF8 data (such as gzip) to be assigned to user-data without corruption [GH-850]
* data-source/aws_vpc: Expose enable_dns_* in aws_vpc data_source [GH-1373]
* resource/aws_appautoscaling_policy: Add support for DynamoDB [GH-1650]
* resource/aws_directory_service_directory: Add support for `tags` [GH-1398]
* resource/aws_rds_cluster: Allow setting of rds cluster engine [GH-1415]
* resource/aws_ssm_association: now supports update for `parameters`, `schedule_expression`,`output_location` [GH-1421]
Expand Down Expand Up @@ -44,7 +45,7 @@ IMPROVEMENTS:
* resource/aws_nat_gateway: Add tags support [GH-1625]
* resource/aws_route53_record: Add support for Route53 multi-value answer routing policy [GH-1686]
* resource/aws_instance: Read iops only when volume type is io1 [GH-1573]
* Allow RDS Cluster / Cluster instance to specify the engine [GH-1591]
* resource/aws_rds_cluster(+_instance) Allow specifying the engine [GH-1591]
* resource/aws_cloudwatch_event_target: Add Input transformer for Cloudwatch Events [GH-1343]
* resource/aws_directory_service_directory: Support Import functionality [GH-1732]

Expand Down
266 changes: 264 additions & 2 deletions aws/resource_aws_appautoscaling_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import (
"fmt"
"log"
"strconv"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/applicationautoscaling"
"github.com/hashicorp/terraform/helper/hashcode"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
)

Expand Down Expand Up @@ -153,6 +155,95 @@ func resourceAwsAppautoscalingPolicy() *schema.Resource {
},
},
},
"target_tracking_scaling_policy_configuration": {
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"customized_metric_specification": &schema.Schema{
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
ConflictsWith: []string{"target_tracking_scaling_policy_configuration.0.predefined_metric_specification"},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"dimensions": &schema.Schema{
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
},
"value": {
Type: schema.TypeString,
Required: true,
},
},
},
},
"metric_name": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"namespace": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"statistic": &schema.Schema{
Type: schema.TypeString,
Required: true,
ValidateFunc: validateAppautoscalingCustomizedMetricSpecificationStatistic,
},
"unit": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
},
},
},
"predefined_metric_specification": &schema.Schema{
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
ConflictsWith: []string{"target_tracking_scaling_policy_configuration.0.customized_metric_specification"},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"predefined_metric_type": &schema.Schema{
Type: schema.TypeString,
Required: true,
ValidateFunc: validateAppautoscalingPredefinedMetricSpecification,
},
"resource_label": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ValidateFunc: validateAppautoscalingPredefinedResourceLabel,
},
},
},
},
"disable_scale_in": &schema.Schema{
Type: schema.TypeBool,
Default: false,
Optional: true,
},
"scale_in_cooldown": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
},
"scale_out_cooldown": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
},
"target_value": &schema.Schema{
Type: schema.TypeFloat,
Required: true,
},
},
},
},
},
}
}
Expand All @@ -166,9 +257,20 @@ func resourceAwsAppautoscalingPolicyCreate(d *schema.ResourceData, meta interfac
}

log.Printf("[DEBUG] ApplicationAutoScaling PutScalingPolicy: %#v", params)
resp, err := conn.PutScalingPolicy(&params)
var resp *applicationautoscaling.PutScalingPolicyOutput
err = resource.Retry(1*time.Minute, func() *resource.RetryError {
var err error
resp, err = conn.PutScalingPolicy(&params)
if err != nil {
if isAWSErr(err, "FailedResourceAccessException", "is not authorized to perform") {
return resource.RetryableError(err)
}
return resource.NonRetryableError(fmt.Errorf("Error putting scaling policy: %s", err))
}
return nil
})
if err != nil {
return fmt.Errorf("Error putting scaling policy: %s", err)
return err
}

d.Set("arn", resp.PolicyARN)
Expand Down Expand Up @@ -198,6 +300,8 @@ func resourceAwsAppautoscalingPolicyRead(d *schema.ResourceData, meta interface{
d.Set("service_namespace", p.ServiceNamespace)
d.Set("alarms", p.Alarms)
d.Set("step_scaling_policy_configuration", flattenStepScalingPolicyConfiguration(p.StepScalingPolicyConfiguration))
d.Set("target_tracking_scaling_policy_configuration",
flattenTargetTrackingScalingPolicyConfiguration(p.TargetTrackingScalingPolicyConfiguration))

return nil
}
Expand Down Expand Up @@ -304,6 +408,59 @@ func expandAppautoscalingStepAdjustments(configured []interface{}) ([]*applicati
return adjustments, nil
}

func expandAppautoscalingCustomizedMetricSpecification(configured []interface{}) *applicationautoscaling.CustomizedMetricSpecification {
spec := &applicationautoscaling.CustomizedMetricSpecification{}

for _, raw := range configured {
data := raw.(map[string]interface{})
if v, ok := data["metric_name"]; ok {
spec.MetricName = aws.String(v.(string))
}

if v, ok := data["namespace"]; ok {
spec.Namespace = aws.String(v.(string))
}

if v, ok := data["unit"].(string); ok && v != "" {
spec.Unit = aws.String(v)
}

if v, ok := data["statistic"]; ok {
spec.Statistic = aws.String(v.(string))
}

if s, ok := data["dimensions"].(*schema.Set); ok && s.Len() > 0 {
dimensions := make([]*applicationautoscaling.MetricDimension, s.Len(), s.Len())
for i, d := range s.List() {
dimension := d.(map[string]interface{})
dimensions[i] = &applicationautoscaling.MetricDimension{
Name: aws.String(dimension["name"].(string)),
Value: aws.String(dimension["value"].(string)),
}
}
spec.Dimensions = dimensions
}
}
return spec
}

func expandAppautoscalingPredefinedMetricSpecification(configured []interface{}) *applicationautoscaling.PredefinedMetricSpecification {
spec := &applicationautoscaling.PredefinedMetricSpecification{}

for _, raw := range configured {
data := raw.(map[string]interface{})

if v, ok := data["predefined_metric_type"]; ok {
spec.PredefinedMetricType = aws.String(v.(string))
}

if v, ok := data["resource_label"].(string); ok && v != "" {
spec.ResourceLabel = aws.String(v)
}
}
return spec
}

func getAwsAppautoscalingPutScalingPolicyInput(d *schema.ResourceData) (applicationautoscaling.PutScalingPolicyInput, error) {
var params = applicationautoscaling.PutScalingPolicyInput{
PolicyName: aws.String(d.Get("name").(string)),
Expand Down Expand Up @@ -363,6 +520,39 @@ func getAwsAppautoscalingPutScalingPolicyInput(d *schema.ResourceData) (applicat
params.StepScalingPolicyConfiguration = expandStepScalingPolicyConfiguration(v.([]interface{}))
}

if l, ok := d.GetOk("target_tracking_scaling_policy_configuration"); ok {
v := l.([]interface{})
if len(v) < 1 {
return params, fmt.Errorf("Empty target_tracking_scaling_policy_configuration block")
}
ttspCfg := v[0].(map[string]interface{})
cfg := &applicationautoscaling.TargetTrackingScalingPolicyConfiguration{
TargetValue: aws.Float64(ttspCfg["target_value"].(float64)),
}

if v, ok := ttspCfg["scale_in_cooldown"]; ok {
cfg.ScaleInCooldown = aws.Int64(int64(v.(int)))
}

if v, ok := ttspCfg["scale_out_cooldown"]; ok {
cfg.ScaleOutCooldown = aws.Int64(int64(v.(int)))
}

if v, ok := ttspCfg["disable_scale_in"]; ok {
cfg.DisableScaleIn = aws.Bool(v.(bool))
}

if v, ok := ttspCfg["customized_metric_specification"].([]interface{}); ok && len(v) > 0 {
cfg.CustomizedMetricSpecification = expandAppautoscalingCustomizedMetricSpecification(v)
}

if v, ok := ttspCfg["predefined_metric_specification"].([]interface{}); ok && len(v) > 0 {
cfg.PredefinedMetricSpecification = expandAppautoscalingPredefinedMetricSpecification(v)
}

params.TargetTrackingScalingPolicyConfiguration = cfg
}

return params, nil
}

Expand Down Expand Up @@ -466,6 +656,78 @@ func flattenAppautoscalingStepAdjustments(adjs []*applicationautoscaling.StepAdj
return out
}

func flattenTargetTrackingScalingPolicyConfiguration(cfg *applicationautoscaling.TargetTrackingScalingPolicyConfiguration) []interface{} {
if cfg == nil {
return []interface{}{}
}

m := make(map[string]interface{}, 0)
m["target_value"] = *cfg.TargetValue

if cfg.DisableScaleIn != nil {
m["disable_scale_in"] = *cfg.DisableScaleIn
}
if cfg.ScaleInCooldown != nil {
m["scale_in_cooldown"] = *cfg.ScaleInCooldown
}
if cfg.ScaleOutCooldown != nil {
m["scale_out_cooldown"] = *cfg.ScaleOutCooldown
}
if cfg.CustomizedMetricSpecification != nil {
m["customized_metric_specification"] = flattenCustomizedMetricSpecification(cfg.CustomizedMetricSpecification)
}
if cfg.PredefinedMetricSpecification != nil {
m["predefined_metric_specification"] = flattenPredefinedMetricSpecification(cfg.PredefinedMetricSpecification)
}

return []interface{}{m}
}

func flattenCustomizedMetricSpecification(cfg *applicationautoscaling.CustomizedMetricSpecification) []interface{} {
if cfg == nil {
return []interface{}{}
}

m := map[string]interface{}{
"metric_name": *cfg.MetricName,
"namespace": *cfg.Namespace,
"statistic": *cfg.Statistic,
}

if len(cfg.Dimensions) > 0 {
m["dimensions"] = flattenMetricDimensions(cfg.Dimensions)
}

if cfg.Unit != nil {
m["unit"] = *cfg.Unit
}
return []interface{}{m}
}

func flattenMetricDimensions(ds []*applicationautoscaling.MetricDimension) []interface{} {
l := make([]interface{}, len(ds), len(ds))
for i, d := range ds {
l[i] = map[string]interface{}{
"name": *d.Name,
"value": *d.Value,
}
}
return l
}

func flattenPredefinedMetricSpecification(cfg *applicationautoscaling.PredefinedMetricSpecification) []interface{} {
if cfg == nil {
return []interface{}{}
}
m := map[string]interface{}{
"predefined_metric_type": *cfg.PredefinedMetricType,
}
if cfg.ResourceLabel != nil {
m["resource_label"] = *cfg.ResourceLabel
}
return []interface{}{m}
}

func resourceAwsAppautoscalingAdjustmentHash(v interface{}) int {
var buf bytes.Buffer
m := v.(map[string]interface{})
Expand Down
Loading

0 comments on commit 50f7481

Please sign in to comment.