github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/aws/resource_aws_cloudwatch_metric_alarm.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  
     7  	"github.com/hashicorp/terraform/helper/schema"
     8  
     9  	"github.com/aws/aws-sdk-go/aws"
    10  	"github.com/aws/aws-sdk-go/service/cloudwatch"
    11  )
    12  
    13  func resourceAwsCloudWatchMetricAlarm() *schema.Resource {
    14  	return &schema.Resource{
    15  		Create: resourceAwsCloudWatchMetricAlarmCreate,
    16  		Read:   resourceAwsCloudWatchMetricAlarmRead,
    17  		Update: resourceAwsCloudWatchMetricAlarmUpdate,
    18  		Delete: resourceAwsCloudWatchMetricAlarmDelete,
    19  		Importer: &schema.ResourceImporter{
    20  			State: schema.ImportStatePassthrough,
    21  		},
    22  
    23  		Schema: map[string]*schema.Schema{
    24  			"alarm_name": {
    25  				Type:     schema.TypeString,
    26  				Required: true,
    27  				ForceNew: true,
    28  			},
    29  			"comparison_operator": {
    30  				Type:     schema.TypeString,
    31  				Required: true,
    32  			},
    33  			"evaluation_periods": {
    34  				Type:     schema.TypeInt,
    35  				Required: true,
    36  			},
    37  			"metric_name": {
    38  				Type:     schema.TypeString,
    39  				Required: true,
    40  			},
    41  			"namespace": {
    42  				Type:     schema.TypeString,
    43  				Required: true,
    44  			},
    45  			"period": {
    46  				Type:     schema.TypeInt,
    47  				Required: true,
    48  			},
    49  			"statistic": {
    50  				Type:          schema.TypeString,
    51  				Optional:      true,
    52  				ConflictsWith: []string{"extended_statistic"},
    53  			},
    54  			"threshold": {
    55  				Type:     schema.TypeFloat,
    56  				Required: true,
    57  			},
    58  			"actions_enabled": {
    59  				Type:     schema.TypeBool,
    60  				Optional: true,
    61  				Default:  true,
    62  			},
    63  			"alarm_actions": {
    64  				Type:     schema.TypeSet,
    65  				Optional: true,
    66  				Elem:     &schema.Schema{Type: schema.TypeString},
    67  				Set:      schema.HashString,
    68  			},
    69  			"alarm_description": {
    70  				Type:     schema.TypeString,
    71  				Optional: true,
    72  			},
    73  			"dimensions": {
    74  				Type:     schema.TypeMap,
    75  				Optional: true,
    76  			},
    77  			"insufficient_data_actions": {
    78  				Type:     schema.TypeSet,
    79  				Optional: true,
    80  				Elem:     &schema.Schema{Type: schema.TypeString},
    81  				Set:      schema.HashString,
    82  			},
    83  			"ok_actions": {
    84  				Type:     schema.TypeSet,
    85  				Optional: true,
    86  				Elem:     &schema.Schema{Type: schema.TypeString},
    87  				Set:      schema.HashString,
    88  			},
    89  			"unit": {
    90  				Type:     schema.TypeString,
    91  				Optional: true,
    92  			},
    93  			"extended_statistic": {
    94  				Type:          schema.TypeString,
    95  				Optional:      true,
    96  				ConflictsWith: []string{"statistic"},
    97  			},
    98  		},
    99  	}
   100  }
   101  
   102  func resourceAwsCloudWatchMetricAlarmCreate(d *schema.ResourceData, meta interface{}) error {
   103  	conn := meta.(*AWSClient).cloudwatchconn
   104  
   105  	_, statisticOk := d.GetOk("statistic")
   106  	_, extendedStatisticOk := d.GetOk("extended_statistic")
   107  
   108  	if !statisticOk && !extendedStatisticOk {
   109  		return fmt.Errorf("One of `statistic` or `extended_statistic` must be set for a cloudwatch metric alarm")
   110  	}
   111  
   112  	params := getAwsCloudWatchPutMetricAlarmInput(d)
   113  
   114  	log.Printf("[DEBUG] Creating CloudWatch Metric Alarm: %#v", params)
   115  	_, err := conn.PutMetricAlarm(&params)
   116  	if err != nil {
   117  		return fmt.Errorf("Creating metric alarm failed: %s", err)
   118  	}
   119  	d.SetId(d.Get("alarm_name").(string))
   120  	log.Println("[INFO] CloudWatch Metric Alarm created")
   121  
   122  	return resourceAwsCloudWatchMetricAlarmRead(d, meta)
   123  }
   124  
   125  func resourceAwsCloudWatchMetricAlarmRead(d *schema.ResourceData, meta interface{}) error {
   126  	a, err := getAwsCloudWatchMetricAlarm(d, meta)
   127  	if err != nil {
   128  		return err
   129  	}
   130  	if a == nil {
   131  		d.SetId("")
   132  		return nil
   133  	}
   134  
   135  	log.Printf("[DEBUG] Reading CloudWatch Metric Alarm: %s", d.Get("alarm_name"))
   136  
   137  	d.Set("actions_enabled", a.ActionsEnabled)
   138  
   139  	if err := d.Set("alarm_actions", _strArrPtrToList(a.AlarmActions)); err != nil {
   140  		log.Printf("[WARN] Error setting Alarm Actions: %s", err)
   141  	}
   142  	d.Set("alarm_description", a.AlarmDescription)
   143  	d.Set("alarm_name", a.AlarmName)
   144  	d.Set("comparison_operator", a.ComparisonOperator)
   145  	if err := d.Set("dimensions", flattenDimensions(a.Dimensions)); err != nil {
   146  		return err
   147  	}
   148  	d.Set("evaluation_periods", a.EvaluationPeriods)
   149  
   150  	if err := d.Set("insufficient_data_actions", _strArrPtrToList(a.InsufficientDataActions)); err != nil {
   151  		log.Printf("[WARN] Error setting Insufficient Data Actions: %s", err)
   152  	}
   153  	d.Set("metric_name", a.MetricName)
   154  	d.Set("namespace", a.Namespace)
   155  
   156  	if err := d.Set("ok_actions", _strArrPtrToList(a.OKActions)); err != nil {
   157  		log.Printf("[WARN] Error setting OK Actions: %s", err)
   158  	}
   159  	d.Set("period", a.Period)
   160  	d.Set("statistic", a.Statistic)
   161  	d.Set("threshold", a.Threshold)
   162  	d.Set("unit", a.Unit)
   163  	d.Set("extended_statistic", a.ExtendedStatistic)
   164  
   165  	return nil
   166  }
   167  
   168  func resourceAwsCloudWatchMetricAlarmUpdate(d *schema.ResourceData, meta interface{}) error {
   169  	conn := meta.(*AWSClient).cloudwatchconn
   170  	params := getAwsCloudWatchPutMetricAlarmInput(d)
   171  
   172  	log.Printf("[DEBUG] Updating CloudWatch Metric Alarm: %#v", params)
   173  	_, err := conn.PutMetricAlarm(&params)
   174  	if err != nil {
   175  		return fmt.Errorf("Updating metric alarm failed: %s", err)
   176  	}
   177  	log.Println("[INFO] CloudWatch Metric Alarm updated")
   178  
   179  	return resourceAwsCloudWatchMetricAlarmRead(d, meta)
   180  }
   181  
   182  func resourceAwsCloudWatchMetricAlarmDelete(d *schema.ResourceData, meta interface{}) error {
   183  	p, err := getAwsCloudWatchMetricAlarm(d, meta)
   184  	if err != nil {
   185  		return err
   186  	}
   187  	if p == nil {
   188  		log.Printf("[DEBUG] CloudWatch Metric Alarm %s is already gone", d.Id())
   189  		return nil
   190  	}
   191  
   192  	log.Printf("[INFO] Deleting CloudWatch Metric Alarm: %s", d.Id())
   193  
   194  	conn := meta.(*AWSClient).cloudwatchconn
   195  	params := cloudwatch.DeleteAlarmsInput{
   196  		AlarmNames: []*string{aws.String(d.Id())},
   197  	}
   198  
   199  	if _, err := conn.DeleteAlarms(&params); err != nil {
   200  		return fmt.Errorf("Error deleting CloudWatch Metric Alarm: %s", err)
   201  	}
   202  	log.Println("[INFO] CloudWatch Metric Alarm deleted")
   203  
   204  	d.SetId("")
   205  	return nil
   206  }
   207  
   208  func getAwsCloudWatchPutMetricAlarmInput(d *schema.ResourceData) cloudwatch.PutMetricAlarmInput {
   209  	params := cloudwatch.PutMetricAlarmInput{
   210  		AlarmName:          aws.String(d.Get("alarm_name").(string)),
   211  		ComparisonOperator: aws.String(d.Get("comparison_operator").(string)),
   212  		EvaluationPeriods:  aws.Int64(int64(d.Get("evaluation_periods").(int))),
   213  		MetricName:         aws.String(d.Get("metric_name").(string)),
   214  		Namespace:          aws.String(d.Get("namespace").(string)),
   215  		Period:             aws.Int64(int64(d.Get("period").(int))),
   216  		Threshold:          aws.Float64(d.Get("threshold").(float64)),
   217  	}
   218  
   219  	if v := d.Get("actions_enabled"); v != nil {
   220  		params.ActionsEnabled = aws.Bool(v.(bool))
   221  	}
   222  
   223  	if v, ok := d.GetOk("alarm_description"); ok {
   224  		params.AlarmDescription = aws.String(v.(string))
   225  	}
   226  
   227  	if v, ok := d.GetOk("unit"); ok {
   228  		params.Unit = aws.String(v.(string))
   229  	}
   230  
   231  	if v, ok := d.GetOk("statistic"); ok {
   232  		params.Statistic = aws.String(v.(string))
   233  	}
   234  
   235  	if v, ok := d.GetOk("extended_statistic"); ok {
   236  		params.ExtendedStatistic = aws.String(v.(string))
   237  	}
   238  
   239  	var alarmActions []*string
   240  	if v := d.Get("alarm_actions"); v != nil {
   241  		for _, v := range v.(*schema.Set).List() {
   242  			str := v.(string)
   243  			alarmActions = append(alarmActions, aws.String(str))
   244  		}
   245  		params.AlarmActions = alarmActions
   246  	}
   247  
   248  	var insufficientDataActions []*string
   249  	if v := d.Get("insufficient_data_actions"); v != nil {
   250  		for _, v := range v.(*schema.Set).List() {
   251  			str := v.(string)
   252  			insufficientDataActions = append(insufficientDataActions, aws.String(str))
   253  		}
   254  		params.InsufficientDataActions = insufficientDataActions
   255  	}
   256  
   257  	var okActions []*string
   258  	if v := d.Get("ok_actions"); v != nil {
   259  		for _, v := range v.(*schema.Set).List() {
   260  			str := v.(string)
   261  			okActions = append(okActions, aws.String(str))
   262  		}
   263  		params.OKActions = okActions
   264  	}
   265  
   266  	a := d.Get("dimensions").(map[string]interface{})
   267  	dimensions := make([]*cloudwatch.Dimension, 0, len(a))
   268  	for k, v := range a {
   269  		dimensions = append(dimensions, &cloudwatch.Dimension{
   270  			Name:  aws.String(k),
   271  			Value: aws.String(v.(string)),
   272  		})
   273  	}
   274  	params.Dimensions = dimensions
   275  
   276  	return params
   277  }
   278  
   279  func getAwsCloudWatchMetricAlarm(d *schema.ResourceData, meta interface{}) (*cloudwatch.MetricAlarm, error) {
   280  	conn := meta.(*AWSClient).cloudwatchconn
   281  
   282  	params := cloudwatch.DescribeAlarmsInput{
   283  		AlarmNames: []*string{aws.String(d.Id())},
   284  	}
   285  
   286  	resp, err := conn.DescribeAlarms(&params)
   287  	if err != nil {
   288  		return nil, err
   289  	}
   290  
   291  	// Find it and return it
   292  	for idx, ma := range resp.MetricAlarms {
   293  		if *ma.AlarmName == d.Id() {
   294  			return resp.MetricAlarms[idx], nil
   295  		}
   296  	}
   297  
   298  	return nil, nil
   299  }
   300  
   301  func _strArrPtrToList(strArrPtr []*string) []string {
   302  	var result []string
   303  	for _, elem := range strArrPtr {
   304  		result = append(result, *elem)
   305  	}
   306  	return result
   307  }
   308  
   309  func flattenDimensions(dims []*cloudwatch.Dimension) map[string]interface{} {
   310  	flatDims := make(map[string]interface{})
   311  	for _, d := range dims {
   312  		flatDims[*d.Name] = *d.Value
   313  	}
   314  	return flatDims
   315  }