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

如何通过Terraform为Azure APIM动态配置IP过滤策略?

Azure APIM环境差异化IP过滤的Terraform解决方案

方案1:Terraform动态生成APIM策略XML(推荐)

直接在Terraform层面处理环境差异化的IP列表,生成完整合法的策略XML,规避APIM策略表达式的解析限制。

  1. 按环境定义IP变量
    在variables.tf中声明通用变量:

    variable "environment" {
      type = string
      default = "dev"
    }
    
    variable "allowed_ips" {
      type = list(string)
      description = "List of allowed single IP addresses"
      default = []
    }
    
    variable "allowed_ip_ranges" {
      type = list(string)
      description = "List of allowed IP CIDR ranges"
      default = []
    }
    

    在对应环境的tfvars文件(如dev.tfvars)中赋值:

    environment = "dev"
    allowed_ips = ["192.168.1.1", "10.0.0.5"]
    allowed_ip_ranges = ["192.168.0.0/24", "10.0.0.0/16"]
    
  2. 动态拼接IP过滤策略
    用Terraform的locals和heredoc生成完整策略:

    locals {
      ip_address_nodes = [for ip in var.allowed_ips : "<address>${ip}</address>"]
      ip_range_nodes = [for range in var.allowed_ip_ranges : "<address-range>${range}</address-range>"]
      ip_filter_fragment = join("\n      ", concat(local.ip_address_nodes, local.ip_range_nodes))
    }
    
    resource "azurerm_api_management_api_policy" "example" {
      api_name            = azurerm_api_management_api.example.name
      api_management_name = azurerm_api_management.example.name
      resource_group_name = azurerm_resource_group.example.name
    
      content = <<XML
    <policies>
      <inbound>
        <ip-filter action="allow">
          ${local.ip_filter_fragment}
        </ip-filter>
        <!-- 其他入站策略 -->
      </inbound>
      <!-- 其他策略节点 -->
    </policies>
    XML
    }
    

    Terraform会根据当前环境变量自动生成对应节点,APIM收到的是标准XML,不会触发解析错误。

方案2:修正APIM策略表达式语法

若坚持使用APIM NamedValue存储IP列表,需严格遵循APIM Policy Expression语法,避免XML解析冲突:

  1. 配置NamedValue
    在Terraform中创建NamedValue存储逗号分隔的IP字符串:

    resource "azurerm_api_management_named_value" "allowed_ips" {
      name                = "AllowedIPAddresses"
      api_management_name = azurerm_api_management.example.name
      resource_group_name = azurerm_resource_group.example.name
      value               = join(",", var.allowed_ips)
    }
    
    resource "azurerm_api_management_named_value" "allowed_ip_ranges" {
      name                = "AllowedIPRanges"
      api_management_name = azurerm_api_management.example.name
      resource_group_name = azurerm_resource_group.example.name
      value               = join(",", var.allowed_ip_ranges)
    }
    
  2. 编写正确的APIM策略
    使用APIM的<foreach>节点遍历拆分后的IP数组,表达式必须用@{...}包裹,确保XML结构合法:

    <policies>
      <inbound>
        <ip-filter action="allow">
          <!-- 遍历单个IP -->
          <foreach items="@(split(NamedValue.GetValue("AllowedIPAddresses"), ','))" scope="request" var="ip">
            <address>@(context.Variables.GetValueOrDefault("ip").Trim())</address>
          </foreach>
          <!-- 遍历IP范围 -->
          <foreach items="@(split(NamedValue.GetValue("AllowedIPRanges"), ','))" scope="request" var="range">
            <address-range>@(context.Variables.GetValueOrDefault("range").Trim())</address-range>
          </foreach>
        </ip-filter>
        <!-- 其他入站策略 -->
      </inbound>
    </policies>
    

    之前的解析错误大概率是因为直接在XML节点中嵌入未正确包裹的表达式,导致XML解析器无法识别。

方案3:封装Terraform模块复用逻辑

将IP过滤策略生成逻辑封装为模块,方便多环境、多API复用:

# modules/apim_ip_filter/main.tf
variable "allowed_ips" {
  type = list(string)
  description = "List of allowed single IPs"
}

variable "allowed_ip_ranges" {
  type = list(string)
  description = "List of allowed IP ranges"
}

output "policy_fragment" {
  type = string
  value = join("\n      ", concat(
    [for ip in var.allowed_ips : "<address>${ip}</address>"],
    [for range in var.allowed_ip_ranges : "<address-range>${range}</address-range>"]
  ))
}

主模块调用示例:

module "api_ip_filter" {
  source = "./modules/apim_ip_filter"
  allowed_ips = var.allowed_ips
  allowed_ip_ranges = var.allowed_ip_ranges
}

resource "azurerm_api_management_api_policy" "example" {
  # ... 基础配置
  content = <<XML
<policies>
  <inbound>
    <ip-filter action="allow">
      ${module.api_ip_filter.policy_fragment}
    </ip-filter>
  </inbound>
</policies>
XML
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 00:23:20