From 762f080be27fd8a3fb6937f1062d7f60da257ae6 Mon Sep 17 00:00:00 2001 From: Wodans Son <20408400+WodansSon@users.noreply.github.com> Date: Mon, 12 Dec 2022 01:06:42 -0700 Subject: [PATCH] [Bug:] `azurerm_cdn_frontdoor_firewall_policy` - allow `Log` as a valid value for managed rule override `action` in DRS 2.0 and above (#19637) --- .../cdn_frontdoor_firewall_policy_resource.go | 7 +- ...frontdoor_firewall_policy_resource_test.go | 109 +++++++++++++++++- ...dn_frontdoor_firewall_policy.html.markdown | 8 +- 3 files changed, 116 insertions(+), 8 deletions(-) diff --git a/internal/services/cdn/cdn_frontdoor_firewall_policy_resource.go b/internal/services/cdn/cdn_frontdoor_firewall_policy_resource.go index ef307e0acc99..832d025a746f 100644 --- a/internal/services/cdn/cdn_frontdoor_firewall_policy_resource.go +++ b/internal/services/cdn/cdn_frontdoor_firewall_policy_resource.go @@ -901,16 +901,17 @@ func expandCdnFrontDoorFirewallRuleOverride(input []interface{}, versionRaw stri if rule["enabled"].(bool) { enabled = frontdoor.ManagedRuleEnabledStateEnabled } + ruleId := rule["rule_id"].(string) actionTypeRaw := rule["action"].(string) action := frontdoor.ActionType(actionTypeRaw) - // NOTE: Default Rule Sets(DRS) 2.0 and above rules only use action type of 'AnomalyScoring' + // NOTE: Default Rule Sets(DRS) 2.0 and above rules only use action type of 'AnomalyScoring' or 'Log'. Issues 19088 and 19561 // This will still work for bot rules as well since it will be the default value of 1.0 if version < 2.0 && actionTypeRaw == "AnomalyScoring" { return nil, fmt.Errorf("'AnomalyScoring' is only valid in managed rules that are DRS 2.0 and above, got %q", versionRaw) - } else if version >= 2.0 && actionTypeRaw != "AnomalyScoring" { - return nil, fmt.Errorf("the managed rules 'action' field must be set to 'AnomalyScoring' if the managed rule is DRS 2.0 or above, got %q", action) + } else if version >= 2.0 && actionTypeRaw != "AnomalyScoring" && actionTypeRaw != "Log" { + return nil, fmt.Errorf("the managed rules 'action' field must be set to 'AnomalyScoring' or 'Log' if the managed rule is DRS 2.0 or above, got %q", action) } exclusions := expandCdnFrontDoorFirewallManagedRuleGroupExclusion(rule["exclusion"].([]interface{})) diff --git a/internal/services/cdn/cdn_frontdoor_firewall_policy_resource_test.go b/internal/services/cdn/cdn_frontdoor_firewall_policy_resource_test.go index 4adf7dbe55d8..6517a02c513b 100644 --- a/internal/services/cdn/cdn_frontdoor_firewall_policy_resource_test.go +++ b/internal/services/cdn/cdn_frontdoor_firewall_policy_resource_test.go @@ -205,7 +205,7 @@ func TestAccCdnFrontDoorFirewallPolicy_DRSTwoPointOhError(t *testing.T) { data.ResourceTest(t, r, []acceptance.TestStep{ { Config: r.DRSTwoPointOhError(data), - ExpectError: regexp.MustCompile("the managed rules 'action' field must be set to 'AnomalyScoring' if the managed rule is DRS 2.0 or above"), + ExpectError: regexp.MustCompile("the managed rules 'action' field must be set to 'AnomalyScoring' or 'Log' if the managed rule is DRS 2.0 or above"), }, }) } @@ -222,6 +222,33 @@ func TestAccCdnFrontDoorFirewallPolicy_DRSTwoPointOhTypeError(t *testing.T) { }) } +func TestAccCdnFrontDoorFirewallPolicy_DRSTwoPointOneAction(t *testing.T) { + // NOTE: Regression test case for issue #19561 + data := acceptance.BuildTestData(t, "azurerm_cdn_frontdoor_firewall_policy", "test") + r := CdnFrontDoorFirewallPolicyResource{} + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.DRSTwoPointOneActionLog(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func TestAccCdnFrontDoorFirewallPolicy_DRSTwoPointOneActionError(t *testing.T) { + // NOTE: Regression test case for issue #19561 + data := acceptance.BuildTestData(t, "azurerm_cdn_frontdoor_firewall_policy", "test") + r := CdnFrontDoorFirewallPolicyResource{} + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.DRSTwoPointOneActionError(data), + ExpectError: regexp.MustCompile("the managed rules 'action' field must be set to 'AnomalyScoring' or 'Log' if the managed rule is DRS 2.0 or above"), + }, + }) +} + func (CdnFrontDoorFirewallPolicyResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { id, err := parse.FrontDoorFirewallPolicyID(state.ID) if err != nil { @@ -681,3 +708,83 @@ resource "azurerm_cdn_frontdoor_firewall_policy" "test" { } `, tmp, data.RandomInteger) } + +func (r CdnFrontDoorFirewallPolicyResource) DRSTwoPointOneActionLog(data acceptance.TestData) string { + tmp := r.template(data) + return fmt.Sprintf(` +%s + +resource "azurerm_cdn_frontdoor_firewall_policy" "test" { + name = "accTestWAF%d" + resource_group_name = azurerm_resource_group.test.name + sku_name = azurerm_cdn_frontdoor_profile.test.sku_name + enabled = true + mode = "Prevention" + redirect_url = "https://www.contoso.com" + custom_block_response_status_code = 403 + custom_block_response_body = "PGh0bWw+CjxoZWFkZXI+PHRpdGxlPkhlbGxvPC90aXRsZT48L2hlYWRlcj4KPGJvZHk+CkhlbGxvIHdvcmxkCjwvYm9keT4KPC9odG1sPg==" + + managed_rule { + type = "Microsoft_DefaultRuleSet" + version = "2.1" + action = "Block" + + override { + rule_group_name = "PHP" + + rule { + rule_id = "933100" + enabled = false + action = "AnomalyScoring" + } + + rule { + rule_id = "933110" + enabled = false + action = "Log" + } + } + } +} +`, tmp, data.RandomInteger) +} + +func (r CdnFrontDoorFirewallPolicyResource) DRSTwoPointOneActionError(data acceptance.TestData) string { + tmp := r.template(data) + return fmt.Sprintf(` +%s + +resource "azurerm_cdn_frontdoor_firewall_policy" "test" { + name = "accTestWAF%d" + resource_group_name = azurerm_resource_group.test.name + sku_name = azurerm_cdn_frontdoor_profile.test.sku_name + enabled = true + mode = "Prevention" + redirect_url = "https://www.contoso.com" + custom_block_response_status_code = 403 + custom_block_response_body = "PGh0bWw+CjxoZWFkZXI+PHRpdGxlPkhlbGxvPC90aXRsZT48L2hlYWRlcj4KPGJvZHk+CkhlbGxvIHdvcmxkCjwvYm9keT4KPC9odG1sPg==" + + managed_rule { + type = "Microsoft_DefaultRuleSet" + version = "2.1" + action = "Block" + + override { + rule_group_name = "PHP" + + rule { + rule_id = "933100" + enabled = false + action = "AnomalyScoring" + } + + rule { + rule_id = "933110" + enabled = false + action = "Redirect" + } + } + } +} +`, tmp, data.RandomInteger) +} diff --git a/website/docs/r/cdn_frontdoor_firewall_policy.html.markdown b/website/docs/r/cdn_frontdoor_firewall_policy.html.markdown index 962a4c7ce96d..e774cd0893c8 100644 --- a/website/docs/r/cdn_frontdoor_firewall_policy.html.markdown +++ b/website/docs/r/cdn_frontdoor_firewall_policy.html.markdown @@ -201,9 +201,7 @@ A `managed_rule` block supports the following: * `version` - (Required) The version of the managed rule to use with this resource. Possible values depends on which DRS type you are using, for the `DefaultRuleSet` type the possible values include `1.0` or `preview-0.1`. For `Microsoft_DefaultRuleSet` the possible values include `1.1`, `2.0` or `2.1`. For `BotProtection` the value must be `preview-0.1` and for `Microsoft_BotManagerRuleSet` the value must be `1.0`. -* `action` - (Required) The action to perform when the managed rule is matched. Possible values depends on which DRS version you are using, for DRS `1.0`, `1.1` and `preview-0.1` the possible values include `Allow`, `Block`, `Log`, or `Redirect`. For DRS `2.0` and `2.1` the value must be `AnomalyScoring`. - -->**NOTE:** Please see the DRS [product documentation](https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-drs?tabs=drs20#anomaly-scoring-mode) for more information. +* `action` - (Required) The action to perform for all DRS rules when the managed rule is matched or when the anomaly score is 5 or greater depending on which version of the DRS you are using. Possible values include `Allow`, `Log`, `Block`, and `Redirect`. * `exclusion` - (Optional) One or more `exclusion` blocks as defined below. @@ -225,7 +223,9 @@ A `rule` block supports the following: * `rule_id` - (Required) Identifier for the managed rule. -* `action` - (Required) The action to be applied when the rule matches. Possible values are `Allow`, `Log`, `Block`, `Redirect` and `AnomalyScoring`. +* `action` - (Required) The action to be applied when the managed rule matches or when the anomaly score is 5 or greater. Possible values for DRS `1.1` and below are `Allow`, `Log`, `Block`, and `Redirect`. For DRS `2.0` and above the possible values are `Log` or `AnomalyScoring`. + +->**NOTE:** Please see the DRS [product documentation](https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-drs?tabs=drs20#anomaly-scoring-mode) for more information. * `enabled` - (Optional) Is the managed rule override enabled or disabled. Defaults to `false`