上下文:这是我提出的以下帖子的延续 Issue while creating multiple subnets using for_each in Terraform
目标:如何使用所创建的一个资源的输出值,并将其用于在同一根模块中创建另一个资源
我尝试过的:
resource "azurerm_virtual_network" "vnet" {
name = var.hub_vnet_name
location = azurerm_resource_group.rg[0].location
resource_group_name = azurerm_resource_group.rg[0].name
for_each = {for k,v in var.vnet_address_space: k=>v if k == "${var.env}"}
address_space = each.value
dns_servers = var.dns_servers
tags = {
environment = "${var.env}"
costcentre = "14500"
}
dynamic "ddos_protection_plan" {
for_each = local.if_ddos_enabled
content {
id = azurerm_network_ddos_protection_plan.ddos[0].id
enable = false
}
}
}
output "azurerm_vnets_names" {
value = values(azurerm_virtual_network.vnet)[*].name
}
到目前为止,它正在工作,我看到了 as 的输出
Outputs:
azurerm_vnets_names = [
"vnet-hub",
]
现在,下一步我尝试在循环中创建子网,如下所示
tfvars.json:
"subnets" : {
"Dev" :
[
{"gw_snet":{
"name" : "GatewaySubnet",
"address_prefixes" : ["10.1.1.0/24"]
},
"dns-snet" : {
"name" : "InboundDNSSubnet",
"address_prefixes" : ["10.1.2.0/24"]
},
"common_snet" : {
"name" : "Common",
"address_prefixes" : ["10.1.3.0/24"]
},
"clientdata_snet" : {
"name" : "ClientDataSubnet",
"address_prefixes" : ["10.1.4.0/20"]
}}
],
"Stage" :
[
{"gw_snet":{
"name" : "GatewaySubnet",
"address_prefixes" : ["10.2.1.0/24"]
},
"dns-snet" : {
"name" : "InboundDNSSubnet",
"address_prefixes" : ["10.2.2.0/24"]
},
"common_snet" : {
"name" : "Common",
"address_prefixes" : ["10.2.3.0/24"]
},
"clientdata_snet" : {
"name" : "ClientDataSubnet",
"address_prefixes" : ["10.2.4.0/20"]
}}
],
"Prod" :
[
{"gw_snet":{
"name" : "GatewaySubnet",
"address_prefixes" : ["10.3.1.0/24"]
},
"dns-snet" : {
"name" : "InboundDNSSubnet",
"address_prefixes" : ["10.3.2.0/24"]
},
"common_snet" : {
"name" : "Common",
"address_prefixes" : ["10.3.3.0/24"]
},
"clientdata_snet" : {
"name" : "ClientDataSubnet",
"address_prefixes" : ["10.3.4.0/20"]
}}
]
}
在我的 main.tf 中:
locals {
net_subnets = merge([
for env, network in var.subnets : {
for k, v in network[0] :
"${k}-${v.name}" => {
subnet_name = v.name
address_prefixes = v.address_prefixes
} if env == "Dev"
}]...)
}
#Creating subnets
resource "azurerm_subnet" "mysubnet" {
for_each = local.net_subnets
name = each.value.subnet_name
address_prefixes = each.value.address_prefixes
virtual_network_name = azurerm_virtual_nework.vnet.name
resource_group_name = var.resource_group_name
}
现在下面的行出错了
virtual_network_name = azurerm_virtual_nework.vnet.name
说“因为我在创建 vnet 时使用了 for_each
,所以我无法使用上面的方式
现在,由于我看到上面定义的输出变量是 azurerm_vnets_names
,我尝试将其引用如下
virtual_network_name = azurerm_vnets_names
没用
然后
我尝试添加数据源
data "azurerm_virtual_network" "vnet" {
name = "vnet-hub"
resource_group_name = "hub"
}
然后尝试以下:
virtual_network_name = data.azurerm_virtual_nework.vnet.name
再次错误表明......它没有声明。
我也尝试了下面的一个,但没有成功
virtual_network_name = azurerm_virtual_network.vnet[*].name
请帮助我确定问题。
最佳答案
这是错误的,因为 azurerm_virtual_nework.vnet
是一个集合,而不是单个值。您使用 for_each
创建了 azurerm_virtual_nework.vnet
,因此 Terraform 认为可能有多个 azurerm_virtual_nework.vnet
资源,而您却没有告诉它使用哪一个。如果您查看 Terraform 给您的错误消息,这一点应该很清楚。
virtual_network_name = azurerm_virtual_nework.vnet.name
<小时/>
这是无效的 Terraform 语法:
virtual_network_name = azurerm_vnets_names
输出只能由父模块引用。在根模块中,输出仅用于将内容输出到 terraform apply
运行的输出日志。您无需声明输出以在声明它们的同一模块中使用。
解决方法是从 azurerm_virtual_nework.vnet
集中实际提取所需的值:
virtual_network_name = azurerm_virtual_nework.vnet[var.env].name
尽管如此,我认为您可以通过在 azurerm_virtual_nework.vnet
资源中根本不使用 for_each
来进一步清理代码,而只需从您的 map ,而不是通过尝试使用 if 语句循环 map 来使一切变得过于复杂:var.vnet_address_space[var.env]
。
关于azure - 如何使用同一根模块中的输出值来创建另一个资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73360687/