上下文:这是我提出的以下帖子的延续在Terraform 中使用for_each创建多个子网时出现问题
目标:如何使用创建的一个资源的输出值,并将其用于在同一根模块中创建另一个资源
我尝试了什么:
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
}
直到上面的点它的工作,我看到的输出
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"]
}}
]
}
在我的主页中。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
来清理代码,只需从映射中查找值,而不是通过尝试使用if语句在映射上循环来大大简化所有内容:var.vnet_address_space[var.env]
。