github.com/andresvia/terraform@v0.6.15-0.20160412045437-d51c75946785/builtin/providers/aws/resource_aws_autoscaling_policy.go (about)

     1  package aws
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"log"
     7  
     8  	"github.com/aws/aws-sdk-go/aws"
     9  	"github.com/aws/aws-sdk-go/service/autoscaling"
    10  	"github.com/hashicorp/terraform/helper/hashcode"
    11  	"github.com/hashicorp/terraform/helper/schema"
    12  )
    13  
    14  func resourceAwsAutoscalingPolicy() *schema.Resource {
    15  	return &schema.Resource{
    16  		Create: resourceAwsAutoscalingPolicyCreate,
    17  		Read:   resourceAwsAutoscalingPolicyRead,
    18  		Update: resourceAwsAutoscalingPolicyUpdate,
    19  		Delete: resourceAwsAutoscalingPolicyDelete,
    20  
    21  		Schema: map[string]*schema.Schema{
    22  			"arn": &schema.Schema{
    23  				Type:     schema.TypeString,
    24  				Computed: true,
    25  			},
    26  			"name": &schema.Schema{
    27  				Type:     schema.TypeString,
    28  				Required: true,
    29  				ForceNew: true,
    30  			},
    31  			"adjustment_type": &schema.Schema{
    32  				Type:     schema.TypeString,
    33  				Required: true,
    34  			},
    35  			"autoscaling_group_name": &schema.Schema{
    36  				Type:     schema.TypeString,
    37  				Required: true,
    38  				ForceNew: true,
    39  			},
    40  			"policy_type": &schema.Schema{
    41  				Type:     schema.TypeString,
    42  				Optional: true,
    43  				Default:  "SimpleScaling", // preserve AWS's default to make validation easier.
    44  			},
    45  			"cooldown": &schema.Schema{
    46  				Type:     schema.TypeInt,
    47  				Optional: true,
    48  			},
    49  			"estimated_instance_warmup": &schema.Schema{
    50  				Type:     schema.TypeInt,
    51  				Optional: true,
    52  			},
    53  			"metric_aggregation_type": &schema.Schema{
    54  				Type:     schema.TypeString,
    55  				Optional: true,
    56  			},
    57  			"min_adjustment_magnitude": &schema.Schema{
    58  				Type:     schema.TypeInt,
    59  				Optional: true,
    60  			},
    61  			"min_adjustment_step": &schema.Schema{
    62  				Type:          schema.TypeInt,
    63  				Optional:      true,
    64  				Deprecated:    "Use min_adjustment_magnitude instead.",
    65  				ConflictsWith: []string{"min_adjustment_magnitude"},
    66  			},
    67  			"scaling_adjustment": &schema.Schema{
    68  				Type:          schema.TypeInt,
    69  				Optional:      true,
    70  				ConflictsWith: []string{"step_adjustment"},
    71  			},
    72  			"step_adjustment": &schema.Schema{
    73  				Type:          schema.TypeSet,
    74  				Optional:      true,
    75  				ConflictsWith: []string{"scaling_adjustment"},
    76  				Elem: &schema.Resource{
    77  					Schema: map[string]*schema.Schema{
    78  						"metric_interval_lower_bound": &schema.Schema{
    79  							Type:     schema.TypeString,
    80  							Optional: true,
    81  						},
    82  						"metric_interval_upper_bound": &schema.Schema{
    83  							Type:     schema.TypeString,
    84  							Optional: true,
    85  						},
    86  						"scaling_adjustment": &schema.Schema{
    87  							Type:     schema.TypeInt,
    88  							Required: true,
    89  						},
    90  					},
    91  				},
    92  				Set: resourceAwsAutoscalingScalingAdjustmentHash,
    93  			},
    94  		},
    95  	}
    96  }
    97  
    98  func resourceAwsAutoscalingPolicyCreate(d *schema.ResourceData, meta interface{}) error {
    99  	autoscalingconn := meta.(*AWSClient).autoscalingconn
   100  
   101  	params, err := getAwsAutoscalingPutScalingPolicyInput(d)
   102  	if err != nil {
   103  		return err
   104  	}
   105  
   106  	log.Printf("[DEBUG] AutoScaling PutScalingPolicy: %#v", params)
   107  	resp, err := autoscalingconn.PutScalingPolicy(&params)
   108  	if err != nil {
   109  		return fmt.Errorf("Error putting scaling policy: %s", err)
   110  	}
   111  
   112  	d.Set("arn", resp.PolicyARN)
   113  	d.SetId(d.Get("name").(string))
   114  	log.Printf("[INFO] AutoScaling Scaling PolicyARN: %s", d.Get("arn").(string))
   115  
   116  	return resourceAwsAutoscalingPolicyRead(d, meta)
   117  }
   118  
   119  func resourceAwsAutoscalingPolicyRead(d *schema.ResourceData, meta interface{}) error {
   120  	p, err := getAwsAutoscalingPolicy(d, meta)
   121  	if err != nil {
   122  		return err
   123  	}
   124  	if p == nil {
   125  		d.SetId("")
   126  		return nil
   127  	}
   128  
   129  	log.Printf("[DEBUG] Read Scaling Policy: ASG: %s, SP: %s, Obj: %#v", d.Get("autoscaling_group_name"), d.Get("name"), p)
   130  
   131  	d.Set("adjustment_type", p.AdjustmentType)
   132  	d.Set("autoscaling_group_name", p.AutoScalingGroupName)
   133  	d.Set("cooldown", p.Cooldown)
   134  	d.Set("estimated_instance_warmup", p.EstimatedInstanceWarmup)
   135  	d.Set("metric_aggregation_type", p.MetricAggregationType)
   136  	d.Set("policy_type", p.PolicyType)
   137  	d.Set("min_adjustment_magnitude", p.MinAdjustmentMagnitude)
   138  	d.Set("min_adjustment_step", p.MinAdjustmentStep)
   139  	d.Set("arn", p.PolicyARN)
   140  	d.Set("name", p.PolicyName)
   141  	d.Set("scaling_adjustment", p.ScalingAdjustment)
   142  	d.Set("step_adjustment", flattenStepAdjustments(p.StepAdjustments))
   143  
   144  	return nil
   145  }
   146  
   147  func resourceAwsAutoscalingPolicyUpdate(d *schema.ResourceData, meta interface{}) error {
   148  	autoscalingconn := meta.(*AWSClient).autoscalingconn
   149  
   150  	params, inputErr := getAwsAutoscalingPutScalingPolicyInput(d)
   151  	if inputErr != nil {
   152  		return inputErr
   153  	}
   154  
   155  	log.Printf("[DEBUG] Autoscaling Update Scaling Policy: %#v", params)
   156  	_, err := autoscalingconn.PutScalingPolicy(&params)
   157  	if err != nil {
   158  		return err
   159  	}
   160  
   161  	return resourceAwsAutoscalingPolicyRead(d, meta)
   162  }
   163  
   164  func resourceAwsAutoscalingPolicyDelete(d *schema.ResourceData, meta interface{}) error {
   165  	autoscalingconn := meta.(*AWSClient).autoscalingconn
   166  	p, err := getAwsAutoscalingPolicy(d, meta)
   167  	if err != nil {
   168  		return err
   169  	}
   170  	if p == nil {
   171  		return nil
   172  	}
   173  
   174  	params := autoscaling.DeletePolicyInput{
   175  		AutoScalingGroupName: aws.String(d.Get("autoscaling_group_name").(string)),
   176  		PolicyName:           aws.String(d.Get("name").(string)),
   177  	}
   178  	if _, err := autoscalingconn.DeletePolicy(&params); err != nil {
   179  		return fmt.Errorf("Autoscaling Scaling Policy: %s ", err)
   180  	}
   181  
   182  	d.SetId("")
   183  	return nil
   184  }
   185  
   186  // PutScalingPolicy can safely resend all parameters without destroying the
   187  // resource, so create and update can share this common function. It will error
   188  // if certain mutually exclusive values are set.
   189  func getAwsAutoscalingPutScalingPolicyInput(d *schema.ResourceData) (autoscaling.PutScalingPolicyInput, error) {
   190  	var params = autoscaling.PutScalingPolicyInput{
   191  		AutoScalingGroupName: aws.String(d.Get("autoscaling_group_name").(string)),
   192  		PolicyName:           aws.String(d.Get("name").(string)),
   193  	}
   194  
   195  	if v, ok := d.GetOk("adjustment_type"); ok {
   196  		params.AdjustmentType = aws.String(v.(string))
   197  	}
   198  
   199  	if v, ok := d.GetOk("cooldown"); ok {
   200  		params.Cooldown = aws.Int64(int64(v.(int)))
   201  	}
   202  
   203  	if v, ok := d.GetOk("estimated_instance_warmup"); ok {
   204  		params.EstimatedInstanceWarmup = aws.Int64(int64(v.(int)))
   205  	}
   206  
   207  	if v, ok := d.GetOk("metric_aggregation_type"); ok {
   208  		params.MetricAggregationType = aws.String(v.(string))
   209  	}
   210  
   211  	if v, ok := d.GetOk("policy_type"); ok {
   212  		params.PolicyType = aws.String(v.(string))
   213  	}
   214  
   215  	if v, ok := d.GetOk("scaling_adjustment"); ok {
   216  		params.ScalingAdjustment = aws.Int64(int64(v.(int)))
   217  	}
   218  
   219  	if v, ok := d.GetOk("step_adjustment"); ok {
   220  		steps, err := expandStepAdjustments(v.(*schema.Set).List())
   221  		if err != nil {
   222  			return params, fmt.Errorf("metric_interval_lower_bound and metric_interval_upper_bound must be strings!")
   223  		}
   224  		params.StepAdjustments = steps
   225  	}
   226  
   227  	if v, ok := d.GetOk("min_adjustment_magnitude"); ok {
   228  		params.MinAdjustmentMagnitude = aws.Int64(int64(v.(int)))
   229  	}
   230  
   231  	if v, ok := d.GetOk("min_adjustment_step"); ok {
   232  		params.MinAdjustmentStep = aws.Int64(int64(v.(int)))
   233  	}
   234  
   235  	// Validate our final input to confirm it won't error when sent to AWS.
   236  	// First, SimpleScaling policy types...
   237  	if *params.PolicyType == "SimpleScaling" && params.StepAdjustments != nil {
   238  		return params, fmt.Errorf("SimpleScaling policy types cannot use step_adjustments!")
   239  	}
   240  	if *params.PolicyType == "SimpleScaling" && params.MetricAggregationType != nil {
   241  		return params, fmt.Errorf("SimpleScaling policy types cannot use metric_aggregation_type!")
   242  	}
   243  	if *params.PolicyType == "SimpleScaling" && params.EstimatedInstanceWarmup != nil {
   244  		return params, fmt.Errorf("SimpleScaling policy types cannot use estimated_instance_warmup!")
   245  	}
   246  
   247  	// Second, StepScaling policy types...
   248  	if *params.PolicyType == "StepScaling" && params.ScalingAdjustment != nil {
   249  		return params, fmt.Errorf("StepScaling policy types cannot use scaling_adjustment!")
   250  	}
   251  	if *params.PolicyType == "StepScaling" && params.Cooldown != nil {
   252  		return params, fmt.Errorf("StepScaling policy types cannot use cooldown!")
   253  	}
   254  
   255  	return params, nil
   256  }
   257  
   258  func getAwsAutoscalingPolicy(d *schema.ResourceData, meta interface{}) (*autoscaling.ScalingPolicy, error) {
   259  	autoscalingconn := meta.(*AWSClient).autoscalingconn
   260  
   261  	params := autoscaling.DescribePoliciesInput{
   262  		AutoScalingGroupName: aws.String(d.Get("autoscaling_group_name").(string)),
   263  		PolicyNames:          []*string{aws.String(d.Get("name").(string))},
   264  	}
   265  
   266  	log.Printf("[DEBUG] AutoScaling Scaling Policy Describe Params: %#v", params)
   267  	resp, err := autoscalingconn.DescribePolicies(&params)
   268  	if err != nil {
   269  		return nil, fmt.Errorf("Error retrieving scaling policies: %s", err)
   270  	}
   271  
   272  	// find scaling policy
   273  	name := d.Get("name")
   274  	for idx, sp := range resp.ScalingPolicies {
   275  		if *sp.PolicyName == name {
   276  			return resp.ScalingPolicies[idx], nil
   277  		}
   278  	}
   279  
   280  	// policy not found
   281  	return nil, nil
   282  }
   283  
   284  func resourceAwsAutoscalingScalingAdjustmentHash(v interface{}) int {
   285  	var buf bytes.Buffer
   286  	m := v.(map[string]interface{})
   287  	if v, ok := m["metric_interval_lower_bound"]; ok {
   288  		buf.WriteString(fmt.Sprintf("%f-", v))
   289  	}
   290  	if v, ok := m["metric_interval_upper_bound"]; ok {
   291  		buf.WriteString(fmt.Sprintf("%f-", v))
   292  	}
   293  	buf.WriteString(fmt.Sprintf("%d-", m["scaling_adjustment"].(int)))
   294  
   295  	return hashcode.String(buf.String())
   296  }