Skip to content

Commit

Permalink
Merge branch 'nikhil-goenka-aws_ssm_association'
Browse files Browse the repository at this point in the history
  • Loading branch information
bflad committed Feb 12, 2021
2 parents 20db73c + c4779c6 commit 8b42218
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 4 deletions.
3 changes: 3 additions & 0 deletions .changelog/15038.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/aws_ssm_association: Add `apply_only_at_cron_interval` argument
```
14 changes: 14 additions & 0 deletions aws/resource_aws_ssm_association.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ func resourceAwsSsmAssociation() *schema.Resource {
SchemaVersion: 1,

Schema: map[string]*schema.Schema{
"apply_only_at_cron_interval": {
Type: schema.TypeBool,
Default: false,
Optional: true,
},
"association_name": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -133,6 +138,10 @@ func resourceAwsSsmAssociationCreate(d *schema.ResourceData, meta interface{}) e
Name: aws.String(d.Get("name").(string)),
}

if v, ok := d.GetOk("apply_only_at_cron_interval"); ok {
associationInput.ApplyOnlyAtCronInterval = aws.Bool(v.(bool))
}

if v, ok := d.GetOk("association_name"); ok {
associationInput.AssociationName = aws.String(v.(string))
}
Expand Down Expand Up @@ -215,6 +224,7 @@ func resourceAwsSsmAssociationRead(d *schema.ResourceData, meta interface{}) err
}

association := resp.AssociationDescription
d.Set("apply_only_at_cron_interval", association.ApplyOnlyAtCronInterval)
d.Set("association_name", association.AssociationName)
d.Set("instance_id", association.InstanceId)
d.Set("name", association.Name)
Expand Down Expand Up @@ -250,6 +260,10 @@ func resourceAwsSsmAssociationUpdate(d *schema.ResourceData, meta interface{}) e
AssociationId: aws.String(d.Get("association_id").(string)),
}

if v, ok := d.GetOk("apply_only_at_cron_interval"); ok {
associationInput.ApplyOnlyAtCronInterval = aws.Bool(v.(bool))
}

// AWS creates a new version every time the association is updated, so everything should be passed in the update.
if v, ok := d.GetOk("association_name"); ok {
associationInput.AssociationName = aws.String(v.(string))
Expand Down
80 changes: 76 additions & 4 deletions aws/resource_aws_ssm_association_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ func TestAccAWSSSMAssociation_basic(t *testing.T) {
Config: testAccAWSSSMAssociationBasicConfig(name),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSSSMAssociationExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "apply_only_at_cron_interval", "false"),
),
},
{
Expand Down Expand Up @@ -56,6 +57,38 @@ func TestAccAWSSSMAssociation_disappears(t *testing.T) {
})
}

func TestAccAWSSSMAssociation_ApplyOnlyAtCronInterval(t *testing.T) {
name := acctest.RandString(10)
resourceName := "aws_ssm_association.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSSSMAssociationDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSSSMAssociationBasicConfigWithApplyOnlyAtCronInterval(name, true),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSSSMAssociationExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "apply_only_at_cron_interval", "true"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccAWSSSMAssociationBasicConfigWithApplyOnlyAtCronInterval(name, false),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSSSMAssociationExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "apply_only_at_cron_interval", "false"),
),
},
},
})
}

func TestAccAWSSSMAssociation_withTargets(t *testing.T) {
name := acctest.RandString(10)
resourceName := "aws_ssm_association.test"
Expand Down Expand Up @@ -364,8 +397,7 @@ func TestAccAWSSSMAssociation_withScheduleExpression(t *testing.T) {
Config: testAccAWSSSMAssociationBasicConfigWithScheduleExpression(name),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSSSMAssociationExists(resourceName),
resource.TestCheckResourceAttr(
resourceName, "schedule_expression", "cron(0 16 ? * TUE *)"),
resource.TestCheckResourceAttr(resourceName, "schedule_expression", "cron(0 16 ? * TUE *)"),
),
},
{
Expand All @@ -377,8 +409,7 @@ func TestAccAWSSSMAssociation_withScheduleExpression(t *testing.T) {
Config: testAccAWSSSMAssociationBasicConfigWithScheduleExpressionUpdated(name),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSSSMAssociationExists(resourceName),
resource.TestCheckResourceAttr(
resourceName, "schedule_expression", "cron(0 16 ? * WED *)"),
resource.TestCheckResourceAttr(resourceName, "schedule_expression", "cron(0 16 ? * WED *)"),
),
},
},
Expand Down Expand Up @@ -519,6 +550,47 @@ func testAccCheckAWSSSMAssociationDestroy(s *terraform.State) error {
return nil
}

func testAccAWSSSMAssociationBasicConfigWithApplyOnlyAtCronInterval(rName string, applyOnlyAtCronInterval bool) string {
return fmt.Sprintf(`
resource "aws_ssm_document" "test" {
name = "test_document_association-%s"
document_type = "Command"
content = <<DOC
{
"schemaVersion": "1.2",
"description": "Check ip configuration of a Linux instance.",
"parameters": {},
"runtimeConfig": {
"aws:runShellScript": {
"properties": [
{
"id": "0.aws:runShellScript",
"runCommand": [
"ifconfig"
]
}
]
}
}
}
DOC
}
resource "aws_ssm_association" "test" {
name = aws_ssm_document.test.name
schedule_expression = "cron(0 16 ? * TUE *)"
apply_only_at_cron_interval = %[2]t
targets {
key = "tag:Name"
values = ["acceptanceTest"]
}
}
`, rName, applyOnlyAtCronInterval)
}

func testAccAWSSSMAssociationBasicConfigWithAutomationTargetParamName(rName string) string {
return composeConfig(testAccLatestAmazonLinuxHvmEbsAmiConfig(), fmt.Sprintf(`
resource "aws_iam_instance_profile" "ssm_profile" {
Expand Down
1 change: 1 addition & 0 deletions website/docs/r/ssm_association.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ resource "aws_ssm_association" "example" {
The following arguments are supported:

* `name` - (Required) The name of the SSM document to apply.
* `apply_only_at_cron_interval` - (Optional) By default, when you create a new or update associations, the system runs it immediately and then according to the schedule you specified. Enable this option if you do not want an association to run immediately after you create or update it. This parameter is not supported for rate expressions. Default: `false`.
* `association_name` - (Optional) The descriptive name for the association.
* `document_version` - (Optional) The document version you want to associate with the target(s). Can be a specific version or the default version.
* `instance_id` - (Optional) The instance ID to apply an SSM document to. Use `targets` with key `InstanceIds` for document schema versions 2.0 and above.
Expand Down

0 comments on commit 8b42218

Please sign in to comment.