From 1fe2e3a3f702d0407560491bb82c0f1c23b6c179 Mon Sep 17 00:00:00 2001 From: Iain Adams Date: Fri, 4 Mar 2022 20:35:08 +0000 Subject: [PATCH] adds sync_compliance attribute to ssm_association resource, fixes #22945 --- .changelog/23515.txt | 3 ++ internal/service/ssm/association.go | 10 ++++ internal/service/ssm/association_test.go | 50 ++++++++++++++++++++ website/docs/r/ssm_association.html.markdown | 1 + 4 files changed, 64 insertions(+) create mode 100644 .changelog/23515.txt diff --git a/.changelog/23515.txt b/.changelog/23515.txt new file mode 100644 index 000000000000..52aeb23c4f8c --- /dev/null +++ b/.changelog/23515.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_ssm_association: Add `sync_compliance` attribute +``` diff --git a/internal/service/ssm/association.go b/internal/service/ssm/association.go index f620c021b64a..b3a8f702918b 100644 --- a/internal/service/ssm/association.go +++ b/internal/service/ssm/association.go @@ -43,6 +43,11 @@ func ResourceAssociation() *schema.Resource { Default: false, Optional: true, }, + "sync_compliance": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"AUTO", "MANUAL"}, false), + }, "association_name": { Type: schema.TypeString, Optional: true, @@ -166,6 +171,10 @@ func resourceAssociationCreate(ctx context.Context, d *schema.ResourceData, meta Name: aws.String(d.Get("name").(string)), } + if v, ok := d.GetOk("sync_compliance"); ok { + associationInput.SyncCompliance = aws.String(v.(string)) + } + if v, ok := d.GetOk("apply_only_at_cron_interval"); ok { associationInput.ApplyOnlyAtCronInterval = aws.Bool(v.(bool)) } @@ -260,6 +269,7 @@ func resourceAssociationRead(ctx context.Context, d *schema.ResourceData, meta i Resource: fmt.Sprintf("association/%s", aws.StringValue(association.AssociationId)), }.String() d.Set("arn", arn) + d.Set("sync_compliance", association.SyncCompliance) d.Set("apply_only_at_cron_interval", association.ApplyOnlyAtCronInterval) d.Set("association_name", association.AssociationName) d.Set("instance_id", association.InstanceId) diff --git a/internal/service/ssm/association_test.go b/internal/service/ssm/association_test.go index 5a776894fbf8..676767698010 100644 --- a/internal/service/ssm/association_test.go +++ b/internal/service/ssm/association_test.go @@ -608,6 +608,32 @@ func TestAccSSMAssociation_rateControl(t *testing.T) { }) } +func TestAccSSMAssociation_syncCompliance(t *testing.T) { + rName := "AWS-RunPatchBaselineAssociation" + resourceName := "aws_ssm_association.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, ssm.EndpointsID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckAssociationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAssociationSyncComplianceConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAssociationExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "sync_compliance", "MANUAL"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testAccCheckAssociationExists(ctx context.Context, n string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] @@ -1569,6 +1595,30 @@ resource "aws_ssm_association" "test" { `, rName, rate) } +func testAccAssociationSyncComplianceConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_ssm_association" "test" { + name = %[1]q + targets { + key = "InstanceIds" + values = ["*"] + } + apply_only_at_cron_interval = false + sync_compliance = "MANUAL" + parameters = { + Operation = "Scan" + RebootOption = "NoReboot" + } + schedule_expression = "cron(0 6 ? * * *)" + lifecycle { + ignore_changes = [ + parameters["AssociationId"] + ] + } +} +`, rName) +} + func testAccAssociationConfig_outputLocationAndWaitForSuccess(rName string) string { return acctest.ConfigCompose( testAccAssociationWithOutputLocationS3RegionConfigBase(rName), diff --git a/website/docs/r/ssm_association.html.markdown b/website/docs/r/ssm_association.html.markdown index 4e4aca7b1ce1..05642c5bd37c 100644 --- a/website/docs/r/ssm_association.html.markdown +++ b/website/docs/r/ssm_association.html.markdown @@ -84,6 +84,7 @@ resource "aws_ssm_association" "example" { The following arguments are supported: * `name` - (Required) The name of the SSM document to apply. +* `sync_compliance` - (Optional) The mode for generating association compliance. You can specify `AUTO` or `MANUAL`. * `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.