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