provider/aws: Add support for aws_ssm_patch_baseline (#14954)
* Add support for aws_ssm_patch_baseline and aws_ssm_patch_group * Fix failing test * Cleanup commented out code
This commit is contained in:
parent
d400fe23e0
commit
d3eed78d95
|
@ -430,6 +430,8 @@ func Provider() terraform.ResourceProvider {
|
|||
"aws_ssm_maintenance_window": resourceAwsSsmMaintenanceWindow(),
|
||||
"aws_ssm_maintenance_window_target": resourceAwsSsmMaintenanceWindowTarget(),
|
||||
"aws_ssm_maintenance_window_task": resourceAwsSsmMaintenanceWindowTask(),
|
||||
"aws_ssm_patch_baseline": resourceAwsSsmPatchBaseline(),
|
||||
"aws_ssm_patch_group": resourceAwsSsmPatchGroup(),
|
||||
"aws_spot_datafeed_subscription": resourceAwsSpotDataFeedSubscription(),
|
||||
"aws_spot_instance_request": resourceAwsSpotInstanceRequest(),
|
||||
"aws_spot_fleet_request": resourceAwsSpotFleetRequest(),
|
||||
|
|
|
@ -0,0 +1,277 @@
|
|||
package aws
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/ssm"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
)
|
||||
|
||||
func resourceAwsSsmPatchBaseline() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceAwsSsmPatchBaselineCreate,
|
||||
Read: resourceAwsSsmPatchBaselineRead,
|
||||
Delete: resourceAwsSsmPatchBaselineDelete,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"description": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"global_filter": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
MaxItems: 4,
|
||||
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},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
"approval_rule": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"approve_after_days": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"patch_filter": {
|
||||
Type: schema.TypeList,
|
||||
Required: true,
|
||||
MaxItems: 10,
|
||||
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},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
"approved_patches": {
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
Set: schema.HashString,
|
||||
},
|
||||
|
||||
"rejected_patches": {
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
Set: schema.HashString,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceAwsSsmPatchBaselineCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
ssmconn := meta.(*AWSClient).ssmconn
|
||||
|
||||
params := &ssm.CreatePatchBaselineInput{
|
||||
Name: aws.String(d.Get("name").(string)),
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("description"); ok {
|
||||
params.Description = aws.String(v.(string))
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("approved_patches"); ok && v.(*schema.Set).Len() > 0 {
|
||||
params.ApprovedPatches = expandStringList(v.(*schema.Set).List())
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("rejected_patches"); ok && v.(*schema.Set).Len() > 0 {
|
||||
params.RejectedPatches = expandStringList(v.(*schema.Set).List())
|
||||
}
|
||||
|
||||
if _, ok := d.GetOk("global_filter"); ok {
|
||||
params.GlobalFilters = expandAwsSsmPatchFilterGroup(d)
|
||||
}
|
||||
|
||||
if _, ok := d.GetOk("approval_rule"); ok {
|
||||
params.ApprovalRules = expandAwsSsmPatchRuleGroup(d)
|
||||
}
|
||||
|
||||
resp, err := ssmconn.CreatePatchBaseline(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.SetId(*resp.BaselineId)
|
||||
return resourceAwsSsmPatchBaselineRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceAwsSsmPatchBaselineRead(d *schema.ResourceData, meta interface{}) error {
|
||||
ssmconn := meta.(*AWSClient).ssmconn
|
||||
|
||||
params := &ssm.GetPatchBaselineInput{
|
||||
BaselineId: aws.String(d.Id()),
|
||||
}
|
||||
|
||||
resp, err := ssmconn.GetPatchBaseline(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.Set("name", resp.Name)
|
||||
d.Set("description", resp.Description)
|
||||
d.Set("approved_patches", flattenStringList(resp.ApprovedPatches))
|
||||
d.Set("rejected_patches", flattenStringList(resp.RejectedPatches))
|
||||
|
||||
if err := d.Set("global_filter", flattenAwsSsmPatchFilterGroup(resp.GlobalFilters)); err != nil {
|
||||
return fmt.Errorf("[DEBUG] Error setting global filters error: %#v", err)
|
||||
}
|
||||
|
||||
if err := d.Set("approval_rule", flattenAwsSsmPatchRuleGroup(resp.ApprovalRules)); err != nil {
|
||||
return fmt.Errorf("[DEBUG] Error setting approval rules error: %#v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceAwsSsmPatchBaselineDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
ssmconn := meta.(*AWSClient).ssmconn
|
||||
|
||||
log.Printf("[INFO] Deleting SSM Patch Baseline: %s", d.Id())
|
||||
|
||||
params := &ssm.DeletePatchBaselineInput{
|
||||
BaselineId: aws.String(d.Id()),
|
||||
}
|
||||
|
||||
_, err := ssmconn.DeletePatchBaseline(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func expandAwsSsmPatchFilterGroup(d *schema.ResourceData) *ssm.PatchFilterGroup {
|
||||
var filters []*ssm.PatchFilter
|
||||
|
||||
filterConfig := d.Get("global_filter").([]interface{})
|
||||
|
||||
for _, fConfig := range filterConfig {
|
||||
config := fConfig.(map[string]interface{})
|
||||
|
||||
filter := &ssm.PatchFilter{
|
||||
Key: aws.String(config["key"].(string)),
|
||||
Values: expandStringList(config["values"].([]interface{})),
|
||||
}
|
||||
|
||||
filters = append(filters, filter)
|
||||
}
|
||||
|
||||
return &ssm.PatchFilterGroup{
|
||||
PatchFilters: filters,
|
||||
}
|
||||
}
|
||||
|
||||
func flattenAwsSsmPatchFilterGroup(group *ssm.PatchFilterGroup) []map[string]interface{} {
|
||||
if len(group.PatchFilters) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
result := make([]map[string]interface{}, 0, len(group.PatchFilters))
|
||||
|
||||
for _, filter := range group.PatchFilters {
|
||||
f := make(map[string]interface{})
|
||||
f["key"] = *filter.Key
|
||||
f["values"] = flattenStringList(filter.Values)
|
||||
|
||||
result = append(result, f)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func expandAwsSsmPatchRuleGroup(d *schema.ResourceData) *ssm.PatchRuleGroup {
|
||||
var rules []*ssm.PatchRule
|
||||
|
||||
ruleConfig := d.Get("approval_rule").([]interface{})
|
||||
|
||||
for _, rConfig := range ruleConfig {
|
||||
rCfg := rConfig.(map[string]interface{})
|
||||
|
||||
var filters []*ssm.PatchFilter
|
||||
filterConfig := rCfg["patch_filter"].([]interface{})
|
||||
|
||||
for _, fConfig := range filterConfig {
|
||||
fCfg := fConfig.(map[string]interface{})
|
||||
|
||||
filter := &ssm.PatchFilter{
|
||||
Key: aws.String(fCfg["key"].(string)),
|
||||
Values: expandStringList(fCfg["values"].([]interface{})),
|
||||
}
|
||||
|
||||
filters = append(filters, filter)
|
||||
}
|
||||
|
||||
filterGroup := &ssm.PatchFilterGroup{
|
||||
PatchFilters: filters,
|
||||
}
|
||||
|
||||
rule := &ssm.PatchRule{
|
||||
ApproveAfterDays: aws.Int64(int64(rCfg["approve_after_days"].(int))),
|
||||
PatchFilterGroup: filterGroup,
|
||||
}
|
||||
|
||||
rules = append(rules, rule)
|
||||
}
|
||||
|
||||
return &ssm.PatchRuleGroup{
|
||||
PatchRules: rules,
|
||||
}
|
||||
}
|
||||
|
||||
func flattenAwsSsmPatchRuleGroup(group *ssm.PatchRuleGroup) []map[string]interface{} {
|
||||
if len(group.PatchRules) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
result := make([]map[string]interface{}, 0, len(group.PatchRules))
|
||||
|
||||
for _, rule := range group.PatchRules {
|
||||
r := make(map[string]interface{})
|
||||
r["approve_after_days"] = *rule.ApproveAfterDays
|
||||
r["patch_filter"] = flattenAwsSsmPatchFilterGroup(rule.PatchFilterGroup)
|
||||
result = append(result, r)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
package aws
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/ssm"
|
||||
"github.com/hashicorp/terraform/helper/acctest"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func TestAccAWSSSMPatchBaseline_basic(t *testing.T) {
|
||||
name := acctest.RandString(10)
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckAWSSSMPatchBaselineDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccAWSSSMPatchBaselineBasicConfig(name),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckAWSSSMPatchBaselineExists("aws_ssm_patch_baseline.foo"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_ssm_patch_baseline.foo", "approved_patches.#", "1"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_ssm_patch_baseline.foo", "approved_patches.2062620480", "KB123456"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_ssm_patch_baseline.foo", "name", fmt.Sprintf("patch-baseline-%s", name)),
|
||||
),
|
||||
},
|
||||
{
|
||||
Config: testAccAWSSSMPatchBaselineBasicConfigUpdated(name),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckAWSSSMPatchBaselineExists("aws_ssm_patch_baseline.foo"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_ssm_patch_baseline.foo", "approved_patches.#", "2"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_ssm_patch_baseline.foo", "approved_patches.2062620480", "KB123456"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_ssm_patch_baseline.foo", "approved_patches.2291496788", "KB456789"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_ssm_patch_baseline.foo", "name", fmt.Sprintf("updated-patch-baseline-%s", name)),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckAWSSSMPatchBaselineExists(n string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
rs, ok := s.RootModule().Resources[n]
|
||||
if !ok {
|
||||
return fmt.Errorf("Not found: %s", n)
|
||||
}
|
||||
|
||||
if rs.Primary.ID == "" {
|
||||
return fmt.Errorf("No SSM Patch Baseline ID is set")
|
||||
}
|
||||
|
||||
conn := testAccProvider.Meta().(*AWSClient).ssmconn
|
||||
|
||||
resp, err := conn.DescribePatchBaselines(&ssm.DescribePatchBaselinesInput{
|
||||
Filters: []*ssm.PatchOrchestratorFilter{
|
||||
{
|
||||
Key: aws.String("NAME_PREFIX"),
|
||||
Values: []*string{aws.String(rs.Primary.Attributes["name"])},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
for _, i := range resp.BaselineIdentities {
|
||||
if *i.BaselineId == rs.Primary.ID {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return fmt.Errorf("No AWS SSM Patch Baseline found")
|
||||
}
|
||||
}
|
||||
|
||||
func testAccCheckAWSSSMPatchBaselineDestroy(s *terraform.State) error {
|
||||
conn := testAccProvider.Meta().(*AWSClient).ssmconn
|
||||
|
||||
for _, rs := range s.RootModule().Resources {
|
||||
if rs.Type != "aws_ssm_patch_baseline" {
|
||||
continue
|
||||
}
|
||||
|
||||
out, err := conn.DescribePatchBaselines(&ssm.DescribePatchBaselinesInput{
|
||||
Filters: []*ssm.PatchOrchestratorFilter{
|
||||
{
|
||||
Key: aws.String("NAME_PREFIX"),
|
||||
Values: []*string{aws.String(rs.Primary.Attributes["name"])},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(out.BaselineIdentities) > 0 {
|
||||
return fmt.Errorf("Expected AWS SSM Patch Baseline to be gone, but was still found")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func testAccAWSSSMPatchBaselineBasicConfig(rName string) string {
|
||||
return fmt.Sprintf(`
|
||||
|
||||
resource "aws_ssm_patch_baseline" "foo" {
|
||||
name = "patch-baseline-%s"
|
||||
approved_patches = ["KB123456"]
|
||||
}
|
||||
|
||||
`, rName)
|
||||
}
|
||||
|
||||
func testAccAWSSSMPatchBaselineBasicConfigUpdated(rName string) string {
|
||||
return fmt.Sprintf(`
|
||||
|
||||
resource "aws_ssm_patch_baseline" "foo" {
|
||||
name = "updated-patch-baseline-%s"
|
||||
approved_patches = ["KB123456","KB456789"]
|
||||
}
|
||||
|
||||
`, rName)
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
package aws
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/ssm"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
)
|
||||
|
||||
func resourceAwsSsmPatchGroup() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceAwsSsmPatchGroupCreate,
|
||||
Read: resourceAwsSsmPatchGroupRead,
|
||||
Delete: resourceAwsSsmPatchGroupDelete,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"baseline_id": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
"patch_group": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceAwsSsmPatchGroupCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
ssmconn := meta.(*AWSClient).ssmconn
|
||||
|
||||
params := &ssm.RegisterPatchBaselineForPatchGroupInput{
|
||||
BaselineId: aws.String(d.Get("baseline_id").(string)),
|
||||
PatchGroup: aws.String(d.Get("patch_group").(string)),
|
||||
}
|
||||
|
||||
resp, err := ssmconn.RegisterPatchBaselineForPatchGroup(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.SetId(*resp.PatchGroup)
|
||||
return resourceAwsSsmPatchGroupRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceAwsSsmPatchGroupRead(d *schema.ResourceData, meta interface{}) error {
|
||||
ssmconn := meta.(*AWSClient).ssmconn
|
||||
|
||||
params := &ssm.DescribePatchGroupsInput{}
|
||||
|
||||
resp, err := ssmconn.DescribePatchGroups(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
found := false
|
||||
for _, t := range resp.Mappings {
|
||||
if *t.PatchGroup == d.Id() {
|
||||
found = true
|
||||
|
||||
d.Set("patch_group", t.PatchGroup)
|
||||
d.Set("baseline_id", t.BaselineIdentity.BaselineId)
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
log.Printf("[INFO] Patch Group not found. Removing from state")
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func resourceAwsSsmPatchGroupDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
ssmconn := meta.(*AWSClient).ssmconn
|
||||
|
||||
log.Printf("[INFO] Deleting SSM Patch Group: %s", d.Id())
|
||||
|
||||
params := &ssm.DeregisterPatchBaselineForPatchGroupInput{
|
||||
BaselineId: aws.String(d.Get("baseline_id").(string)),
|
||||
PatchGroup: aws.String(d.Get("patch_group").(string)),
|
||||
}
|
||||
|
||||
_, err := ssmconn.DeregisterPatchBaselineForPatchGroup(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
package aws
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/service/ssm"
|
||||
"github.com/hashicorp/terraform/helper/acctest"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func TestAccAWSSSMPatchGroup_basic(t *testing.T) {
|
||||
name := acctest.RandString(10)
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckAWSSSMPatchGroupDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccAWSSSMPatchGroupBasicConfig(name),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckAWSSSMPatchGroupExists("aws_ssm_patch_group.patchgroup"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckAWSSSMPatchGroupExists(n string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
rs, ok := s.RootModule().Resources[n]
|
||||
if !ok {
|
||||
return fmt.Errorf("Not found: %s", n)
|
||||
}
|
||||
|
||||
if rs.Primary.ID == "" {
|
||||
return fmt.Errorf("No SSM Patch Baseline ID is set")
|
||||
}
|
||||
|
||||
conn := testAccProvider.Meta().(*AWSClient).ssmconn
|
||||
|
||||
resp, err := conn.DescribePatchGroups(&ssm.DescribePatchGroupsInput{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, i := range resp.Mappings {
|
||||
if *i.BaselineIdentity.BaselineId == rs.Primary.Attributes["baseline_id"] && *i.PatchGroup == rs.Primary.ID {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("No AWS SSM Patch Group found")
|
||||
}
|
||||
}
|
||||
|
||||
func testAccCheckAWSSSMPatchGroupDestroy(s *terraform.State) error {
|
||||
conn := testAccProvider.Meta().(*AWSClient).ssmconn
|
||||
|
||||
for _, rs := range s.RootModule().Resources {
|
||||
if rs.Type != "aws_ssm_patch_group" {
|
||||
continue
|
||||
}
|
||||
|
||||
resp, err := conn.DescribePatchGroups(&ssm.DescribePatchGroupsInput{})
|
||||
|
||||
if err != nil {
|
||||
// Verify the error is what we want
|
||||
if ae, ok := err.(awserr.Error); ok && ae.Code() == "DoesNotExistException" {
|
||||
continue
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
for _, i := range resp.Mappings {
|
||||
if *i.BaselineIdentity.BaselineId == rs.Primary.Attributes["baseline_id"] && *i.PatchGroup == rs.Primary.ID {
|
||||
return fmt.Errorf("Expected AWS SSM Patch Group to be gone, but was still found")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func testAccAWSSSMPatchGroupBasicConfig(rName string) string {
|
||||
return fmt.Sprintf(`
|
||||
|
||||
resource "aws_ssm_patch_baseline" "foo" {
|
||||
name = "patch-baseline-%s"
|
||||
approved_patches = ["KB123456"]
|
||||
}
|
||||
|
||||
resource "aws_ssm_patch_group" "patchgroup" {
|
||||
baseline_id = "${aws_ssm_patch_baseline.foo.id}"
|
||||
patch_group = "patch-group"
|
||||
}
|
||||
|
||||
`, rName)
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
---
|
||||
layout: "aws"
|
||||
page_title: "AWS: aws_ssm_patch_baseline"
|
||||
sidebar_current: "docs-aws-resource-ssm-patch-baseline"
|
||||
description: |-
|
||||
Provides an SSM Patch Baseline resource
|
||||
---
|
||||
|
||||
# aws_ssm_patch_baseline
|
||||
|
||||
Provides an SSM Patch Baseline resource
|
||||
|
||||
~> **NOTE on Patch Baselines:** The `approved_patches` and `approval_rule` are
|
||||
both marked as optional fields, but the Patch Baseline requires that at least one
|
||||
of them is specified.
|
||||
|
||||
## Example Usage
|
||||
|
||||
Basic usage using `approved_patches` only
|
||||
|
||||
```hcl
|
||||
resource "aws_ssm_patch_baseline" "production" {
|
||||
name = "patch-baseline"
|
||||
approved_patches = ["KB123456"]
|
||||
}
|
||||
```
|
||||
|
||||
Advanced usage, specifying patch filters
|
||||
|
||||
```hcl
|
||||
resource "aws_ssm_patch_baseline" "production" {
|
||||
name = "patch-baseline"
|
||||
description = "Patch Baseline Description"
|
||||
approved_patches = ["KB123456", "KB456789"]
|
||||
rejected_patches = ["KB987654"]
|
||||
global_filter {
|
||||
key = "PRODUCT"
|
||||
values = ["WindowsServer2008"]
|
||||
}
|
||||
global_filter {
|
||||
key = "CLASSIFICATION"
|
||||
values = ["ServicePacks"]
|
||||
}
|
||||
global_filter {
|
||||
key = "MSRC_SEVERITY"
|
||||
values = ["Low"]
|
||||
}
|
||||
approval_rule {
|
||||
approve_after_days = 7
|
||||
patch_filter {
|
||||
key = "PRODUCT"
|
||||
values = ["WindowsServer2016"]
|
||||
}
|
||||
patch_filter {
|
||||
key = "CLASSIFICATION"
|
||||
values = ["CriticalUpdates", "SecurityUpdates", "Updates"]
|
||||
}
|
||||
patch_filter {
|
||||
key = "MSRC_SEVERITY"
|
||||
values = ["Critical", "Important", "Moderate"]
|
||||
}
|
||||
}
|
||||
approval_rule {
|
||||
approve_after_days = 7
|
||||
patch_filter {
|
||||
key = "PRODUCT"
|
||||
values = ["WindowsServer2012"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `name` - (Required) The name of the patch baseline.
|
||||
* `description` - (Optional) The description of the patch baseline.
|
||||
* `approved_patches` - (Optional) A list of explicitly approved patches for the baseline.
|
||||
* `rejected_patches` - (Optional) A list of rejected patches.
|
||||
* `global_filter` - (Optional) A set of global filters used to exclude patches from the baseline. Up to 4 global filters can be specified using Key/Value pairs. Valid Keys are `PRODUCT | CLASSIFICATION | MSRC_SEVERITY | PATCH_ID`.
|
||||
* `approval_rule` - (Optional) A set of rules used to include patches in the baseline. up to 10 approval rules can be specified. Each approval_rule block requires the fields documented below.
|
||||
|
||||
The `approval_rule` block supports:
|
||||
|
||||
* `approve_after_days` - (Required) The number of days after the release date of each patch matched by the rule the patch is marked as approved in the patch baseline. Valid Range: 0 to 100.
|
||||
* `patch_filter` - (Required) The patch filter group that defines the criteria for the rule. Up to 4 patch filters can be specified per approval rule using Key/Value pairs. Valid Keys are `PRODUCT | CLASSIFICATION | MSRC_SEVERITY | PATCH_ID`.
|
||||
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
The following attributes are exported:
|
||||
|
||||
* `id` - The ID of the patch baseline.
|
|
@ -0,0 +1,37 @@
|
|||
---
|
||||
layout: "aws"
|
||||
page_title: "AWS: aws_ssm_patch_group"
|
||||
sidebar_current: "docs-aws-resource-ssm-patch-group"
|
||||
description: |-
|
||||
Provides an SSM Patch Group resource
|
||||
---
|
||||
|
||||
# aws_ssm_patch_group
|
||||
|
||||
Provides an SSM Patch Group resource
|
||||
|
||||
## Example Usage
|
||||
|
||||
```hcl
|
||||
resource "aws_ssm_patch_baseline" "production" {
|
||||
name = "patch-baseline"
|
||||
approved_patches = ["KB123456"]
|
||||
}
|
||||
|
||||
resource "aws_ssm_patch_group" "patchgroup" {
|
||||
baseline_id = "${aws_ssm_patch_baseline.production.id}"
|
||||
patch_group = "patch-group-name"
|
||||
}```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `baseline_id` - (Required) The ID of the patch baseline to register the patch group with.
|
||||
* `patch_group` - (Required) The name of the patch group that should be registered with the patch baseline.
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
The following attributes are exported:
|
||||
|
||||
* `id` - The ID of the patch baseline.
|
Loading…
Reference in New Issue