Terraform for_each配置NSG规则source_address_prefix报错排查
问题根因
报错直接原因是配置逻辑存在3个核心错误:
source_address_prefix是azurerm_network_security_rule资源的单值字符串属性,不是可重复声明的嵌套块,根本不支持通过dynamic块循环生成,所以Terraform直接抛出不支持该块类型的错误。- AzureRM provider对NSG规则的多源地址场景专门提供了复数形式的参数
source_address_prefixes(类型为字符串列表),传多个IP前缀必须用这个参数,不能在单值参数上套循环。 - 当前本地变量里的
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
相关产品推荐
相关产品推荐

