azureterraformazure-application-gatewayazure-waf

Terraform Azure Application Gateway associated WAF policy - add multiple rule override IDs


My question is - How do I create a rule exclusion (override) for a WAF policy that's associated to an Application Gateway that has multiple rule IDs in Terraform?

I've created a dynamic rule for my Application Gateway, I've get the below error when trying to apply the code via a CI/CD pipeline:

│ Error: creating Application Gateway Web Application Firewall Policy (Subscription: "XXXX-XXXX-XXXX-XXXX"
│ Resource Group Name: "rg-appgw-prod-uks"
│ Application Gateway Web Application Firewall Policy Name: "waf-policy-appgw-prod-uksouth"): unexpected status 400 (400 Bad Request) with error: ApplicationGatewayFirewallDuplicateRuleGroupOverride: The override RuleGroup 'REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION' is defined more than once for Application Gateway Firewall in context '/subscriptions/XXXX-XXXX-XXXX-XXXX-XXXX/resourceGroups/rg-appgw-prod-uks/providers/Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies/waf-policy-appgw-prod-uksouth'.
│ 
│   with azurerm_web_application_firewall_policy.waf_policy,
│   on application_gw.tf line 101, in resource "azurerm_web_application_firewall_policy" "waf_policy":
│  101: resource "azurerm_web_application_firewall_policy" "waf_policy" {

The config I've got is below: TFVARS -

rule_group_override = [
    {
        rule_group_name = "REQUEST-920-PROTOCOL-ENFORCEMENT"
        id              = "920300"
        enabled         = false
    },
    {
        rule_group_name = "REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION"
        id              = "943100"
        enabled         = false
    },
    {
        rule_group_name = "REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION"
        id              = "943110"
        enabled         = false
    },
    {
        rule_group_name = "REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION"
        id              = "943120"
        enabled         = false
    }
]

Variables -

variable "rule_group_override" {
  type  = list(object({
    rule_group_name = string
    id              = string
    enabled         = bool
  }))
}

Appgw -

      dynamic "rule_group_override" {
        for_each = var.rule_group_override
        content {
          rule_group_name = rule_group_override.value["rule_group_name"]
          rule {
            id      = rule_group_override.value["id"]
            enabled = rule_group_override.value["enabled"]
          } 
        }
      }

Solution

  • Adding multiple rule override IDs while provisioning Azure Application Gateway associated WAF policy using terraform

    The blocker shared in the query occurs in general when the same rule_group_name is specified multiple times in your rule_group_override blocks. However, while using Azure, it expects rule_group_name to be unique within the managed_rule_set.

    If you want to disable multiple rules within the same group, they should be consolidated under a single rule_group_override.

    Demo configuration:

    variable "rule_group_overrides" {
      type = map(list(object({
        id      = string
        enabled = bool
      })))
    }
    
    data "azurerm_resource_group" "rg" {
      name = "vinay-rg"
    }
    
    resource "azurerm_web_application_firewall_policy" "waf_policy" {
      name                = "waf-policy-appgw-prod-eastus"
      resource_group_name = data.azurerm_resource_group.rg.name
      location            = data.azurerm_resource_group.rg.location
    
      policy_settings {
        enabled                     = true
        mode                        = "Prevention"
        request_body_check          = true
        file_upload_limit_in_mb     = 100
        max_request_body_size_in_kb = 2000
      }
    
      managed_rules {
        managed_rule_set {
          type    = "OWASP"
          version = "3.2"
    
          dynamic "rule_group_override" {
            for_each = var.rule_group_overrides
            content {
              rule_group_name = rule_group_override.key
    
              dynamic "rule" {
                for_each = rule_group_override.value
                content {
                  id      = rule.value.id
                  enabled = rule.value.enabled
                }
              }
            }
          }
        }
      }
    }
    

    tfvars:

    rule_group_overrides = {
      "REQUEST-920-PROTOCOL-ENFORCEMENT" = [
        { id = "920300", enabled = false }
      ],
      "REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION" = [
        { id = "943100", enabled = false },
        { id = "943110", enabled = false },
        { id = "943120", enabled = false }
      ]
    }
    

    Deployment:

    enter image description here

    enter image description here

    enter image description here

    Here we applied rule overrides and explicitly disabled those rule IDs mentioned

    Refer:

    https://github.com/hashicorp/terraform-provider-azurerm/issues/20183

    https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/web_application_firewall_policy