Skip to content

Commit

Permalink
Merge pull request #7970 from atsushi-ishibashi/issue6258
Browse files Browse the repository at this point in the history
resource/ssm_association: Support MaxConcurrency and MaxErrors
  • Loading branch information
bflad authored Mar 18, 2019
2 parents c07f924 + 7aab52b commit 099a05a
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 0 deletions.
29 changes: 29 additions & 0 deletions aws/resource_aws_ssm_association.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package aws
import (
"fmt"
"log"
"regexp"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ssm"
Expand Down Expand Up @@ -39,6 +40,16 @@ func resourceAwsSsmAssociation() *schema.Resource {
Optional: true,
Computed: true,
},
"max_concurrency": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringMatch(regexp.MustCompile(`^([1-9][0-9]*|[1-9][0-9]%|[1-9]%|100%)$`), "must be a valid number (e.g. 10) or percentage including the percent sign (e.g. 10%)"),
},
"max_errors": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringMatch(regexp.MustCompile(`^([1-9][0-9]*|[0]|[1-9][0-9]%|[0-9]%|100%)$`), "must be a valid number (e.g. 10) or percentage including the percent sign (e.g. 10%)"),
},
"name": {
Type: schema.TypeString,
ForceNew: true,
Expand Down Expand Up @@ -145,6 +156,14 @@ func resourceAwsSsmAssociationCreate(d *schema.ResourceData, meta interface{}) e
associationInput.ComplianceSeverity = aws.String(v.(string))
}

if v, ok := d.GetOk("max_concurrency"); ok {
associationInput.MaxConcurrency = aws.String(v.(string))
}

if v, ok := d.GetOk("max_errors"); ok {
associationInput.MaxErrors = aws.String(v.(string))
}

resp, err := ssmconn.CreateAssociation(associationInput)
if err != nil {
return fmt.Errorf("Error creating SSM association: %s", err)
Expand Down Expand Up @@ -191,6 +210,8 @@ func resourceAwsSsmAssociationRead(d *schema.ResourceData, meta interface{}) err
d.Set("schedule_expression", association.ScheduleExpression)
d.Set("document_version", association.DocumentVersion)
d.Set("compliance_severity", association.ComplianceSeverity)
d.Set("max_concurrency", association.MaxConcurrency)
d.Set("max_errors", association.MaxErrors)

if err := d.Set("targets", flattenAwsSsmTargets(association.Targets)); err != nil {
return fmt.Errorf("Error setting targets error: %#v", err)
Expand Down Expand Up @@ -241,6 +262,14 @@ func resourceAwsSsmAssociationUpdate(d *schema.ResourceData, meta interface{}) e
associationInput.ComplianceSeverity = aws.String(v.(string))
}

if v, ok := d.GetOk("max_concurrency"); ok {
associationInput.MaxConcurrency = aws.String(v.(string))
}

if v, ok := d.GetOk("max_errors"); ok {
associationInput.MaxErrors = aws.String(v.(string))
}

_, err := ssmconn.UpdateAssociation(associationInput)
if err != nil {
return fmt.Errorf("Error updating SSM association: %s", err)
Expand Down
67 changes: 67 additions & 0 deletions aws/resource_aws_ssm_association_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,37 @@ func TestAccAWSSSMAssociation_withComplianceSeverity(t *testing.T) {
})
}

func TestAccAWSSSMAssociation_rateControl(t *testing.T) {
name := acctest.RandString(10)
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSSSMAssociationDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSSSMAssociationRateControlConfig(name, "10%"),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSSSMAssociationExists("aws_ssm_association.foo"),
resource.TestCheckResourceAttr(
"aws_ssm_association.foo", "max_concurrency", "10%"),
resource.TestCheckResourceAttr(
"aws_ssm_association.foo", "max_errors", "10%"),
),
},
{
Config: testAccAWSSSMAssociationRateControlConfig(name, "20%"),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSSSMAssociationExists("aws_ssm_association.foo"),
resource.TestCheckResourceAttr(
"aws_ssm_association.foo", "max_concurrency", "20%"),
resource.TestCheckResourceAttr(
"aws_ssm_association.foo", "max_errors", "20%"),
),
},
},
})
}

func testAccCheckAWSSSMAssociationExists(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
Expand Down Expand Up @@ -959,3 +990,39 @@ resource "aws_ssm_association" "foo" {
}
`, rName, assocName, compSeverity)
}

func testAccAWSSSMAssociationRateControlConfig(rName, rate string) string {
return fmt.Sprintf(`
resource "aws_ssm_document" "foo_document" {
name = "tf-test-ssm-document-%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" "foo" {
name = "${aws_ssm_document.foo_document.name}"
max_concurrency = "%s"
max_errors = "%s"
targets {
key = "tag:Name"
values = ["acceptanceTest"]
}
}
`, rName, rate, rate)
}
2 changes: 2 additions & 0 deletions website/docs/r/ssm_association.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ The following arguments are supported:
* `schedule_expression` - (Optional) A cron expression when the association will be applied to the target(s).
* `targets` - (Optional) A block containing the targets of the SSM association. Targets are documented below. AWS currently supports a maximum of 5 targets.
* `compliance_severity` - (Optional) The compliance severity for the association. Can be one of the following: `UNSPECIFIED`, `LOW`, `MEDIUM`, `HIGH` or `CRITICAL`
* `max_concurrency` - (Optional) The maximum number of targets allowed to run the association at the same time. You can specify a number, for example 10, or a percentage of the target set, for example 10%.
* `max_errors` - (Optional) The number of errors that are allowed before the system stops sending requests to run the association on additional targets. You can specify a number, for example 10, or a percentage of the target set, for example 10%.

Output Location (`output_location`) is an S3 bucket where you want to store the results of this association:

Expand Down

0 comments on commit 099a05a

Please sign in to comment.