You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Terraform部署Azure WAF自定义规则遇ApplicationGatewayFirewallMatchValueNoCollection错误

问题描述

部署Azure WAF自定义规则时遇到400错误:

Application Gateway Web Application Firewall Policy Name: "waf-policy-prod-uksouth"): unexpected status 400 (400 Bad Request) with error: ApplicationGatewayFirewallMatchValueNoCollection: Custom Rule 'AllowAmexPay' does not have a valid collection match variable 'RequestUri' which support selector in its condition in context 'properties.customRules[2].matchConditions[0].matchVariables[0]'.

with azurerm_web_application_firewall_policy.waf_policy,
on application_gw.tf line 224, in resource "azurerm_web_application_firewall_policy" "waf_policy":
224: resource "azurerm_web_application_firewall_policy" "waf_policy" {

相关配置文件如下:

TFVars文件

custom_rules = [
    {
        name                    = "RecitePreferences"
        priority                = "70"
        enabled                 = true
        rule_type               = "MatchRule"
        variable_name           = "RequestCookies"
        selector                = "Recite.Preferences"
        operator                = "Any"
        action                  = "Allow"
    },
    {
        name                    = "CookieConsent"
        priority                = "71"
        enabled                 = true
        rule_type               = "MatchRule"
        variable_name           = "RequestCookies"
        selector                = "CookieConsent"
        operator                = "Any"
        action                  = "Allow"
    },
    {
        name                    = "AllowAmexPay"
        priority                = "80"
        enabled                 = true
        rule_type               = "MatchRule"
        variable_name           = "RequestUri"
        selector                = "/smart-card/amex-pay"
        operator                = "Contains"
        action                  = "Allow"
    },
    {
        name                    = "AllowAmexPayComplete"
        priority                = "81"
        enabled                 = true
        rule_type               = "MatchRule"
        variable_name           = "RequestUri"
        selector                = "/smart-card/amex-pay-complete"
        operator                = "Contains"
        action                  = "Allow"
    }
]

Variables.tf文件

variable "custom_rules" {
  type  = list(object({
    name                    = string
    priority                = string
    enabled                 = bool
    rule_type               = string
    variable_name           = string
    operator                = string
    selector                = string
    action                  = string
  }))
}

Application Gateway配置

resource "azurerm_web_application_firewall_policy" "waf_policy" {
  name                = "waf-policy-${var.general_environment}-${var.general_location}"
  resource_group_name = azurerm_resource_group.prod.name
  location            = azurerm_resource_group.prod.location

  policy_settings {
    enabled                     = true
    mode                        = "Detection"
    request_body_check          = false
    file_upload_limit_in_mb     = 100
    max_request_body_size_in_kb = 128
  }
  managed_rules {
    managed_rule_set {
      type    = "OWASP"
      version = "3.2"
      
      dynamic "rule_group_override" {
        for_each = var.rule_group_override
        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
            } 
          }
        }
      }
    }

    dynamic "exclusion" {
      for_each = var.exclusion

      content {
        match_variable          = exclusion.value["match_variable"]
        selector                = exclusion.value["selector"]
        selector_match_operator = exclusion.value["selector_match_operator"]
      }
    }
    managed_rule_set {
      type = "Microsoft_BotManagerRuleSet"
      version = "1.0"
    }
  }
  dynamic "custom_rules" {
    for_each = var.custom_rules

    content {
      name          = custom_rules.value["name"]
      enabled       = custom_rules.value["enabled"]
      priority      = custom_rules.value["priority"]
      rule_type     = custom_rules.value["rule_type"]
      action        = custom_rules.value["action"]
      match_conditions {
        operator     = custom_rules.value["operator"]
        match_variables {
          variable_name = custom_rules.value["variable_name"]
          selector      = custom_rules.value["selector"]
        }
      }
    } 
  }     
}

疑问:是否有更优的变量传递方式来解决该部署错误?


解决方案

错误根源

Azure WAF的RequestUri属于单值匹配变量,这类变量不支持使用selector(selector仅适用于集合类变量,比如RequestCookies、RequestHeaders,用来指定集合中的具体项)。当前配置强制所有规则都传递selector,导致RequestUri规则触发API校验错误。

优化后的变量传递与配置调整

1. 修改Variables.tf:让selector可选,新增match_values字段

调整变量结构,兼容集合类和单值类规则的不同配置需求:

variable "custom_rules" {
  type = list(object({
    name                    = string
    priority                = string
    enabled                 = bool
    rule_type               = string
    variable_name           = string
    operator                = string
    action                  = string
    # selector仅用于集合类变量,设为可选
    selector                = optional(string)
    # match_values用于单值变量,设为可选列表
    match_values            = optional(list(string))
  }))
}

2. 修改TFVars文件:调整RequestUri规则的配置

把RequestUri规则的selector替换为match_values:

custom_rules = [
    {
        name                    = "RecitePreferences"
        priority                = "70"
        enabled                 = true
        rule_type               = "MatchRule"
        variable_name           = "RequestCookies"
        selector                = "Recite.Preferences"
        operator                = "Any"
        action                  = "Allow"
    },
    {
        name                    = "CookieConsent"
        priority                = "71"
        enabled                 = true
        rule_type               = "MatchRule"
        variable_name           = "RequestCookies"
        selector                = "CookieConsent"
        operator                = "Any"
        action                  = "Allow"
    },
    {
        name                    = "AllowAmexPay"
        priority                = "80"
        enabled                 = true
        rule_type               = "MatchRule"
        variable_name           = "RequestUri"
        match_values            = ["/smart-card/amex-pay"]
        operator                = "Contains"
        action                  = "Allow"
    },
    {
        name                    = "AllowAmexPayComplete"
        priority                = "81"
        enabled                 = true
        rule_type               = "MatchRule"
        variable_name           = "RequestUri"
        match_values            = ["/smart-card/amex-pay-complete"]
        operator                = "Contains"
        action                  = "Allow"
    }
]

3. 修改Application Gateway配置:动态匹配变量类型

在dynamic custom_rules块中,根据变量类型决定是否输出selector或match_values:

resource "azurerm_web_application_firewall_policy" "waf_policy" {
  # 保留原有基础配置...

  dynamic "custom_rules" {
    for_each = var.custom_rules

    content {
      name          = custom_rules.value["name"]
      enabled       = custom_rules.value["enabled"]
      priority      = custom_rules.value["priority"]
      rule_type     = custom_rules.value["rule_type"]
      action        = custom_rules.value["action"]
      match_conditions {
        operator     = custom_rules.value["operator"]
        # 动态生成match_variables
        dynamic "match_variables" {
          for_each = [custom_rules.value]
          content {
            variable_name = match_variables.value["variable_name"]
            # 仅当selector存在时输出
            if match_variables.value["selector"] != null {
              selector = match_variables.value["selector"]
            }
          }
        }
        # 仅当match_values存在时输出
        if custom_rules.value["match_values"] != null {
          match_values = custom_rules.value["match_values"]
        }
      }
    } 
  }     
}

关键说明

  • 集合类变量(如RequestCookies):使用selector指定要匹配的集合项,配合operator = "Any"或"Equals"等使用。
  • 单值类变量(如RequestUri、RequestMethod):使用match_values指定匹配值,配合operator = "Contains"、"Equals"等使用。
  • 调整后的变量结构更灵活,既能兼容原有集合类规则,也能正确配置单值类规则,避免触发Azure WAF的API校验错误。

内容的提问来源于stack exchange,提问作者Matty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 06:38:10