diff --git a/aws/provider.go b/aws/provider.go index 0543109d0f13..7cf44f61983f 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -663,6 +663,7 @@ func Provider() *schema.Provider { "aws_fsx_lustre_file_system": resourceAwsFsxLustreFileSystem(), "aws_fsx_windows_file_system": resourceAwsFsxWindowsFileSystem(), "aws_fms_admin_account": resourceAwsFmsAdminAccount(), + "aws_fms_policy": resourceAwsFmsPolicy(), "aws_gamelift_alias": resourceAwsGameliftAlias(), "aws_gamelift_build": resourceAwsGameliftBuild(), "aws_gamelift_fleet": resourceAwsGameliftFleet(), diff --git a/aws/resource_aws_fms_policy.go b/aws/resource_aws_fms_policy.go new file mode 100644 index 000000000000..fccddfa43b48 --- /dev/null +++ b/aws/resource_aws_fms_policy.go @@ -0,0 +1,347 @@ +package aws + +import ( + "fmt" + "log" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/fms" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func resourceAwsFmsPolicy() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsFmsPolicyCreate, + Read: resourceAwsFmsPolicyRead, + Update: resourceAwsFmsPolicyUpdate, + Delete: resourceAwsFmsPolicyDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + + "delete_all_policy_resources": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + + "exclude_resource_tags": { + Type: schema.TypeBool, + Required: true, + }, + + "exclude_map": { + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + DiffSuppressFunc: suppressMissingOptionalConfigurationBlock, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "orgunit": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + + "include_map": { + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + DiffSuppressFunc: suppressMissingOptionalConfigurationBlock, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "orgunit": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + + "remediation_enabled": { + Type: schema.TypeBool, + Optional: true, + }, + + "resource_type_list": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{"AWS::ApiGateway::Stage", "AWS::ElasticLoadBalancingV2::LoadBalancer", "AWS::CloudFront::Distribution"}, false), + }, + Set: schema.HashString, + }, + + "policy_update_token": { + Type: schema.TypeString, + Computed: true, + }, + + "resource_tags": tagsSchema(), + + "security_service_policy_data": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Required: true, + }, + "managed_service_data": { + Type: schema.TypeString, + Optional: true, + DiffSuppressFunc: suppressEquivalentJsonDiffs, + }, + }, + }, + }, + "arn": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +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: expandStringList(d.Get("resource_type_list").(*schema.Set).List()), + 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{})) + } + + params := &fms.PutPolicyInput{ + Policy: fmsPolicy, + } + + var resp *fms.PutPolicyOutput + var err error + + resp, err = conn.PutPolicy(params) + + if err != nil { + return fmt.Errorf("Creating Policy Failed: %s", err.Error()) + } + + d.SetId(aws.StringValue(resp.Policy.PolicyId)) + + return resourceAwsFmsPolicyRead(d, meta) +} + +func resourceAwsFmsPolicyRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).fmsconn + + var resp *fms.GetPolicyOutput + var req = &fms.GetPolicyInput{ + PolicyId: aws.String(d.Id()), + } + + resp, err := conn.GetPolicy(req) + + if err != nil { + if isAWSErr(err, fms.ErrCodeResourceNotFoundException, "") { + log.Printf("[WARN] FMS Policy (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + return err + } + + 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 { + return err + } + 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 { + return err + } + d.Set("policy_update_token", aws.StringValue(resp.Policy.PolicyUpdateToken)) + 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 { + return err + } + + return nil +} + +func resourceAwsFmsPolicyUpdate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).fmsconn + + 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: expandStringList(d.Get("resource_type_list").(*schema.Set).List()), + ExcludeResourceTags: aws.Bool(d.Get("exclude_resource_tags").(bool)), + } + + fmsPolicy.ExcludeMap = expandFMSPolicyMap(d.Get("exclude_map").([]interface{})) + + fmsPolicy.IncludeMap = expandFMSPolicyMap(d.Get("include_map").([]interface{})) + + fmsPolicy.ResourceTags = constructResourceTags(d.Get("resource_tags")) + + 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)), + } + + params := &fms.PutPolicyInput{Policy: fmsPolicy} + _, err := conn.PutPolicy(params) + + if err != nil { + return fmt.Errorf("Error modifying FMS Policy Rule: %s", err) + } + + return resourceAwsFmsPolicyRead(d, meta) +} + +func resourceAwsFmsPolicyDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).fmsconn + log.Printf("[DEBUG] Delete FMS Policy: %s", d.Id()) + + _, err := conn.DeletePolicy(&fms.DeletePolicyInput{ + PolicyId: aws.String(d.Id()), + DeleteAllPolicyResources: aws.Bool(d.Get("delete_all_policy_resources").(bool)), + }) + + if isAWSErr(err, fms.ErrCodeResourceNotFoundException, "") { + return nil + } + + if err != nil { + return fmt.Errorf("error deleting FMS Policy (%s): %s", d.Id(), err) + } + + return nil +} + +func expandFMSPolicyMap(set []interface{}) map[string][]*string { + fmsPolicyMap := map[string][]*string{} + if len(set) > 0 { + if _, ok := set[0].(map[string]interface{}); !ok { + return fmsPolicyMap + } + for key, listValue := range set[0].(map[string]interface{}) { + var flatKey string + switch key { + case "account": + flatKey = "ACCOUNT" + case "orgunit": + flatKey = "ORG_UNIT" + } + + for _, value := range listValue.(*schema.Set).List() { + fmsPolicyMap[flatKey] = append(fmsPolicyMap[flatKey], aws.String(value.(string))) + } + } + } + return fmsPolicyMap +} + +func flattenFMSPolicyMap(fmsPolicyMap map[string][]*string) []interface{} { + flatPolicyMap := map[string]interface{}{} + + for key, value := range fmsPolicyMap { + switch key { + case "ACCOUNT": + flatPolicyMap["account"] = value + case "ORG_UNIT": + flatPolicyMap["orgunit"] = value + default: + log.Printf("[WARNING] Unexpected key (%q) found in FMS policy", key) + } + } + + return []interface{}{flatPolicyMap} +} + +func flattenFMSResourceTags(resourceTags []*fms.ResourceTag) map[string]interface{} { + resTags := map[string]interface{}{} + + for _, v := range resourceTags { + resTags[*v.Key] = v.Value + } + return resTags +} + +func constructResourceTags(rTags interface{}) []*fms.ResourceTag { + var rTagList []*fms.ResourceTag + + tags := rTags.(map[string]interface{}) + for k, v := range tags { + rTagList = append(rTagList, &fms.ResourceTag{Key: aws.String(k), Value: aws.String(v.(string))}) + } + + return rTagList +} diff --git a/aws/resource_aws_fms_policy_test.go b/aws/resource_aws_fms_policy_test.go new file mode 100644 index 000000000000..802aab689313 --- /dev/null +++ b/aws/resource_aws_fms_policy_test.go @@ -0,0 +1,311 @@ +package aws + +import ( + "fmt" + "regexp" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/fms" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestAccAWSFmsPolicy_basic(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(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)) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsFmsPolicyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccFmsPolicyConfig_include(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_update(t *testing.T) { + fmsPolicyName := fmt.Sprintf("tf-fms-%s", acctest.RandString(5)) + fmsPolicyName2 := fmt.Sprintf("tf-fms-%s2", 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(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"), + ), + }, + { + Config: testAccFmsPolicyConfig_updated(fmsPolicyName2, wafRuleGroupName), + }, + }, + }) +} + +func TestAccAWSFmsPolicy_tags(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_tags(fmsPolicyName, wafRuleGroupName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsFmsPolicyExists("aws_fms_policy.test"), + resource.TestCheckResourceAttr("aws_fms_policy.test", "name", fmsPolicyName), + resource.TestCheckResourceAttr("aws_fms_policy.test", "resource_tags.%", "2"), + resource.TestCheckResourceAttr("aws_fms_policy.test", "resource_tags.Usage", "original"), + ), + }, + { + Config: testAccFmsPolicyConfig_tagsChanged(fmsPolicyName, wafRuleGroupName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsFmsPolicyExists("aws_fms_policy.test"), + resource.TestCheckResourceAttr("aws_fms_policy.test", "name", fmsPolicyName), + resource.TestCheckResourceAttr("aws_fms_policy.test", "resource_tags.%", "1"), + resource.TestCheckResourceAttr("aws_fms_policy.test", "resource_tags.Usage", "changed"), + ), + }, + }, + }) +} + +func testAccCheckAwsFmsPolicyDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).fmsconn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_fms_policy" { + continue + } + + policyID := rs.Primary.Attributes["id"] + + input := &fms.GetPolicyInput{ + PolicyId: aws.String(policyID), + } + + resp, err := conn.GetPolicy(input) + + if isAWSErr(err, fms.ErrCodeResourceNotFoundException, "") { + continue + } + + if err != nil { + return err + } + + if resp.Policy.PolicyId != nil { + return fmt.Errorf("[DESTROY Error] Fms Policy (%s) not deleted", rs.Primary.ID) + } + } + return nil +} + +func testAccCheckAwsFmsPolicyExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + _, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + return nil + } +} + +func testAccFmsPolicyConfig(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_list = ["AWS::ElasticLoadBalancingV2::LoadBalancer"] + + exclude_map { + account = [data.aws_organizations_organization.example.accounts[0].id] + } + + security_service_policy_data { + type = "WAF" + managed_service_data = "{\"type\": \"WAF\", \"ruleGroups\": [{\"id\":\"${aws_wafregional_rule_group.test.id}\", \"overrideAction\" : {\"type\": \"COUNT\"}}],\"defaultAction\": {\"type\": \"BLOCK\"}, \"overrideCustomerWebACLAssociation\": false}" + } +} + +data "aws_organizations_organization" "example" {} + +resource "aws_wafregional_rule_group" "test" { + metric_name = "MyTest" + name = "%[2]s" +} +`, name, group) +} + +func testAccFmsPolicyConfig_updated(name string, group string) string { + return fmt.Sprintf(` +resource "aws_fms_policy" "test" { + exclude_resource_tags = false + name = "%[1]s" + remediation_enabled = true + resource_type_list = ["AWS::ElasticLoadBalancingV2::LoadBalancer"] + + exclude_map { + account = [data.aws_organizations_organization.example.accounts[0].id] + } + + security_service_policy_data { + type = "WAF" + managed_service_data = "{\"type\": \"WAF\", \"ruleGroups\": [{\"id\":\"${aws_wafregional_rule_group.test.id}\", \"overrideAction\" : {\"type\": \"COUNT\"}}],\"defaultAction\": {\"type\": \"ALLOW\"}, \"overrideCustomerWebACLAssociation\": false}" + } + + lifecycle { + create_before_destroy = false + } +} + +data "aws_organizations_organization" "example" {} + +resource "aws_wafregional_rule_group" "test" { + metric_name = "MyTest" + name = "%[2]s" +} + +resource "aws_wafregional_rule_group" "test2" { + metric_name = "MyTest2" + name = "%[2]s" +} +`, name, group) +} + +func testAccFmsPolicyConfig_include(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_list = ["AWS::ElasticLoadBalancingV2::LoadBalancer"] + + include_map { + account = [data.aws_organizations_organization.example.accounts[0].id] + } + + security_service_policy_data { + type = "WAF" + managed_service_data = "{\"type\": \"WAF\", \"ruleGroups\": [{\"id\":\"${aws_wafregional_rule_group.test.id}\", \"overrideAction\" : {\"type\": \"COUNT\"}}],\"defaultAction\": {\"type\": \"BLOCK\"}, \"overrideCustomerWebACLAssociation\": false}" + } +} + +data "aws_organizations_organization" "example" {} + +resource "aws_wafregional_rule_group" "test" { + metric_name = "MyTest" + name = "%[2]s" +} +`, name, group) +} + +func testAccFmsPolicyConfig_tags(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_list = ["AWS::ElasticLoadBalancingV2::LoadBalancer"] + + security_service_policy_data { + type = "WAF" + managed_service_data = "{\"type\": \"WAF\", \"ruleGroups\": [{\"id\":\"${aws_wafregional_rule_group.test.id}\", \"overrideAction\" : {\"type\": \"COUNT\"}}],\"defaultAction\": {\"type\": \"BLOCK\"}, \"overrideCustomerWebACLAssociation\": false}" + } + + resource_tags = { + Environment = "Testing" + Usage = "original" + } + +} + +resource "aws_wafregional_rule_group" "test" { + metric_name = "MyTest" + name = "%[2]s" +} +`, name, group) +} + +func testAccFmsPolicyConfig_tagsChanged(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_list = ["AWS::ElasticLoadBalancingV2::LoadBalancer"] + + security_service_policy_data { + type = "WAF" + managed_service_data = "{\"type\": \"WAF\", \"ruleGroups\": [{\"id\":\"${aws_wafregional_rule_group.test.id}\", \"overrideAction\" : {\"type\": \"COUNT\"}}],\"defaultAction\": {\"type\": \"BLOCK\"}, \"overrideCustomerWebACLAssociation\": false}" + } + + resource_tags = { + Usage = "changed" + } + +} + +resource "aws_wafregional_rule_group" "test" { + metric_name = "MyTest" + name = "%[2]s" +} +`, name, group) +} diff --git a/website/docs/r/fms_policy.html.markdown b/website/docs/r/fms_policy.html.markdown new file mode 100644 index 000000000000..45725f6d25e6 --- /dev/null +++ b/website/docs/r/fms_policy.html.markdown @@ -0,0 +1,103 @@ +--- +subcategory: "Firewall Manager (FMS)" +layout: "aws" +page_title: "AWS: aws_fms_policy" +description: |- + Provides a resource to create an AWS Firewall Manager policy +--- + +# Resource: aws_fms_policy + +Provides a resource to create an AWS Firewall Manager policy. You need to be using AWS organizations and have enabled the Firewall Manager administrator account. + +## Example Usage + +```hcl +resource "aws_fms_policy" "example" { + name = "FMS-Policy-Example" + exclude_resource_tags = false + remediation_enabled = false + resource_type_list = ["AWS::ElasticLoadBalancingV2::LoadBalancer"] + + security_service_policy_data { + type = "WAF" + + managed_service_data = < Additional information about this configuration can be found in the [AWS Firewall Manager SecurityServicePolicyData API Reference](https://docs.aws.amazon.com/fms/2018-01-01/APIReference/API_SecurityServicePolicyData.html) + +* `type` - (Required) Type currently only supports WAF. +* `rule_groups` - (Required) A rule group block, maximum of 2 rule group blocks are currently supported. + * `id` - (Required) Id of the WAF Rule Group that's to be attached. + * `override_action` (Required) Override the action that a group requests CloudFront or AWS WAF takes when a web request matches the conditions in the rule. + * `type` - (Required) valid values are `NONE` or `COUNT`. +* `default_action`- (Required) Configuration block with action that you want AWS Waf to take when a request doesn't match the criteria in any of the rules. + * `type` - (Required) valid values are `BLOCK` or `COUNT`. + +## Attribute Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The AWS account ID of the AWS Firewall Manager administrator account. +* `policy_update_token` - A unique identifier for each update to the policy. + +## Import + +Firewall Manager policies can be imported using the policy ID, e.g. + +``` +$ terraform import aws_fms_policy.example 5be49585-a7e3-4c49-dde1-a179fe4a619a +```