Terraform模块创建Azure子网后无法获取资源ID的问题
Terraform获取子网模块ID时的属性错误解决
报错信息
Error: Unsupported attribute │ │ on outputs.tf line 3, in output "one_azure_subnet_id": │ 3: for id in keys(var.subnets) : id => module.Subnet.azure_subnet_id[id] │ ├──────────────── │ │ module.Subnet is object with 3 attributes │ │ This object does not have an attribute named "azure_subnet_id".
场景说明
通过自定义Terraform子网模块批量创建3个子网后,在主项目的输出配置中尝试获取所有子网ID时触发上述错误。
子网模块结构
Subnet/ ┣ main.tf ┣ outputs.tf ┗ variables.tf
子网模块代码
main.tf
resource "azurerm_subnet" "subnet_module" { name = var.subnet_name resource_group_name = var.resource_group_name virtual_network_name = var.vnet_name address_prefixes = var.address_prefixes }
outputs.tf
output "azure_subnet_id" { value = azurerm_subnet.subnet_module[*].id description = "Lists the ID's of the subnets" }
variables.tf
variable "subnet_name" { type = string } variable "address_prefixes" { type = list(string) } variable "resource_group_name" { type = string description = "Resource Group Name" } variable "vnet_name" { type = string description = "vnet name" }
主项目代码
模块调用配置
module "Subnet" { source = "./Modules/Subnet" for_each = var.subnets subnet_name = each.value["name"] address_prefixes = each.value["address_prefixes"] resource_group_name = data.azurerm_resource_group.rg.name vnet_name = azurerm_virtual_network.vnet.name }
子网变量定义
subnets = { subnet_1 = { name = "dev-virtual-subnet" address_prefixes = ["10.13.1.0/24"] } subnet_2 = { name = "test-virtual-subnet" address_prefixes = ["10.13.2.0/24"] } subnet_3 = { name = "staging-virtual-subnet" address_prefixes = ["10.13.3.0/24"] } }
出错的输出配置
output "onefms_azure_subnet_id" { value = { for id in keys(var.subnets) : id => module.Subnet.azure_subnet_id[id] } description = "Lists the ID's of the subnets" }
错误原因及修复方案
错误原因
- 使用
for_each调用模块时,module.Subnet会变成以for_each键为索引的映射对象,而非单个模块实例。直接访问module.Subnet.azure_subnet_id会报错,因为映射对象本身没有该属性,属性属于每个子模块实例。 - 子网模块的输出使用
[*]展开,但该模块每次仅创建单个子网,azurerm_subnet.subnet_module是单个资源而非列表,[*]会生成冗余的单元素列表。
修复步骤
调整子网模块的outputs.tf:
移除不必要的[*],直接输出单个子网ID:output "azure_subnet_id" { value = azurerm_subnet.subnet_module.id description = "The ID of the subnet" }修改主项目的outputs.tf:
遍历module.Subnet映射,直接获取每个实例的输出值:output "onefms_azure_subnet_id" { value = { for k, subnet_module in module.Subnet : k => subnet_module.azure_subnet_id } description = "Lists the ID's of the subnets" }
修改后即可正常生成以subnet_1/subnet_2/subnet_3为键、对应子网ID为值的映射输出。
内容的提问来源于stack exchange,提问作者Jason
相关产品推荐
相关产品推荐

