From 43c8366c481172c21c4be65617d3b9ae4a420c19 Mon Sep 17 00:00:00 2001 From: stack72 Date: Fri, 13 Jan 2017 11:27:42 +0000 Subject: [PATCH] provider/aws: Add Support for aws_cloudwatch_metric_alarm extended statistic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: #11189 This introduces a new parameter and makes an existing parameter from `required` to `optional` as both cannot be specified together ``` % make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSCloudWatchMetricAlarm_' 2 ↵ ✹ ✭ ==> Checking that code complies with gofmt requirements... go generate $(go list ./... | grep -v /terraform/vendor/) 2017/01/13 11:25:24 Generated command/internal_plugin_list.go TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSCloudWatchMetricAlarm_ -timeout 120m === RUN TestAccAWSCloudWatchMetricAlarm_importBasic --- PASS: TestAccAWSCloudWatchMetricAlarm_importBasic (19.80s) === RUN TestAccAWSCloudWatchMetricAlarm_basic --- PASS: TestAccAWSCloudWatchMetricAlarm_basic (20.42s) === RUN TestAccAWSCloudWatchMetricAlarm_extendedStatistic --- PASS: TestAccAWSCloudWatchMetricAlarm_extendedStatistic (18.92s) PASS ``` --- .../resource_aws_cloudwatch_metric_alarm.go | 57 ++++++++++----- ...source_aws_cloudwatch_metric_alarm_test.go | 71 ++++++++++++++++++- .../r/cloudwatch_metric_alarm.html.markdown | 8 ++- 3 files changed, 115 insertions(+), 21 deletions(-) diff --git a/builtin/providers/aws/resource_aws_cloudwatch_metric_alarm.go b/builtin/providers/aws/resource_aws_cloudwatch_metric_alarm.go index 72a1e43c5059..95153030e260 100644 --- a/builtin/providers/aws/resource_aws_cloudwatch_metric_alarm.go +++ b/builtin/providers/aws/resource_aws_cloudwatch_metric_alarm.go @@ -21,74 +21,80 @@ func resourceAwsCloudWatchMetricAlarm() *schema.Resource { }, Schema: map[string]*schema.Schema{ - "alarm_name": &schema.Schema{ + "alarm_name": { Type: schema.TypeString, Required: true, ForceNew: true, }, - "comparison_operator": &schema.Schema{ + "comparison_operator": { Type: schema.TypeString, Required: true, }, - "evaluation_periods": &schema.Schema{ + "evaluation_periods": { Type: schema.TypeInt, Required: true, }, - "metric_name": &schema.Schema{ + "metric_name": { Type: schema.TypeString, Required: true, }, - "namespace": &schema.Schema{ + "namespace": { Type: schema.TypeString, Required: true, }, - "period": &schema.Schema{ + "period": { Type: schema.TypeInt, Required: true, }, - "statistic": &schema.Schema{ - Type: schema.TypeString, - Required: true, + "statistic": { + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"extended_statistic"}, }, - "threshold": &schema.Schema{ + "threshold": { Type: schema.TypeFloat, Required: true, }, - "actions_enabled": &schema.Schema{ + "actions_enabled": { Type: schema.TypeBool, Optional: true, Default: true, }, - "alarm_actions": &schema.Schema{ + "alarm_actions": { Type: schema.TypeSet, Optional: true, Elem: &schema.Schema{Type: schema.TypeString}, Set: schema.HashString, }, - "alarm_description": &schema.Schema{ + "alarm_description": { Type: schema.TypeString, Optional: true, }, - "dimensions": &schema.Schema{ + "dimensions": { Type: schema.TypeMap, Optional: true, }, - "insufficient_data_actions": &schema.Schema{ + "insufficient_data_actions": { Type: schema.TypeSet, Optional: true, Elem: &schema.Schema{Type: schema.TypeString}, Set: schema.HashString, }, - "ok_actions": &schema.Schema{ + "ok_actions": { Type: schema.TypeSet, Optional: true, Elem: &schema.Schema{Type: schema.TypeString}, Set: schema.HashString, }, - "unit": &schema.Schema{ + "unit": { Type: schema.TypeString, Optional: true, }, + "extended_statistic": { + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"statistic"}, + }, }, } } @@ -96,6 +102,13 @@ func resourceAwsCloudWatchMetricAlarm() *schema.Resource { func resourceAwsCloudWatchMetricAlarmCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).cloudwatchconn + _, statisticOk := d.GetOk("statistic") + _, extendedStatisticOk := d.GetOk("extended_statistic") + + if !statisticOk && !extendedStatisticOk { + return fmt.Errorf("One of `statistic` or `extended_statistic` must be set for a cloudwatch metric alarm") + } + params := getAwsCloudWatchPutMetricAlarmInput(d) log.Printf("[DEBUG] Creating CloudWatch Metric Alarm: %#v", params) @@ -147,6 +160,7 @@ func resourceAwsCloudWatchMetricAlarmRead(d *schema.ResourceData, meta interface d.Set("statistic", a.Statistic) d.Set("threshold", a.Threshold) d.Set("unit", a.Unit) + d.Set("extended_statistic", a.ExtendedStatistic) return nil } @@ -199,7 +213,6 @@ func getAwsCloudWatchPutMetricAlarmInput(d *schema.ResourceData) cloudwatch.PutM MetricName: aws.String(d.Get("metric_name").(string)), Namespace: aws.String(d.Get("namespace").(string)), Period: aws.Int64(int64(d.Get("period").(int))), - Statistic: aws.String(d.Get("statistic").(string)), Threshold: aws.Float64(d.Get("threshold").(float64)), } @@ -215,6 +228,14 @@ func getAwsCloudWatchPutMetricAlarmInput(d *schema.ResourceData) cloudwatch.PutM params.Unit = aws.String(v.(string)) } + if v, ok := d.GetOk("statistic"); ok { + params.Statistic = aws.String(v.(string)) + } + + if v, ok := d.GetOk("extended_statistic"); ok { + params.ExtendedStatistic = aws.String(v.(string)) + } + var alarmActions []*string if v := d.Get("alarm_actions"); v != nil { for _, v := range v.(*schema.Set).List() { diff --git a/builtin/providers/aws/resource_aws_cloudwatch_metric_alarm_test.go b/builtin/providers/aws/resource_aws_cloudwatch_metric_alarm_test.go index fc34b038f9f2..a3f902c4db3d 100644 --- a/builtin/providers/aws/resource_aws_cloudwatch_metric_alarm_test.go +++ b/builtin/providers/aws/resource_aws_cloudwatch_metric_alarm_test.go @@ -2,6 +2,7 @@ package aws import ( "fmt" + "regexp" "testing" "github.com/aws/aws-sdk-go/aws" @@ -18,7 +19,7 @@ func TestAccAWSCloudWatchMetricAlarm_basic(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccCheckAWSCloudWatchMetricAlarmDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: testAccAWSCloudWatchMetricAlarmConfig, Check: resource.ComposeTestCheckFunc( testAccCheckCloudWatchMetricAlarmExists("aws_cloudwatch_metric_alarm.foobar", &alarm), @@ -32,6 +33,39 @@ func TestAccAWSCloudWatchMetricAlarm_basic(t *testing.T) { }) } +func TestAccAWSCloudWatchMetricAlarm_extendedStatistic(t *testing.T) { + var alarm cloudwatch.MetricAlarm + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSCloudWatchMetricAlarmDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSCloudWatchMetricAlarmConfigExtendedStatistic, + Check: resource.ComposeTestCheckFunc( + testAccCheckCloudWatchMetricAlarmExists("aws_cloudwatch_metric_alarm.foobar", &alarm), + resource.TestCheckResourceAttr("aws_cloudwatch_metric_alarm.foobar", "extended_statistic", "p88.0"), + ), + }, + }, + }) +} + +func TestAccAWSCloudWatchMetricAlarm_missingStatistic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSCloudWatchMetricAlarmDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSCloudWatchMetricAlarmConfigMissingStatistic, + ExpectError: regexp.MustCompile("One of `statistic` or `extended_statistic` must be set for a cloudwatch metric alarm"), + }, + }, + }) +} + func testAccCheckCloudWatchMetricAlarmDimension(n, k, v string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] @@ -116,3 +150,38 @@ resource "aws_cloudwatch_metric_alarm" "foobar" { } } `) + +var testAccAWSCloudWatchMetricAlarmConfigExtendedStatistic = fmt.Sprintf(` +resource "aws_cloudwatch_metric_alarm" "foobar" { + alarm_name = "terraform-test-foobar6" + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = "2" + metric_name = "CPUUtilization" + namespace = "AWS/EC2" + period = "120" + extended_statistic = "p88.0" + threshold = "80" + alarm_description = "This metric monitors ec2 cpu utilization" + insufficient_data_actions = [] + dimensions { + InstanceId = "i-abc123" + } +} +`) + +var testAccAWSCloudWatchMetricAlarmConfigMissingStatistic = fmt.Sprintf(` +resource "aws_cloudwatch_metric_alarm" "foobar" { + alarm_name = "terraform-test-foobar6" + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = "2" + metric_name = "CPUUtilization" + namespace = "AWS/EC2" + period = "120" + threshold = "80" + alarm_description = "This metric monitors ec2 cpu utilization" + insufficient_data_actions = [] + dimensions { + InstanceId = "i-abc123" + } +} +`) diff --git a/website/source/docs/providers/aws/r/cloudwatch_metric_alarm.html.markdown b/website/source/docs/providers/aws/r/cloudwatch_metric_alarm.html.markdown index d91b8863e021..9e4d3b06a76b 100644 --- a/website/source/docs/providers/aws/r/cloudwatch_metric_alarm.html.markdown +++ b/website/source/docs/providers/aws/r/cloudwatch_metric_alarm.html.markdown @@ -52,6 +52,10 @@ resource "aws_cloudwatch_metric_alarm" "bat" { alarm_actions = ["${aws_autoscaling_policy.bat.arn}"] } ``` + +~> **NOTE:** You cannot create a metric alarm consisting of both `statistic` and `extended_statistic` parameters. +You must choose one or the other + ## Argument Reference See [related part of AWS Docs](https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_PutMetricAlarm.html) @@ -67,7 +71,7 @@ The following arguments are supported: * `namespace` - (Required) The namespace for the alarm's associated metric. See docs for the [list of namespaces](https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/aws-namespaces.html). See docs for [supported metrics](https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/CW_Support_For_AWS.html). * `period` - (Required) The period in seconds over which the specified `statistic` is applied. -* `statistic` - (Required) The statistic to apply to the alarm's associated metric. +* `statistic` - (Optional) The statistic to apply to the alarm's associated metric. Either of the following is supported: `SampleCount`, `Average`, `Sum`, `Minimum`, `Maximum` * `threshold` - (Required) The value against which the specified statistic is compared. * `actions_enabled` - (Optional) Indicates whether or not actions should be executed during any changes to the alarm's state. Defaults to `true`. @@ -77,6 +81,7 @@ The following arguments are supported: * `insufficient_data_actions` - (Optional) The list of actions to execute when this alarm transitions into an INSUFFICIENT_DATA state from any other state. Each action is specified as an Amazon Resource Number (ARN). * `ok_actions` - (Optional) The list of actions to execute when this alarm transitions into an OK state from any other state. Each action is specified as an Amazon Resource Number (ARN). * `unit` - (Optional) The unit for the alarm's associated metric. +* `extended_statistic` - (Optional) The percentile statistic for the metric associated with the alarm. Specify a value between p0.0 and p100. ## Attributes Reference @@ -85,7 +90,6 @@ The following attributes are exported: * `id` - The ID of the health check - ## Import Cloud Metric Alarms can be imported using the `alarm_name`, e.g.