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

Terraform for_each配置NSG规则source_address_prefix报错排查

问题根因

报错直接原因是配置逻辑存在3个核心错误:

  1. source_address_prefix是azurerm_network_security_rule资源的单值字符串属性,不是可重复声明的嵌套块,根本不支持通过dynamic块循环生成,所以Terraform直接抛出不支持该块类型的错误。
  2. AzureRM provider对NSG规则的多源地址场景专门提供了复数形式的参数source_address_prefixes(类型为字符串列表),传多个IP前缀必须用这个参数,不能在单值参数上套循环。
  3. 当前本地变量里的source_address_prefix字段类型不统一:有的规则传字符串,有的传列表,会直接触发类型不匹配的二次报错。
修复方案
  • 统一调整本地变量中所有规则的source_address_prefix字段格式,全部转为字符串列表类型,单IP、通配符*都包装为单元素列表,保证类型一致。
  • 删除错误的dynamic "source_address_prefix"嵌套块,直接将列表值传给复数参数source_address_prefixes即可,该参数原生支持接收列表,不需要额外循环。
  • 注意:单值参数source_address_prefix和多值参数source_address_prefixes互斥,同一条规则里只能选一个使用,多IP场景全程用复数参数即可。
修复后完整代码

main.tf

resource "azurerm_network_security_group" "nsg" {
  name                = "nsg"
  location            = azurerm_resource_group.Terraform.location 
  resource_group_name = azurerm_resource_group.Terraform.name
}

resource "azurerm_network_security_rule" "nsg1rules" {
  for_each                    = local.nsgrules
  name                        = each.key
  direction                   = each.value.direction
  access                      = each.value.access
  priority                    = each.value.priority
  protocol                    = each.value.protocol
  source_port_range           = each.value.source_port_range
  destination_port_range      = each.value.destination_port_range
  # 直接使用多值参数传列表,删除错误的dynamic块
  source_address_prefixes     = each.value.source_address_prefix
  destination_address_prefix  = each.value.destination_address_prefix
  resource_group_name         = azurerm_resource_group.Terraform.name
  network_security_group_name = azurerm_network_security_group.nsg.name
}

resource "azurerm_network_interface_security_group_association" "nsg" {
  network_interface_id      = azurerm_network_interface.nic.id
  network_security_group_id = azurerm_network_security_group.nsg.id
}

locals.tf

locals {
  nsgrules = {
    rdp = {
      name                       = "RDP"
      priority                   = 330
      direction                  = "Inbound"
      access                     = "Deny"
      protocol                   = "Tcp"
      source_port_range          = "*"
      destination_port_range     = "3389"
      # 统一转为列表格式
      source_address_prefix      = ["0.0.0.0"]
      destination_address_prefix = "*"
    }

    rdp2 = {
      name                       = "RDP2"
      priority                   = 340
      direction                  = "Inbound"
      access                     = "Deny"
      protocol                   = "Tcp"
      source_port_range          = "*"
      destination_port_range     = "3389"
      source_address_prefix      = ["1.1.1.1", "2.2.2.2"]
      destination_address_prefix = "*"
    }

    rdp3 = {
      name                       = "RDP3"
      priority                   = 310
      direction                  = "Inbound"
      access                     = "Allow"
      protocol                   = "Tcp"
      source_port_range          = "*"
      destination_port_range     = "3389"
      # 统一转为列表格式
      source_address_prefix      = ["3.3.3.3"]
      destination_address_prefix = "*"
    }

    https = {
      name                       = "HTTPS"
      priority                   = 320
      direction                  = "Inbound"
      access                     = "Allow"
      protocol                   = "Tcp"
      source_port_range          = "*"
      destination_port_range     = "443"
      # 统一转为列表格式
      source_address_prefix      = ["*"]
      destination_address_prefix = "*"
    }
  }
}

补充提示:如果后续需要配置多目的地址前缀,同理使用复数参数destination_address_prefixes即可,不要在单值destination_address_prefix上套dynamic块。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 08:33:11