provider/aws: Add support for targets to aws_ssm_association (#14246)
* provider/aws: Add support for targets to aws_ssm_association Fixes: #13975 ``` % make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSSSMAssociation_' ==> Checking that code complies with gofmt requirements... go generate $(go list ./... | grep -v /terraform/vendor/) 2017/05/05 20:32:43 Generated command/internal_plugin_list.go TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSSSMAssociation_ -timeout 120m === RUN TestAccAWSSSMAssociation_basic --- PASS: TestAccAWSSSMAssociation_basic (139.13s) === RUN TestAccAWSSSMAssociation_withTargets --- PASS: TestAccAWSSSMAssociation_withTargets (33.19s) PASS ok github.com/hashicorp/terraform/builtin/providers/aws 172.343s ``` * Update ssm_association.html.markdown
This commit is contained in:
parent
3230217dc5
commit
9dd4e5bcb0
|
@ -17,22 +17,46 @@ func resourceAwsSsmAssociation() *schema.Resource {
|
|||
Delete: resourceAwsSsmAssociationDelete,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"association_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"instance_id": {
|
||||
Type: schema.TypeString,
|
||||
ForceNew: true,
|
||||
Required: true,
|
||||
Optional: true,
|
||||
},
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
ForceNew: true,
|
||||
Required: true,
|
||||
},
|
||||
"parameters": &schema.Schema{
|
||||
"parameters": {
|
||||
Type: schema.TypeMap,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
Computed: true,
|
||||
},
|
||||
"targets": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
Computed: true,
|
||||
MaxItems: 1,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"key": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
"values": {
|
||||
Type: schema.TypeList,
|
||||
Required: true,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -44,13 +68,20 @@ func resourceAwsSsmAssociationCreate(d *schema.ResourceData, meta interface{}) e
|
|||
|
||||
assosciationInput := &ssm.CreateAssociationInput{
|
||||
Name: aws.String(d.Get("name").(string)),
|
||||
InstanceId: aws.String(d.Get("instance_id").(string)),
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("instance_id"); ok {
|
||||
assosciationInput.InstanceId = aws.String(v.(string))
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("parameters"); ok {
|
||||
assosciationInput.Parameters = expandSSMDocumentParameters(v.(map[string]interface{}))
|
||||
}
|
||||
|
||||
if _, ok := d.GetOk("targets"); ok {
|
||||
assosciationInput.Targets = expandAwsSsmTargets(d)
|
||||
}
|
||||
|
||||
resp, err := ssmconn.CreateAssociation(assosciationInput)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("[ERROR] Error creating SSM association: {{err}}", err)
|
||||
|
@ -61,6 +92,7 @@ func resourceAwsSsmAssociationCreate(d *schema.ResourceData, meta interface{}) e
|
|||
}
|
||||
|
||||
d.SetId(*resp.AssociationDescription.Name)
|
||||
d.Set("association_id", resp.AssociationDescription.AssociationId)
|
||||
|
||||
return resourceAwsSsmAssociationRead(d, meta)
|
||||
}
|
||||
|
@ -68,11 +100,10 @@ func resourceAwsSsmAssociationCreate(d *schema.ResourceData, meta interface{}) e
|
|||
func resourceAwsSsmAssociationRead(d *schema.ResourceData, meta interface{}) error {
|
||||
ssmconn := meta.(*AWSClient).ssmconn
|
||||
|
||||
log.Printf("[DEBUG] Reading SSM Assosciation: %s", d.Id())
|
||||
log.Printf("[DEBUG] Reading SSM Association: %s", d.Id())
|
||||
|
||||
params := &ssm.DescribeAssociationInput{
|
||||
Name: aws.String(d.Get("name").(string)),
|
||||
InstanceId: aws.String(d.Get("instance_id").(string)),
|
||||
AssociationId: aws.String(d.Get("association_id").(string)),
|
||||
}
|
||||
|
||||
resp, err := ssmconn.DescribeAssociation(params)
|
||||
|
@ -88,6 +119,11 @@ func resourceAwsSsmAssociationRead(d *schema.ResourceData, meta interface{}) err
|
|||
d.Set("instance_id", association.InstanceId)
|
||||
d.Set("name", association.Name)
|
||||
d.Set("parameters", association.Parameters)
|
||||
d.Set("association_id", association.AssociationId)
|
||||
|
||||
if err := d.Set("targets", flattenAwsSsmTargets(association.Targets)); err != nil {
|
||||
return fmt.Errorf("[DEBUG] Error setting targets error: %#v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -98,8 +134,7 @@ func resourceAwsSsmAssociationDelete(d *schema.ResourceData, meta interface{}) e
|
|||
log.Printf("[DEBUG] Deleting SSM Assosciation: %s", d.Id())
|
||||
|
||||
params := &ssm.DeleteAssociationInput{
|
||||
Name: aws.String(d.Get("name").(string)),
|
||||
InstanceId: aws.String(d.Get("instance_id").(string)),
|
||||
AssociationId: aws.String(d.Get("association_id").(string)),
|
||||
}
|
||||
|
||||
_, err := ssmconn.DeleteAssociation(params)
|
||||
|
|
|
@ -19,7 +19,7 @@ func TestAccAWSSSMAssociation_basic(t *testing.T) {
|
|||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckAWSSSMAssociationDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
{
|
||||
Config: testAccAWSSSMAssociationBasicConfig(name),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckAWSSSMAssociationExists("aws_ssm_association.foo"),
|
||||
|
@ -29,6 +29,23 @@ func TestAccAWSSSMAssociation_basic(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccAWSSSMAssociation_withTargets(t *testing.T) {
|
||||
name := acctest.RandString(10)
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckAWSSSMAssociationDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccAWSSSMAssociationBasicConfigWithTargets(name),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckAWSSSMAssociationExists("aws_ssm_association.foo"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckAWSSSMAssociationExists(n string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
rs, ok := s.RootModule().Resources[n]
|
||||
|
@ -43,12 +60,14 @@ func testAccCheckAWSSSMAssociationExists(n string) resource.TestCheckFunc {
|
|||
conn := testAccProvider.Meta().(*AWSClient).ssmconn
|
||||
|
||||
_, err := conn.DescribeAssociation(&ssm.DescribeAssociationInput{
|
||||
Name: aws.String(rs.Primary.Attributes["name"]),
|
||||
InstanceId: aws.String(rs.Primary.Attributes["instance_id"]),
|
||||
AssociationId: aws.String(rs.Primary.Attributes["association_id"]),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("Could not descripbe the assosciation - %s", err)
|
||||
if wserr, ok := err.(awserr.Error); ok && wserr.Code() == "AssociationDoesNotExist" {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -64,24 +83,57 @@ func testAccCheckAWSSSMAssociationDestroy(s *terraform.State) error {
|
|||
}
|
||||
|
||||
out, err := conn.DescribeAssociation(&ssm.DescribeAssociationInput{
|
||||
Name: aws.String(rs.Primary.Attributes["name"]),
|
||||
InstanceId: aws.String(rs.Primary.Attributes["instance_id"]),
|
||||
AssociationId: aws.String(rs.Primary.Attributes["association_id"]),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
// InvalidDocument means it's gone, this is good
|
||||
if wserr, ok := err.(awserr.Error); ok && wserr.Code() == "InvalidDocument" {
|
||||
if wserr, ok := err.(awserr.Error); ok && wserr.Code() == "AssociationDoesNotExist" {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if out != nil {
|
||||
return fmt.Errorf("Expected AWS SSM Assosciation to be gone, but was still found")
|
||||
return fmt.Errorf("Expected AWS SSM Association to be gone, but was still found")
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("Default error in SSM Assosciation Test")
|
||||
return fmt.Errorf("Default error in SSM Association Test")
|
||||
}
|
||||
|
||||
func testAccAWSSSMAssociationBasicConfigWithTargets(rName string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "aws_ssm_document" "foo_document" {
|
||||
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" "foo" {
|
||||
name = "${aws_ssm_document.foo_document.name}",
|
||||
targets {
|
||||
key = "tag:Name"
|
||||
values = ["acceptanceTest"]
|
||||
}
|
||||
}`, rName)
|
||||
}
|
||||
|
||||
func testAccAWSSSMAssociationBasicConfig(rName string) string {
|
||||
|
|
|
@ -57,42 +57,6 @@ func resourceAwsSsmMaintenanceWindowTarget() *schema.Resource {
|
|||
}
|
||||
}
|
||||
|
||||
func expandAwsSsmMaintenanceWindowTargets(d *schema.ResourceData) []*ssm.Target {
|
||||
var targets []*ssm.Target
|
||||
|
||||
targetConfig := d.Get("targets").([]interface{})
|
||||
|
||||
for _, tConfig := range targetConfig {
|
||||
config := tConfig.(map[string]interface{})
|
||||
|
||||
target := &ssm.Target{
|
||||
Key: aws.String(config["key"].(string)),
|
||||
Values: expandStringList(config["values"].([]interface{})),
|
||||
}
|
||||
|
||||
targets = append(targets, target)
|
||||
}
|
||||
|
||||
return targets
|
||||
}
|
||||
|
||||
func flattenAwsSsmMaintenanceWindowTargets(targets []*ssm.Target) []map[string]interface{} {
|
||||
if len(targets) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
result := make([]map[string]interface{}, 0, len(targets))
|
||||
target := targets[0]
|
||||
|
||||
t := make(map[string]interface{})
|
||||
t["key"] = *target.Key
|
||||
t["values"] = flattenStringList(target.Values)
|
||||
|
||||
result = append(result, t)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func resourceAwsSsmMaintenanceWindowTargetCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
ssmconn := meta.(*AWSClient).ssmconn
|
||||
|
||||
|
@ -101,7 +65,7 @@ func resourceAwsSsmMaintenanceWindowTargetCreate(d *schema.ResourceData, meta in
|
|||
params := &ssm.RegisterTargetWithMaintenanceWindowInput{
|
||||
WindowId: aws.String(d.Get("window_id").(string)),
|
||||
ResourceType: aws.String(d.Get("resource_type").(string)),
|
||||
Targets: expandAwsSsmMaintenanceWindowTargets(d),
|
||||
Targets: expandAwsSsmTargets(d),
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("owner_information"); ok {
|
||||
|
@ -145,7 +109,7 @@ func resourceAwsSsmMaintenanceWindowTargetRead(d *schema.ResourceData, meta inte
|
|||
d.Set("window_id", t.WindowId)
|
||||
d.Set("resource_type", t.ResourceType)
|
||||
|
||||
if err := d.Set("targets", flattenAwsSsmMaintenanceWindowTargets(t.Targets)); err != nil {
|
||||
if err := d.Set("targets", flattenAwsSsmTargets(t.Targets)); err != nil {
|
||||
return fmt.Errorf("[DEBUG] Error setting targets error: %#v", err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -144,7 +144,7 @@ func resourceAwsSsmMaintenanceWindowTaskCreate(d *schema.ResourceData, meta inte
|
|||
TaskType: aws.String(d.Get("task_type").(string)),
|
||||
ServiceRoleArn: aws.String(d.Get("service_role_arn").(string)),
|
||||
TaskArn: aws.String(d.Get("task_arn").(string)),
|
||||
Targets: expandAwsSsmMaintenanceWindowTargets(d),
|
||||
Targets: expandAwsSsmTargets(d),
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("priority"); ok {
|
||||
|
@ -196,7 +196,7 @@ func resourceAwsSsmMaintenanceWindowTaskRead(d *schema.ResourceData, meta interf
|
|||
}
|
||||
}
|
||||
|
||||
if err := d.Set("targets", flattenAwsSsmMaintenanceWindowTargets(t.Targets)); err != nil {
|
||||
if err := d.Set("targets", flattenAwsSsmTargets(t.Targets)); err != nil {
|
||||
return fmt.Errorf("[DEBUG] Error setting targets error: %#v", err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import (
|
|||
"github.com/aws/aws-sdk-go/service/rds"
|
||||
"github.com/aws/aws-sdk-go/service/redshift"
|
||||
"github.com/aws/aws-sdk-go/service/route53"
|
||||
"github.com/aws/aws-sdk-go/service/ssm"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
@ -2085,3 +2086,39 @@ func sliceContainsMap(l []interface{}, m map[string]interface{}) (int, bool) {
|
|||
|
||||
return -1, false
|
||||
}
|
||||
|
||||
func expandAwsSsmTargets(d *schema.ResourceData) []*ssm.Target {
|
||||
var targets []*ssm.Target
|
||||
|
||||
targetConfig := d.Get("targets").([]interface{})
|
||||
|
||||
for _, tConfig := range targetConfig {
|
||||
config := tConfig.(map[string]interface{})
|
||||
|
||||
target := &ssm.Target{
|
||||
Key: aws.String(config["key"].(string)),
|
||||
Values: expandStringList(config["values"].([]interface{})),
|
||||
}
|
||||
|
||||
targets = append(targets, target)
|
||||
}
|
||||
|
||||
return targets
|
||||
}
|
||||
|
||||
func flattenAwsSsmTargets(targets []*ssm.Target) []map[string]interface{} {
|
||||
if len(targets) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
result := make([]map[string]interface{}, 0, len(targets))
|
||||
target := targets[0]
|
||||
|
||||
t := make(map[string]interface{})
|
||||
t["key"] = *target.Key
|
||||
t["values"] = flattenStringList(target.Values)
|
||||
|
||||
result = append(result, t)
|
||||
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ description: |-
|
|||
Assosciates an SSM Document to an instance.
|
||||
---
|
||||
|
||||
# aws\_ssm\_association
|
||||
# aws_ssm_association
|
||||
|
||||
Assosciates an SSM Document to an instance.
|
||||
|
||||
|
@ -68,8 +68,9 @@ resource "aws_ssm_association" "foo" {
|
|||
The following arguments are supported:
|
||||
|
||||
* `name` - (Required) The name of the SSM document to apply.
|
||||
* `instance_id` - (Required) The instance id to apply an SSM document to.
|
||||
* `instance_id` - (Optional) The instance id to apply an SSM document to.
|
||||
* `parameters` - (Optional) Additional parameters to pass to the SSM document.
|
||||
* `targets` - (Optional) 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. Only 1 target is currently supported by AWS.
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
|
|
Loading…
Reference in New Issue