diff --git a/aws/resource_aws_ssm_maintenance_window_target.go b/aws/resource_aws_ssm_maintenance_window_target.go index e4f1a0c7be6..dfced2ee2c8 100644 --- a/aws/resource_aws_ssm_maintenance_window_target.go +++ b/aws/resource_aws_ssm_maintenance_window_target.go @@ -3,10 +3,12 @@ package aws import ( "fmt" "log" + "regexp" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ssm" "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" ) func resourceAwsSsmMaintenanceWindowTarget() *schema.Resource { @@ -48,6 +50,20 @@ func resourceAwsSsmMaintenanceWindowTarget() *schema.Resource { }, }, + "name": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validation.StringMatch(regexp.MustCompile(`^[a-zA-Z0-9_\-.]{3,128}$`), "Only alphanumeric characters, hyphens, dots & underscores allowed"), + }, + + "description": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(3, 128), + }, + "owner_information": { Type: schema.TypeString, Optional: true, @@ -65,6 +81,8 @@ func resourceAwsSsmMaintenanceWindowTargetCreate(d *schema.ResourceData, meta in WindowId: aws.String(d.Get("window_id").(string)), ResourceType: aws.String(d.Get("resource_type").(string)), Targets: expandAwsSsmTargets(d.Get("targets").([]interface{})), + Name: aws.String(d.Get("name").(string)), + Description: aws.String(d.Get("description").(string)), } if v, ok := d.GetOk("owner_information"); ok { @@ -107,6 +125,8 @@ func resourceAwsSsmMaintenanceWindowTargetRead(d *schema.ResourceData, meta inte d.Set("owner_information", t.OwnerInformation) d.Set("window_id", t.WindowId) d.Set("resource_type", t.ResourceType) + d.Set("name", t.Name) + d.Set("description", t.Description) if err := d.Set("targets", flattenAwsSsmTargets(t.Targets)); err != nil { return fmt.Errorf("Error setting targets error: %#v", err) diff --git a/aws/resource_aws_ssm_maintenance_window_target_test.go b/aws/resource_aws_ssm_maintenance_window_target_test.go index e6b189788cc..d92e815b033 100644 --- a/aws/resource_aws_ssm_maintenance_window_target_test.go +++ b/aws/resource_aws_ssm_maintenance_window_target_test.go @@ -2,6 +2,7 @@ package aws import ( "fmt" + "regexp" "testing" "github.com/aws/aws-sdk-go/aws" @@ -30,6 +31,8 @@ func TestAccAWSSSMMaintenanceWindowTarget_basic(t *testing.T) { resource.TestCheckResourceAttr("aws_ssm_maintenance_window_target.target", "targets.1.values.#", "2"), resource.TestCheckResourceAttr("aws_ssm_maintenance_window_target.target", "targets.1.values.0", "acceptance_test"), resource.TestCheckResourceAttr("aws_ssm_maintenance_window_target.target", "targets.1.values.1", "acceptance_test2"), + resource.TestCheckResourceAttr("aws_ssm_maintenance_window_target.target", "name", "TestMaintenanceWindowTarget"), + resource.TestCheckResourceAttr("aws_ssm_maintenance_window_target.target", "description", "This resource is for test purpose only"), ), }, { @@ -41,6 +44,29 @@ func TestAccAWSSSMMaintenanceWindowTarget_basic(t *testing.T) { }) } +func TestAccAWSSSMMaintenanceWindowTarget_validation(t *testing.T) { + name := acctest.RandString(10) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSSMMaintenanceWindowTargetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSSMMaintenanceWindowTargetBasicConfigWithTarget(name, "Bäd Name!@#$%^", "good description"), + ExpectError: regexp.MustCompile(`Only alphanumeric characters, hyphens, dots & underscores allowed`), + }, + { + Config: testAccAWSSSMMaintenanceWindowTargetBasicConfigWithTarget(name, "goodname", "bd"), + ExpectError: regexp.MustCompile(`expected length of [\w]+ to be in the range \(3 - 128\), got [\w]+`), + }, + { + Config: testAccAWSSSMMaintenanceWindowTargetBasicConfigWithTarget(name, "goodname", "This description is tooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo long"), + ExpectError: regexp.MustCompile(`expected length of [\w]+ to be in the range \(3 - 128\), got [\w]+`), + }, + }, + }) +} + func TestAccAWSSSMMaintenanceWindowTarget_update(t *testing.T) { name := acctest.RandString(10) resource.ParallelTest(t, resource.TestCase{ @@ -59,6 +85,8 @@ func TestAccAWSSSMMaintenanceWindowTarget_update(t *testing.T) { resource.TestCheckResourceAttr("aws_ssm_maintenance_window_target.target", "targets.1.values.#", "2"), resource.TestCheckResourceAttr("aws_ssm_maintenance_window_target.target", "targets.1.values.0", "acceptance_test"), resource.TestCheckResourceAttr("aws_ssm_maintenance_window_target.target", "targets.1.values.1", "acceptance_test2"), + resource.TestCheckResourceAttr("aws_ssm_maintenance_window_target.target", "name", "TestMaintenanceWindowTarget"), + resource.TestCheckResourceAttr("aws_ssm_maintenance_window_target.target", "description", "This resource is for test purpose only"), ), }, { @@ -72,6 +100,8 @@ func TestAccAWSSSMMaintenanceWindowTarget_update(t *testing.T) { resource.TestCheckResourceAttr("aws_ssm_maintenance_window_target.target", "targets.1.key", "tag:Updated"), resource.TestCheckResourceAttr("aws_ssm_maintenance_window_target.target", "targets.1.values.#", "1"), resource.TestCheckResourceAttr("aws_ssm_maintenance_window_target.target", "targets.1.values.0", "new-value"), + resource.TestCheckResourceAttr("aws_ssm_maintenance_window_target.target", "name", "TestMaintenanceWindowTarget"), + resource.TestCheckResourceAttr("aws_ssm_maintenance_window_target.target", "description", "This resource is for test purpose only - updated"), ), }, }, @@ -160,6 +190,8 @@ resource "aws_ssm_maintenance_window" "foo" { } resource "aws_ssm_maintenance_window_target" "target" { + name = "TestMaintenanceWindowTarget" + description = "This resource is for test purpose only" window_id = "${aws_ssm_maintenance_window.foo.id}" resource_type = "INSTANCE" targets { @@ -184,6 +216,8 @@ resource "aws_ssm_maintenance_window" "foo" { } resource "aws_ssm_maintenance_window_target" "target" { + name = "TestMaintenanceWindowTarget" + description = "This resource is for test purpose only - updated" window_id = "${aws_ssm_maintenance_window.foo.id}" resource_type = "INSTANCE" owner_information = "something" @@ -198,3 +232,30 @@ resource "aws_ssm_maintenance_window_target" "target" { } `, rName) } + +func testAccAWSSSMMaintenanceWindowTargetBasicConfigWithTarget(rName, tName, tDesc string) string { + return fmt.Sprintf(` +resource "aws_ssm_maintenance_window" "foo" { + name = "maintenance-window-%s" + schedule = "cron(0 16 ? * TUE *)" + duration = 3 + cutoff = 1 +} + +resource "aws_ssm_maintenance_window_target" "target" { + name = "%s" + description = "%s" + window_id = "${aws_ssm_maintenance_window.foo.id}" + resource_type = "INSTANCE" + owner_information = "something" + targets { + key = "tag:Name" + values = ["acceptance_test"] + } + targets { + key = "tag:Updated" + values = ["new-value"] + } +} +`, rName, tName, tDesc) +} diff --git a/website/docs/r/ssm_maintenance_window_target.html.markdown b/website/docs/r/ssm_maintenance_window_target.html.markdown index dca2d0b568d..c8960afb686 100644 --- a/website/docs/r/ssm_maintenance_window_target.html.markdown +++ b/website/docs/r/ssm_maintenance_window_target.html.markdown @@ -22,6 +22,8 @@ resource "aws_ssm_maintenance_window" "window" { resource "aws_ssm_maintenance_window_target" "target1" { window_id = "${aws_ssm_maintenance_window.window.id}" + name = "maintenance-window-target" + description = "This is a maintenance window target" resource_type = "INSTANCE" targets { @@ -36,6 +38,8 @@ resource "aws_ssm_maintenance_window_target" "target1" { The following arguments are supported: * `window_id` - (Required) The Id of the maintenance window to register the target with. +* `name` - (Optional) The name of the maintenance window target. +* `description` - (Optional) The description of the maintenance window target. * `resource_type` - (Required) The type of target being registered with the Maintenance Window. Possible values `INSTANCE`. * `targets` - (Required) The targets (either instances or tags). Instances are specified using Key=instanceids,Values=instanceid1,instanceid2. Tags are specified using Key=tag name,Values=tag value. * `owner_information` - (Optional) User-provided value that will be included in any CloudWatch events raised while running tasks for these targets in this Maintenance Window.