Skip to content

Commit

Permalink
Allow use of resource_type and resource_type_list
Browse files Browse the repository at this point in the history
  • Loading branch information
bill-rich committed Feb 3, 2021
1 parent ddd0d84 commit 50cb80a
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 38 deletions.
76 changes: 39 additions & 37 deletions aws/resource_aws_fms_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,20 @@ func resourceAwsFmsPolicy() *schema.Resource {
},

"resource_type_list": {
Type: schema.TypeSet,
Required: true,
Type: schema.TypeSet,
Optional: true,
Set: schema.HashString,
ConflictsWith: []string{"resource_type"},
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: validation.StringInSlice([]string{"AWS::ApiGateway::Stage", "AWS::ElasticLoadBalancingV2::LoadBalancer", "AWS::CloudFront::Distribution", "AWS::EC2::NetworkInterface", "AWS::EC2::Instance", "AWS::EC2::SecurityGroup"}, false),
},
Set: schema.HashString,
},

"resource_type": {
Type: schema.TypeString,
Optional: true,
ConflictsWith: []string{"resource_type_list"},
},

"policy_update_token": {
Expand Down Expand Up @@ -138,31 +145,7 @@ func resourceAwsFmsPolicy() *schema.Resource {
func resourceAwsFmsPolicyCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).fmsconn

fmsPolicy := &fms.Policy{
PolicyName: aws.String(d.Get("name").(string)),
RemediationEnabled: aws.Bool(d.Get("remediation_enabled").(bool)),
ResourceType: aws.String("ResourceTypeList"),
ResourceTypeList: expandStringSet(d.Get("resource_type_list").(*schema.Set)),
ExcludeResourceTags: aws.Bool(d.Get("exclude_resource_tags").(bool)),
}

securityServicePolicy := d.Get("security_service_policy_data").([]interface{})[0].(map[string]interface{})
fmsPolicy.SecurityServicePolicyData = &fms.SecurityServicePolicyData{
ManagedServiceData: aws.String(securityServicePolicy["managed_service_data"].(string)),
Type: aws.String(securityServicePolicy["type"].(string)),
}

if rTags, tagsOk := d.GetOk("resource_tags"); tagsOk {
fmsPolicy.ResourceTags = constructResourceTags(rTags)
}

if v, ok := d.GetOk("include_map"); ok {
fmsPolicy.IncludeMap = expandFMSPolicyMap(v.([]interface{}))
}

if v, ok := d.GetOk("exclude_map"); ok {
fmsPolicy.ExcludeMap = expandFMSPolicyMap(v.([]interface{}))
}
fmsPolicy := resourceAwsFmsPolicyExpandPolicy(d)

params := &fms.PutPolicyInput{
Policy: fmsPolicy,
Expand Down Expand Up @@ -201,46 +184,57 @@ func resourceAwsFmsPolicyRead(d *schema.ResourceData, meta interface{}) error {
return err
}

return resourceAwsFmsPolicyFlattenPolicy(d, resp)
}

func resourceAwsFmsPolicyFlattenPolicy(d *schema.ResourceData, resp *fms.GetPolicyOutput) error {
d.Set("arn", aws.StringValue(resp.PolicyArn))

d.Set("name", aws.StringValue(resp.Policy.PolicyName))
d.Set("exclude_resource_tags", aws.BoolValue(resp.Policy.ExcludeResourceTags))
if err = d.Set("exclude_map", flattenFMSPolicyMap(resp.Policy.ExcludeMap)); err != nil {
if err := d.Set("exclude_map", flattenFMSPolicyMap(resp.Policy.ExcludeMap)); err != nil {
return err
}
if err = d.Set("include_map", flattenFMSPolicyMap(resp.Policy.IncludeMap)); err != nil {
if err := d.Set("include_map", flattenFMSPolicyMap(resp.Policy.IncludeMap)); err != nil {
return err
}
d.Set("remediation_enabled", aws.BoolValue(resp.Policy.RemediationEnabled))
if err = d.Set("resource_type_list", resp.Policy.ResourceTypeList); err != nil {
if err := d.Set("resource_type_list", resp.Policy.ResourceTypeList); err != nil {
return err
}
if aws.StringValue(resp.Policy.ResourceType) != "ResourceTypeList" {
d.Set("resource_type", aws.StringValue(resp.Policy.ResourceType))
}
d.Set("policy_update_token", aws.StringValue(resp.Policy.PolicyUpdateToken))
if err = d.Set("resource_tags", flattenFMSResourceTags(resp.Policy.ResourceTags)); err != nil {
if err := d.Set("resource_tags", flattenFMSResourceTags(resp.Policy.ResourceTags)); err != nil {
return err
}

securityServicePolicy := []map[string]string{{
"type": *resp.Policy.SecurityServicePolicyData.Type,
"managed_service_data": *resp.Policy.SecurityServicePolicyData.ManagedServiceData,
}}
if err = d.Set("security_service_policy_data", securityServicePolicy); err != nil {
if err := d.Set("security_service_policy_data", securityServicePolicy); err != nil {
return err
}

return nil
}

func resourceAwsFmsPolicyUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).fmsconn
func resourceAwsFmsPolicyExpandPolicy(d *schema.ResourceData) *fms.Policy {
resourceType := aws.String("ResourceTypeList")
resourceTypeList := expandStringSet(d.Get("resource_type_list").(*schema.Set))
if t, ok := d.GetOk("resource_type"); ok {
resourceType = aws.String(t.(string))
}

fmsPolicy := &fms.Policy{
PolicyName: aws.String(d.Get("name").(string)),
PolicyId: aws.String(d.Id()),
PolicyUpdateToken: aws.String(d.Get("policy_update_token").(string)),
RemediationEnabled: aws.Bool(d.Get("remediation_enabled").(bool)),
ResourceType: aws.String("ResourceTypeList"),
ResourceTypeList: expandStringSet(d.Get("resource_type_list").(*schema.Set)),
ResourceType: resourceType,
ResourceTypeList: resourceTypeList,
ExcludeResourceTags: aws.Bool(d.Get("exclude_resource_tags").(bool)),
}

Expand All @@ -256,6 +250,14 @@ func resourceAwsFmsPolicyUpdate(d *schema.ResourceData, meta interface{}) error
Type: aws.String(securityServicePolicy["type"].(string)),
}

return fmsPolicy
}

func resourceAwsFmsPolicyUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).fmsconn

fmsPolicy := resourceAwsFmsPolicyExpandPolicy(d)

params := &fms.PutPolicyInput{Policy: fmsPolicy}
_, err := conn.PutPolicy(params)

Expand Down
50 changes: 50 additions & 0 deletions aws/resource_aws_fms_policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,34 @@ func TestAccAWSFmsPolicy_basic(t *testing.T) {
})
}

func TestAccAWSFmsPolicy_cloudfrontDistribution(t *testing.T) {
fmsPolicyName := fmt.Sprintf("tf-fms-%s", acctest.RandString(5))
wafRuleGroupName := fmt.Sprintf("tf-waf-rg-%s", acctest.RandString(5))

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAwsFmsPolicyDestroy,
Steps: []resource.TestStep{
{
Config: testAccFmsPolicyConfig_cloudfrontDistribution(fmsPolicyName, wafRuleGroupName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsFmsPolicyExists("aws_fms_policy.test"),
testAccMatchResourceAttrRegionalARN("aws_fms_policy.test", "arn", "fms", regexp.MustCompile(`policy/`)),
resource.TestCheckResourceAttr("aws_fms_policy.test", "name", fmsPolicyName),
resource.TestCheckResourceAttr("aws_fms_policy.test", "security_service_policy_data.#", "1"),
),
},
{
ResourceName: "aws_fms_policy.test",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"policy_update_token", "delete_all_policy_resources"},
},
},
})
}

func TestAccAWSFmsPolicy_includeMap(t *testing.T) {
fmsPolicyName := fmt.Sprintf("tf-fms-%s", acctest.RandString(5))
wafRuleGroupName := fmt.Sprintf("tf-waf-rg-%s", acctest.RandString(5))
Expand Down Expand Up @@ -187,6 +215,28 @@ resource "aws_fms_policy" "test" {
data "aws_organizations_organization" "example" {}
resource "aws_wafregional_rule_group" "test" {
metric_name = "MyTest"
name = "%[2]s"
}
`, name, group)
}

func testAccFmsPolicyConfig_cloudfrontDistribution(name string, group string) string {
return fmt.Sprintf(`
resource "aws_fms_policy" "test" {
exclude_resource_tags = false
name = "%[1]s"
remediation_enabled = false
resource_type = "AWS::CloudFront::Distribution"
security_service_policy_data {
type = "WAFV2"
managed_service_data = "{\"type\": \"WAF\", \"ruleGroups\": [{\"id\":\"${aws_wafregional_rule_group.test.id}\", \"overrideAction\" : {\"type\": \"COUNT\"}}],\"defaultAction\": {\"type\": \"BLOCK\"}, \"overrideCustomerWebACLAssociation\": false}"
}
}
resource "aws_wafregional_rule_group" "test" {
metric_name = "MyTest"
name = "%[2]s"
Expand Down
3 changes: 2 additions & 1 deletion website/docs/r/fms_policy.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ The following arguments are supported:
* `include_map` - (Optional) A map of lists, with a single key named 'account' with a list of AWS Account IDs to include for this policy.
* `remediation_enabled` - (Required) A boolean value, indicates if the policy should automatically applied to resources that already exist in the account.
* `resource_tags` - (Optional) A map of resource tags, that if present will filter protections on resources based on the exclude_resource_tags.
* `resource_type_list` - (Required, Forces new resource) A list of resource types to protect, valid values are: `AWS::ElasticLoadBalancingV2::LoadBalancer`, `AWS::ApiGateway::Stage`, `AWS::CloudFront::Distribution`.
* `resource_type` - (Optional) A resource type to protect, valid values are: `AWS::ElasticLoadBalancingV2::LoadBalancer`, `AWS::ApiGateway::Stage`, `AWS::CloudFront::Distribution`. Conflicts with `resource_type_list`.
* `resource_type_list` - (Optional) A list of resource types to protect, valid values are: `AWS::ElasticLoadBalancingV2::LoadBalancer`, `AWS::ApiGateway::Stage`, `AWS::CloudFront::Distribution`. Conflicts with `resource_type`.
* `security_service_policy_data` - (Required) The objects to include in Security Service Policy Data. Documented below.

## `exclude_map` Configuration Block
Expand Down

0 comments on commit 50cb80a

Please sign in to comment.