如何从for_each创建的Terraform子网中获取subnet_id并关联NSG
解决Terraform中for_each创建子网后关联NSG的引用错误及结构查看
一、错误原因
each.value cannot be used in this context的核心问题是:each变量仅在定义了for_each的资源/模块块内部有效,关联NSG的资源不在子网创建的for_each块中,因此无法直接调用each.value。
二、正确引用指定子网ID关联NSG
结合你的配置场景,给出具体实现步骤:
1. 本地筛选当前环境子网的示例(对应你的local配置)
locals { # 从tfvars中提取当前环境的子网列表,假设var.subnets是按Dev/Stage/Prod分组的结构 current_env_subnets = var.subnets[var.environment] }
2. 用for_each创建子网的资源定义
这里将子网名称作为for_each的键,方便后续精准索引:
resource "azurerm_subnet" "this" { for_each = { for subnet in local.current_env_subnets : subnet.name => subnet } name = each.value.name resource_group_name = azurerm_resource_group.this.name virtual_network_name = azurerm_virtual_network.this.name address_prefixes = each.value.address_prefixes }
3. 关联NSG到目标子网(如ClientDataSubnet)
直接通过子网资源的键名引用目标子网ID,无需使用each:
resource "azurerm_subnet_network_security_group_association" "client_data_nsg_link" { subnet_id = azurerm_subnet.this["ClientDataSubnet"].id network_security_group_id = azurerm_network_security_group.client_data.id }
如果你的for_each用了自定义键而非子网名称,只需把["ClientDataSubnet"]替换成目标子网对应的键即可。
三、查看for_each创建的子网信息存储结构
有两种实用方式:
- 方式1:用terraform console交互式查看
执行命令进入交互环境:
terraform console
输入资源名称即可查看完整的映射结构:
azurerm_subnet.this
输出示例(简化版):
{ "ClientDataSubnet" = { "address_prefixes" = ["10.0.1.0/24"] "id" = "/subscriptions/xxx/resourceGroups/rg/providers/Microsoft.Network/virtualNetworks/vnet/subnets/ClientDataSubnet" # 其他子网属性... } "ManagementSubnet" = { # 另一个子网的属性 } }
- 方式2:用terraform state show查看状态
查看所有子网的状态:
terraform state show azurerm_subnet.this
查看单个特定子网的状态:
terraform state show 'azurerm_subnet.this["ClientDataSubnet"]'
内容的提问来源于stack exchange,提问作者asp
相关产品推荐
相关产品推荐

