From 1b5a0b36d5c3a756e2efe45a3eff2bda67135997 Mon Sep 17 00:00:00 2001 From: Sune Keller Date: Sun, 26 Apr 2020 04:59:54 +0200 Subject: [PATCH] azurerm_web_application_firewall_policy - support managed_rules (#6126) --- .../web_application_firewall_policy.go | 40 +++ .../resource_arm_application_gateway.go | 61 ++-- ...rce_arm_web_application_firewall_policy.go | 275 +++++++++++++++++- ...rm_web_application_firewall_policy_test.go | 82 ++++++ ..._application_firewall_policy.html.markdown | 95 +++++- 5 files changed, 495 insertions(+), 58 deletions(-) create mode 100644 azurerm/helpers/validate/web_application_firewall_policy.go diff --git a/azurerm/helpers/validate/web_application_firewall_policy.go b/azurerm/helpers/validate/web_application_firewall_policy.go new file mode 100644 index 000000000000..da86db47f952 --- /dev/null +++ b/azurerm/helpers/validate/web_application_firewall_policy.go @@ -0,0 +1,40 @@ +package validate + +import "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + +var ValidateWebApplicationFirewallPolicyRuleGroupName = validation.StringInSlice([]string{ + "crs_20_protocol_violations", + "crs_21_protocol_anomalies", + "crs_23_request_limits", + "crs_30_http_policy", + "crs_35_bad_robots", + "crs_40_generic_attacks", + "crs_41_sql_injection_attacks", + "crs_41_xss_attacks", + "crs_42_tight_security", + "crs_45_trojans", + "General", + "REQUEST-911-METHOD-ENFORCEMENT", + "REQUEST-913-SCANNER-DETECTION", + "REQUEST-920-PROTOCOL-ENFORCEMENT", + "REQUEST-921-PROTOCOL-ATTACK", + "REQUEST-930-APPLICATION-ATTACK-LFI", + "REQUEST-931-APPLICATION-ATTACK-RFI", + "REQUEST-932-APPLICATION-ATTACK-RCE", + "REQUEST-933-APPLICATION-ATTACK-PHP", + "REQUEST-941-APPLICATION-ATTACK-XSS", + "REQUEST-942-APPLICATION-ATTACK-SQLI", + "REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION", +}, false) + +var ValidateWebApplicationFirewallPolicyRuleSetVersion = validation.StringInSlice([]string{ + "1.0", + "2.2.9", + "3.0", + "3.1", +}, false) + +var ValidateWebApplicationFirewallPolicyRuleSetType = validation.StringInSlice([]string{ + "OWASP", + "Microsoft_BotManagerRuleSet", +}, false) diff --git a/azurerm/internal/services/network/resource_arm_application_gateway.go b/azurerm/internal/services/network/resource_arm_application_gateway.go index 8fcdd30c995b..9e22c7bd6ba4 100644 --- a/azurerm/internal/services/network/resource_arm_application_gateway.go +++ b/azurerm/internal/services/network/resource_arm_application_gateway.go @@ -1170,19 +1170,16 @@ func resourceArmApplicationGateway() *schema.Resource { }, "rule_set_type": { - Type: schema.TypeString, - Optional: true, - Default: "OWASP", + Type: schema.TypeString, + Optional: true, + Default: "OWASP", + ValidateFunc: validate.ValidateWebApplicationFirewallPolicyRuleSetType, }, "rule_set_version": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringInSlice([]string{ - "2.2.9", - "3.0", - "3.1", - }, false), + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.ValidateWebApplicationFirewallPolicyRuleSetVersion, }, "file_upload_limit_mb": { Type: schema.TypeInt, @@ -1207,32 +1204,9 @@ func resourceArmApplicationGateway() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "rule_group_name": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringInSlice([]string{ - "crs_20_protocol_violations", - "crs_21_protocol_anomalies", - "crs_23_request_limits", - "crs_30_http_policy", - "crs_35_bad_robots", - "crs_40_generic_attacks", - "crs_41_sql_injection_attacks", - "crs_41_xss_attacks", - "crs_42_tight_security", - "crs_45_trojans", - "General", - "REQUEST-911-METHOD-ENFORCEMENT", - "REQUEST-913-SCANNER-DETECTION", - "REQUEST-920-PROTOCOL-ENFORCEMENT", - "REQUEST-921-PROTOCOL-ATTACK", - "REQUEST-930-APPLICATION-ATTACK-LFI", - "REQUEST-931-APPLICATION-ATTACK-RFI", - "REQUEST-932-APPLICATION-ATTACK-RCE", - "REQUEST-933-APPLICATION-ATTACK-PHP", - "REQUEST-941-APPLICATION-ATTACK-XSS", - "REQUEST-942-APPLICATION-ATTACK-SQLI", - "REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION", - }, false), + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.ValidateWebApplicationFirewallPolicyRuleGroupName, }, "rules": { @@ -1255,19 +1229,20 @@ func resourceArmApplicationGateway() *schema.Resource { Type: schema.TypeString, Required: true, ValidateFunc: validation.StringInSlice([]string{ - "RequestHeaderNames", - "RequestArgNames", - "RequestCookieNames", + string(network.RequestArgNames), + string(network.RequestCookieNames), + string(network.RequestHeaderNames), }, false), }, "selector_match_operator": { Type: schema.TypeString, ValidateFunc: validation.StringInSlice([]string{ - "Equals", - "StartsWith", - "EndsWith", - "Contains", + string(network.OwaspCrsExclusionEntrySelectorMatchOperatorContains), + string(network.OwaspCrsExclusionEntrySelectorMatchOperatorEndsWith), + string(network.OwaspCrsExclusionEntrySelectorMatchOperatorEquals), + string(network.OwaspCrsExclusionEntrySelectorMatchOperatorEqualsAny), + string(network.OwaspCrsExclusionEntrySelectorMatchOperatorStartsWith), }, false), Optional: true, }, diff --git a/azurerm/internal/services/network/resource_arm_web_application_firewall_policy.go b/azurerm/internal/services/network/resource_arm_web_application_firewall_policy.go index 0e11f794324d..a3955c94e88f 100644 --- a/azurerm/internal/services/network/resource_arm_web_application_firewall_policy.go +++ b/azurerm/internal/services/network/resource_arm_web_application_firewall_policy.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" @@ -143,6 +144,88 @@ func resourceArmWebApplicationFirewallPolicy() *schema.Resource { }, }, + "managed_rules": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "exclusion": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "match_variable": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(network.RequestArgNames), + string(network.RequestCookieNames), + string(network.RequestHeaderNames), + }, false), + }, + "selector": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + "selector_match_operator": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(network.OwaspCrsExclusionEntrySelectorMatchOperatorContains), + string(network.OwaspCrsExclusionEntrySelectorMatchOperatorEndsWith), + string(network.OwaspCrsExclusionEntrySelectorMatchOperatorEquals), + string(network.OwaspCrsExclusionEntrySelectorMatchOperatorEqualsAny), + string(network.OwaspCrsExclusionEntrySelectorMatchOperatorStartsWith), + }, false), + }, + }, + }, + }, + "managed_rule_set": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Optional: true, + Default: "OWASP", + ValidateFunc: validate.ValidateWebApplicationFirewallPolicyRuleSetType, + }, + "version": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.ValidateWebApplicationFirewallPolicyRuleSetVersion, + }, + "rule_group_override": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "rule_group_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.ValidateWebApplicationFirewallPolicyRuleGroupName, + }, + "disabled_rules": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "policy_settings": { Type: schema.TypeList, Optional: true, @@ -195,6 +278,7 @@ func resourceArmWebApplicationFirewallPolicyCreateUpdate(d *schema.ResourceData, location := azure.NormalizeLocation(d.Get("location").(string)) customRules := d.Get("custom_rules").([]interface{}) policySettings := d.Get("policy_settings").([]interface{}) + managedRules := d.Get("managed_rules").([]interface{}) t := d.Get("tags").(map[string]interface{}) parameters := network.WebApplicationFirewallPolicy{ @@ -202,6 +286,7 @@ func resourceArmWebApplicationFirewallPolicyCreateUpdate(d *schema.ResourceData, WebApplicationFirewallPolicyPropertiesFormat: &network.WebApplicationFirewallPolicyPropertiesFormat{ CustomRules: expandArmWebApplicationFirewallPolicyWebApplicationFirewallCustomRule(customRules), PolicySettings: expandArmWebApplicationFirewallPolicyPolicySettings(policySettings), + ManagedRules: expandArmWebApplicationFirewallPolicyManagedRulesDefinition(managedRules), }, Tags: tags.Expand(t), } @@ -256,6 +341,12 @@ func resourceArmWebApplicationFirewallPolicyRead(d *schema.ResourceData, meta in if err := d.Set("policy_settings", flattenArmWebApplicationFirewallPolicyPolicySettings(webApplicationFirewallPolicyPropertiesFormat.PolicySettings)); err != nil { return fmt.Errorf("Error setting `policy_settings`: %+v", err) } + if err := d.Set("managed_rules", flattenArmWebApplicationFirewallPolicyManagedRulesDefinition(webApplicationFirewallPolicyPropertiesFormat.ManagedRules)); err != nil { + return fmt.Errorf("Error setting `managed_rules`: %+v", err) + } + if err := d.Set("managed_rules", flattenArmWebApplicationFirewallPolicyManagedRulesDefinition(webApplicationFirewallPolicyPropertiesFormat.ManagedRules)); err != nil { + return fmt.Errorf("Error setting `managed_rules`: %+v", err) + } } return tags.FlattenAndSet(d, resp.Tags) @@ -320,7 +411,7 @@ func expandArmWebApplicationFirewallPolicyPolicySettings(input []interface{}) *n v := input[0].(map[string]interface{}) enabled := network.WebApplicationFirewallEnabledStateDisabled - if v["enabled"].(bool) { + if value, ok := v["enabled"].(bool); ok && value { enabled = network.WebApplicationFirewallEnabledStateEnabled } mode := v["mode"].(string) @@ -332,6 +423,96 @@ func expandArmWebApplicationFirewallPolicyPolicySettings(input []interface{}) *n return &result } +func expandArmWebApplicationFirewallPolicyManagedRulesDefinition(input []interface{}) *network.ManagedRulesDefinition { + if len(input) == 0 { + return nil + } + v := input[0].(map[string]interface{}) + + exclusions := v["exclusion"].([]interface{}) + managedRuleSets := v["managed_rule_set"].([]interface{}) + + return &network.ManagedRulesDefinition{ + Exclusions: expandArmWebApplicationFirewallPolicyExclusions(exclusions), + ManagedRuleSets: expandArmWebApplicationFirewallPolicyManagedRuleSet(managedRuleSets), + } +} + +func expandArmWebApplicationFirewallPolicyExclusions(input []interface{}) *[]network.OwaspCrsExclusionEntry { + results := make([]network.OwaspCrsExclusionEntry, 0) + for _, item := range input { + v := item.(map[string]interface{}) + + matchVariable := v["match_variable"].(string) + selectorMatchOperator := v["selector_match_operator"].(string) + selector := v["selector"].(string) + + result := network.OwaspCrsExclusionEntry{ + MatchVariable: network.OwaspCrsExclusionEntryMatchVariable(matchVariable), + SelectorMatchOperator: network.OwaspCrsExclusionEntrySelectorMatchOperator(selectorMatchOperator), + Selector: utils.String(selector), + } + + results = append(results, result) + } + return &results +} + +func expandArmWebApplicationFirewallPolicyManagedRuleSet(input []interface{}) *[]network.ManagedRuleSet { + results := make([]network.ManagedRuleSet, 0) + for _, item := range input { + v := item.(map[string]interface{}) + + ruleSetType := v["type"].(string) + ruleSetVersion := v["version"].(string) + ruleGroupOverrides := []interface{}{} + if value, exists := v["rule_group_override"]; exists { + ruleGroupOverrides = value.([]interface{}) + } + result := network.ManagedRuleSet{ + RuleSetType: utils.String(ruleSetType), + RuleSetVersion: utils.String(ruleSetVersion), + RuleGroupOverrides: expandArmWebApplicationFirewallPolicyRuleGroupOverrides(ruleGroupOverrides), + } + + results = append(results, result) + } + return &results +} + +func expandArmWebApplicationFirewallPolicyRuleGroupOverrides(input []interface{}) *[]network.ManagedRuleGroupOverride { + results := make([]network.ManagedRuleGroupOverride, 0) + for _, item := range input { + v := item.(map[string]interface{}) + + ruleGroupName := v["rule_group_name"].(string) + disabledRules := v["disabled_rules"].([]interface{}) + + result := network.ManagedRuleGroupOverride{ + RuleGroupName: utils.String(ruleGroupName), + Rules: expandArmWebApplicationFirewallPolicyRules(disabledRules), + } + + results = append(results, result) + } + return &results +} + +func expandArmWebApplicationFirewallPolicyRules(input []interface{}) *[]network.ManagedRuleOverride { + results := make([]network.ManagedRuleOverride, 0) + for _, item := range input { + ruleID := item.(string) + + result := network.ManagedRuleOverride{ + RuleID: utils.String(ruleID), + State: network.ManagedRuleEnabledStateDisabled, + } + + results = append(results, result) + } + return &results +} + func expandArmWebApplicationFirewallPolicyMatchCondition(input []interface{}) *[]network.MatchCondition { results := make([]network.MatchCondition, 0) for _, item := range input { @@ -402,12 +583,102 @@ func flattenArmWebApplicationFirewallPolicyPolicySettings(input *network.PolicyS result := make(map[string]interface{}) - result["enabled"] = input.State == network.WebApplicationFirewallEnabledStateDisabled + result["enabled"] = input.State == network.WebApplicationFirewallEnabledStateEnabled result["mode"] = string(input.Mode) return []interface{}{result} } +func flattenArmWebApplicationFirewallPolicyManagedRulesDefinition(input *network.ManagedRulesDefinition) []interface{} { + results := make([]interface{}, 0) + if input == nil { + return results + } + + v := make(map[string]interface{}) + + v["exclusion"] = flattenArmWebApplicationFirewallPolicyExclusions(input.Exclusions) + v["managed_rule_set"] = flattenArmWebApplicationFirewallPolicyManagedRuleSets(input.ManagedRuleSets) + + results = append(results, v) + + return results +} + +func flattenArmWebApplicationFirewallPolicyExclusions(input *[]network.OwaspCrsExclusionEntry) []interface{} { + results := make([]interface{}, 0) + if input == nil { + return results + } + + for _, item := range *input { + v := make(map[string]interface{}) + + selector := item.Selector + + v["match_variable"] = string(item.MatchVariable) + if selector != nil { + v["selector"] = *selector + } + v["selector_match_operator"] = string(item.SelectorMatchOperator) + + results = append(results, v) + } + return results +} + +func flattenArmWebApplicationFirewallPolicyManagedRuleSets(input *[]network.ManagedRuleSet) []interface{} { + results := make([]interface{}, 0) + if input == nil { + return results + } + + for _, item := range *input { + v := make(map[string]interface{}) + + v["type"] = item.RuleSetType + v["version"] = item.RuleSetVersion + v["rule_group_override"] = flattenArmWebApplicationFirewallPolicyRuleGroupOverrides(item.RuleGroupOverrides) + + results = append(results, v) + } + return results +} + +func flattenArmWebApplicationFirewallPolicyRuleGroupOverrides(input *[]network.ManagedRuleGroupOverride) []interface{} { + results := make([]interface{}, 0) + if input == nil { + return results + } + + for _, item := range *input { + v := make(map[string]interface{}) + + v["rule_group_name"] = item.RuleGroupName + v["disabled_rules"] = flattenArmWebApplicationFirewallPolicyManagedRuleOverrides(item.Rules) + + results = append(results, v) + } + return results +} + +func flattenArmWebApplicationFirewallPolicyManagedRuleOverrides(input *[]network.ManagedRuleOverride) []string { + results := make([]string, 0) + if input == nil { + return results + } + + for _, item := range *input { + if item.State == "" || item.State == network.ManagedRuleEnabledStateDisabled { + v := *item.RuleID + + results = append(results, v) + } + } + + return results +} + func flattenArmWebApplicationFirewallPolicyMatchCondition(input *[]network.MatchCondition) []interface{} { results := make([]interface{}, 0) if input == nil { diff --git a/azurerm/internal/services/network/tests/resource_arm_web_application_firewall_policy_test.go b/azurerm/internal/services/network/tests/resource_arm_web_application_firewall_policy_test.go index 576c91e87635..8df8d533dd92 100644 --- a/azurerm/internal/services/network/tests/resource_arm_web_application_firewall_policy_test.go +++ b/azurerm/internal/services/network/tests/resource_arm_web_application_firewall_policy_test.go @@ -73,6 +73,25 @@ func TestAccAzureRMWebApplicationFirewallPolicy_complete(t *testing.T) { resource.TestCheckResourceAttr(data.ResourceName, "custom_rules.1.match_conditions.1.match_values.#", "1"), resource.TestCheckResourceAttr(data.ResourceName, "custom_rules.1.match_conditions.1.match_values.0", "Windows"), resource.TestCheckResourceAttr(data.ResourceName, "custom_rules.1.action", "Block"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.#", "1"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.exclusion.#", "2"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.exclusion.0.match_variable", "RequestHeaderNames"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.exclusion.0.selector", "x-shared-secret"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.exclusion.0.selector_match_operator", "Equals"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.exclusion.1.match_variable", "RequestCookieNames"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.exclusion.1.selector", "too-much-fun"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.exclusion.1.selector_match_operator", "EndsWith"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.managed_rule_set.#", "1"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.managed_rule_set.0.type", "OWASP"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.managed_rule_set.0.version", "3.1"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.managed_rule_set.0.rule_group_override.#", "1"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.managed_rule_set.0.rule_group_override.0.rule_group_name", "REQUEST-920-PROTOCOL-ENFORCEMENT"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.managed_rule_set.0.rule_group_override.0.disabled_rules.#", "2"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.managed_rule_set.0.rule_group_override.0.disabled_rules.0", "920300"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.managed_rule_set.0.rule_group_override.0.disabled_rules.1", "920440"), + resource.TestCheckResourceAttr(data.ResourceName, "policy_settings.#", "1"), + resource.TestCheckResourceAttr(data.ResourceName, "policy_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(data.ResourceName, "policy_settings.0.mode", "Prevention"), ), }, data.ImportStep(), @@ -129,6 +148,25 @@ func TestAccAzureRMWebApplicationFirewallPolicy_update(t *testing.T) { resource.TestCheckResourceAttr(data.ResourceName, "custom_rules.1.match_conditions.1.match_values.#", "1"), resource.TestCheckResourceAttr(data.ResourceName, "custom_rules.1.match_conditions.1.match_values.0", "Windows"), resource.TestCheckResourceAttr(data.ResourceName, "custom_rules.1.action", "Block"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.#", "1"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.exclusion.#", "2"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.exclusion.0.match_variable", "RequestHeaderNames"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.exclusion.0.selector", "x-shared-secret"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.exclusion.0.selector_match_operator", "Equals"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.exclusion.1.match_variable", "RequestCookieNames"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.exclusion.1.selector", "too-much-fun"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.exclusion.1.selector_match_operator", "EndsWith"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.managed_rule_set.#", "1"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.managed_rule_set.0.type", "OWASP"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.managed_rule_set.0.version", "3.1"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.managed_rule_set.0.rule_group_override.#", "1"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.managed_rule_set.0.rule_group_override.0.rule_group_name", "REQUEST-920-PROTOCOL-ENFORCEMENT"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.managed_rule_set.0.rule_group_override.0.disabled_rules.#", "2"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.managed_rule_set.0.rule_group_override.0.disabled_rules.0", "920300"), + resource.TestCheckResourceAttr(data.ResourceName, "managed_rules.0.managed_rule_set.0.rule_group_override.0.disabled_rules.1", "920440"), + resource.TestCheckResourceAttr(data.ResourceName, "policy_settings.#", "1"), + resource.TestCheckResourceAttr(data.ResourceName, "policy_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(data.ResourceName, "policy_settings.0.mode", "Prevention"), ), }, data.ImportStep(), @@ -199,6 +237,18 @@ resource "azurerm_web_application_firewall_policy" "test" { name = "acctestwafpolicy-%d" resource_group_name = azurerm_resource_group.test.name location = azurerm_resource_group.test.location + + managed_rules { + managed_rule_set { + type = "OWASP" + version = "3.1" + } + } + + policy_settings { + enabled = true + mode = "Detection" + } } `, data.RandomInteger, data.Locations.Primary, data.RandomInteger) } @@ -265,6 +315,38 @@ resource "azurerm_web_application_firewall_policy" "test" { action = "Block" } + + managed_rules { + exclusion { + match_variable = "RequestHeaderNames" + selector = "x-shared-secret" + selector_match_operator = "Equals" + } + + exclusion { + match_variable = "RequestCookieNames" + selector = "too-much-fun" + selector_match_operator = "EndsWith" + } + + managed_rule_set { + type = "OWASP" + version = "3.1" + + rule_group_override { + rule_group_name = "REQUEST-920-PROTOCOL-ENFORCEMENT" + disabled_rules = [ + "920300", + "920440", + ] + } + } + } + + policy_settings { + enabled = true + mode = "Prevention" + } } `, data.RandomInteger, data.Locations.Primary, data.RandomInteger) } diff --git a/website/docs/r/web_application_firewall_policy.html.markdown b/website/docs/r/web_application_firewall_policy.html.markdown index 51a80dcabee0..b1ee28367c72 100644 --- a/website/docs/r/web_application_firewall_policy.html.markdown +++ b/website/docs/r/web_application_firewall_policy.html.markdown @@ -69,6 +69,37 @@ resource "azurerm_web_application_firewall_policy" "example" { action = "Block" } + + policy_settings { + enabled = true + mode = "Prevention" + } + + managed_rules { + exclusion { + match_variable = "RequestHeaderNames" + selector = "x-company-secret-header" + selector_match_operator = "Equals" + } + exclusion { + match_variable = "RequestCookieNames" + selector = "too-tasty" + selector_match_operator = "EndsWith" + } + + managed_rule_set { + rule_set_type = "OWASP" + rule_set_version = "3.1" + rule_group_override { + rule_group_name = "REQUEST-920-PROTOCOL-ENFORCEMENT" + disabled_rules = [ + "920300", + "920440" + ] + } + } + } + } ``` @@ -82,41 +113,43 @@ The following arguments are supported: * `location` - (Optional) Resource location. Changing this forces a new resource to be created. -* `custom_rules` - (Optional) One or more `custom_rule` blocks as defined below. +* `custom_rules` - (Optional) One or more `custom_rules` blocks as defined below. + +* `policy_settings` - (Optional) A `policy_settings` block as defined below. -* `policy_settings` - (Optional) A `policy_setting` block as defined below. +* `managed_rules` - (Optional) A `managed_rules` blocks as defined below. * `tags` - (Optional) A mapping of tags to assign to the Web Application Firewall Policy. --- -The `custom_rule` block supports the following: +The `custom_rules` block supports the following: * `name` - (Optional) Gets name of the resource that is unique within a policy. This name can be used to access the resource. -* `priority` - (Required) Describes priority of the rule. Rules with a lower value will be evaluated before rules with a higher value +* `priority` - (Required) Describes priority of the rule. Rules with a lower value will be evaluated before rules with a higher value. -* `rule_type` - (Required) Describes the type of rule +* `rule_type` - (Required) Describes the type of rule. -* `match_conditions` - (Required) One or more `match_condition` block defined below. +* `match_conditions` - (Required) One or more `match_conditions` blocks as defined below. -* `action` - (Required) Type of Actions +* `action` - (Required) Type of action. --- -The `match_condition` block supports the following: +The `match_conditions` block supports the following: -* `match_variables` - (Required) One or more `match_variable` block defined below. +* `match_variables` - (Required) One or more `match_variables` blocks as defined below. -* `operator` - (Required) Describes operator to be matched +* `operator` - (Required) Describes operator to be matched. * `negation_condition` - (Optional) Describes if this is negate condition or not -* `match_values` - (Required) Match value +* `match_values` - (Required) A list of match values. --- -The `match_variable` block supports the following: +The `match_variables` block supports the following: * `variable_name` - (Required) The name of the Match Variable @@ -124,12 +157,48 @@ The `match_variable` block supports the following: --- -The `policy_setting` block supports the following: +The `policy_settings` block supports the following: * `enabled` - (Optional) Describes if the policy is in enabled state or disabled state Defaults to `Enabled`. * `mode` - (Optional) Describes if it is in detection mode or prevention mode at the policy level Defaults to `Prevention`. +--- + +The `managed_rules` block supports the following: + +* `exclusion` - (Optional) One or more `exclusion` block defined below. + +* `managed_rule_set` - (Optional) One or more `managed_rule_set` block defined below. + +--- + +The `exclusion` block supports the following: + +* `match_variables` - (Required) The name of the Match Variable. Possible values: `RequestArgNames`, `RequestCookieNames`, `RequestHeaderNames`. + +* `selector` - (Optional) Describes field of the matchVariable collection. + +* `selector_match_operator` - (Required) Describes operator to be matched. Possible values: `Contains`, `EndsWith`, `Equals`, `EqualsAny`, `StartsWith`. + +--- + +The `managed_rule_set` block supports the following: + +* `type` - (Required) The rule set type. + +* `version` - (Required) The rule set version. + +* `rule_group_override` - (Optional) One or more `rule_group_override` block defined below. + +--- + +The `rule_group_override` block supports the following: + +* `rule_group_name` - (Required) The name of the Rule Group + +* `disabled_rules` - (Optional) One or more Rule ID's + ## Attributes Reference The following attributes are exported: