在Azure中用Terraform循环为子网创建NSG时遇属性错误求助
Terraform循环创建Azure子网NSG的属性错误解决
问题场景
尝试通过Terraform循环为Azure虚拟网络中的所有子网创建Network Security Group(NSG)并关联到对应子网,但执行时触发属性不存在的错误。
代码片段
Main.tf
resource "azurerm_network_security_group" "nsg" { for_each = var.subnets name = lower("nsg_${each.key}_in") resource_group_name = var.resource_group_name location = var.location tags = merge({ "ResourceName" = lower("nsg_${each.key}_in") }, var.tags, ) dynamic "security_rule" { for_each = concat(lookup(each.value, "nsg_inbound_rules", []), lookup(each.value, "nsg_outbound_rules", [])) content { name = security_rule.value[0] == "" ? "Default_Rule" : security_rule.value[0] priority = security_rule.value[1] direction = security_rule.value[2] == "" ? "Inbound" : security_rule.value[2] access = security_rule.value[3] == "" ? "Allow" : security_rule.value[3] protocol = security_rule.value[4] == "" ? "Tcp" : security_rule.value[4] source_port_range = "*" destination_port_range = security_rule.value[5] == "" ? "*" : security_rule.value[5] source_address_prefix = security_rule.value[6] == "" ? element(each.value.subnet_address_prefix, 0) : security_rule.value[6] destination_address_prefix = security_rule.value[7] == "" ? element(each.value.subnet_address_prefix, 0) : security_rule.value[7] description = "${security_rule.value[2]}_Port_${security_rule.value[5]}" } } } resource "azurerm_subnet_network_security_group_association" "nsg-assoc" { for_each = var.subnets subnet_id = azurerm_subnet.snet[each.key].id network_security_group_id = azurerm_network_security_group.nsg[each.key].id } # 错误触发的子网资源定义(用户代码中未完整提供,错误指向此处) resource "azurerm_subnet" "snet" { for_each = var.subnets name = lower(format("snet-%s-${var.hub_vnet_name}-${var.location}", each.value.subnet_name)) # 其他子网属性(如virtual_network_id等)需补充 }
variables.tf
variable "subnets" { type = map(object({ name = string })) default = { "s1" = { name = "dns_snet"}, "s2" = { name = "common_snet"}, "s3" = { name = "gw_snet"}, "s4" = { name = "clientdata_snet"} } }
错误信息
Error: Unsupported attribute │ │ on main.tf line 167, in resource "azurerm_subnet" "snet": │ 167: name = lower(format("snet-%s-${var.hub_vnet_name}-${var.location}", each.value.subnet_name)) │ ├──────────────── │ │ each.value is object with 1 attribute "name" │ │ This object does not have an attribute named "subnet_name"
问题分析与解决
核心错误原因
在azurerm_subnet.snet资源中,你引用了each.value.subnet_name,但variables.tf里定义的subnets变量对象仅包含name属性,没有subnet_name,Terraform无法识别该属性导致报错。
修复步骤
- 修正子网名称引用
将子网资源中的each.value.subnet_name改为each.value.name,修正后代码:
resource "azurerm_subnet" "snet" { for_each = var.subnets name = lower(format("snet-%s-${var.hub_vnet_name}-${var.location}", each.value.name)) virtual_network_id = azurerm_virtual_network.your_vnet.id # 补充必填的虚拟网络ID address_prefixes = [each.value.subnet_address_prefix] # 后续需匹配变量定义 }
- 补充NSG依赖的属性
你的NSG资源中还引用了each.value.subnet_address_prefix,但当前变量定义无此属性,后续执行会触发同类错误,需更新variables.tf:
variable "subnets" { type = map(object({ name = string subnet_address_prefix = string # 添加子网地址前缀属性 })) default = { "s1" = { name = "dns_snet", subnet_address_prefix = "10.0.1.0/24"}, "s2" = { name = "common_snet", subnet_address_prefix = "10.0.2.0/24"}, "s3" = { name = "gw_snet", subnet_address_prefix = "10.0.3.0/24"}, "s4" = { name = "clientdata_snet", subnet_address_prefix = "10.0.4.0/24"} } }
内容的提问来源于stack exchange,提问作者asp
相关产品推荐
相关产品推荐

