我正在模块上试用新的for_each
函数,该模块本身会输出一些需要传递给另一个资源的值。
module "vnets" {
source = "../caf-virtual-network"
for_each = var.vnet_list
ARM_ENVIRONMENT = var.ARM_ENVIRONMENT
ARM_LOCATION = var.ARM_LOCATION
ARM_SUBSCRIPTION_ID = var.ARM_SUBSCRIPTION_ID
diagnostics_map = local.diagnostics_map
location = var.ARM_LOCATION
netwatcher = local.netwatcher
networking_object = each.value
tags = var.global_settings.tags
virtual_network_rg = "${module.names.standard["resource-group"]}-${each.value.vnet.resource_group_name}"
depends_on = [
module.resource_groups_networking
]
}
我可以通过指定类似这样的对象来为一个或多个这些对象获取模块的输出
output "subnets" { value = module.vnets["vnet_shared_services_object"].vnet_subnets }
,它看起来像这样:
"vnet_shared_services_object" = {
"sn-dev-uks-asdf-app-dynamic" = "/subscriptions/asdf/resourceGroups/asdf/providers/Microsoft.Network/virtualNetworks/vnet-dev-uks-asdf-shared-services/subnets/sn-dev-uks-asdf-app-dynamic"
"sn-dev-uks-asdf-artifactory" = "/subscriptions/asdf/resourceGroups/asdf/providers/Microsoft.Network/virtualNetworks/vnet-dev-uks-asdf-shared-services/subnets/sn-dev-uks-asdf-artifactory"
}
在这里,我指定一个对象的输出,但是我想一次点击就动态地指定两个对象的输出。
所以我想要这个;
"vnet_shared_services_object" = {
"sn-dev-uks-asdf-app-dynamic" = "/subscriptions/asdf/resourceGroups/asdf/providers/Microsoft.Network/virtualNetworks/vnet-dev-uks-asdf-shared-services/subnets/sn-dev-uks-asdf-app-dynamic"
"sn-dev-uks-asdf-artifactory" = "/subscriptions/asdf/resourceGroups/asdf/providers/Microsoft.Network/virtualNetworks/vnet-dev-uks-asdf-shared-services/subnets/sn-dev-uks-asdf-artifactory"
}
"vnet_transit_object" = {
"AzureFirewallSubnet" = "/subscriptions/asdf/resourceGroups/qwer/providers/Microsoft.Network/virtualNetworks/vnet-dev-uks-asdf-transit/subnets/AzureFirewallSubnet"
"GatewaySubnet" = "/subscriptions/asdf/resourceGroups/qwer/providers/Microsoft.Network/virtualNetworks/vnet-dev-uks-asdf-transit/subnets/GatewaySubnet"
"sn-dev-uks-asdf-bind-dns" = "/subscriptions/asdf/resourceGroups/qwer/providers/Microsoft.Network/virtualNetworks/vnet-dev-uks-asdf-transit/subnets/sn-dev-uks-asdf-bind-dns"
}
...输出看起来像这样:
subnets = {
"sn-dev-uks-asdf-app-dynamic" = "/subscriptions/asdf/resourceGroups/asdf/providers/Microsoft.Network/virtualNetworks/vnet-dev-uks-asdf-shared-services/subnets/sn-dev-uks-asdf-app-dynamic"
"sn-dev-uks-asdf-artifactory" = "/subscriptions/asdf/resourceGroups/asdf/providers/Microsoft.Network/virtualNetworks/vnet-dev-uks-asdf-shared-services/subnets/sn-dev-uks-asdf-artifactory"
"AzureFirewallSubnet" = "/subscriptions/asdf/resourceGroups/qwer/providers/Microsoft.Network/virtualNetworks/vnet-dev-uks-asdf-transit/subnets/AzureFirewallSubnet"
"GatewaySubnet" = "/subscriptions/asdf/resourceGroups/qwer/providers/Microsoft.Network/virtualNetworks/vnet-dev-uks-asdf-transit/subnets/GatewaySubnet"
"sn-dev-uks-asdf-bind-dns" = "/subscriptions/asdf/resourceGroups/qwer/providers/Microsoft.Network/virtualNetworks/vnet-dev-uks-asdf-transit/subnets/sn-dev-uks-asdf-bind-dns"
}
所以我知道执行以下操作是可行的,但是我要说明的重点是我不知道要生产多少个vnet模块,因此我需要使它动态: >
output merge{
value = merge({
for key, value in module.vnets["vnet_shared_services_object"].vnet_subnets:
key => value
},
{
for key, value in module.vnets["vnet_transit_object"].vnet_subnets:
key => value
})
}
使用Terraform上的指南来使输出对象变平(https://www.terraform.io/docs/configuration/functions/flatten.html),但这并不是我希望的那样:
output stuff {
value = flatten([
for key, value in module.vnets: [
for subnet, id in value.vnet_subnets: {
"${subnet}" = id
}
]
])
}
...等于:
stuff = [
{
"sn-dev-uks-asdf-app-dynamic" = "/subscriptions/asdf/resourceGroups/rg-dev-uks-asdf-vnet-shared-services/providers/Microsoft.Network/virtualNetworks/vnet-dev-uks-asdf-shared-services/subnets/sn-dev-uks-asdf-app-dynamic"
},
{
"sn-dev-uks-asdf-artifactory" = "/subscriptions/asdf/resourceGroups/rg-dev-uks-asdf-vnet-shared-services/providers/Microsoft.Network/virtualNetworks/vnet-dev-uks-asdf-shared-services/subnets/sn-dev-uks-asdf-artifactory"
},
...and so on
]
仅供参考,这对我没有帮助:(
output {
value = merge(
for key, value in module.vnets:
key => value.vnets_subnets
)
}
对此将提供任何帮助!
答案 0 :(得分:0)
我不确定我是否正确理解了输入图,但是我尝试复制创建一些 mock变量的问题。
为此,我创建了以下变量:
variable "vnets" {
default = {
"vnet_shared_services_object" = {
"sn-dev-uks-asdf-app-dynamic" = "/subscriptions/asdf/resourceGroups/asdf/providers/Microsoft.Network/virtualNetworks/vnet-dev-uks-asdf-shared-services/subnets/sn-dev-uks-asdf-app-dynamic"
"sn-dev-uks-asdf-artifactory" = "/subscriptions/asdf/resourceGroups/asdf/providers/Microsoft.Network/virtualNetworks/vnet-dev-uks-asdf-shared-services/subnets/sn-dev-uks-asdf-artifactory"
}
}
}
variable "vnet_subnets" {
default = {
"vnet_transit_object" = {
"AzureFirewallSubnet" = "/subscriptions/asdf/resourceGroups/qwer/providers/Microsoft.Network/virtualNetworks/vnet-dev-uks-asdf-transit/subnets/AzureFirewallSubnet"
"GatewaySubnet" = "/subscriptions/asdf/resourceGroups/qwer/providers/Microsoft.Network/virtualNetworks/vnet-dev-uks-asdf-transit/subnets/GatewaySubnet"
"sn-dev-uks-asdf-bind-dns" = "/subscriptions/asdf/resourceGroups/qwer/providers/Microsoft.Network/virtualNetworks/vnet-dev-uks-asdf-transit/subnets/sn-dev-uks-asdf-bind-dns"
}
}
}
然后将输出视为:
output stuff {
value = {for k,v in flatten([
for key, value in merge(var.vnets, var.vnet_subnets):
[for subkey1, subval1 in value: {"${subkey1}" = subval1}]
]): keys(v)[0] => values(v)[0]}
}
导致:
stuff = {
"AzureFirewallSubnet" = "/subscriptions/asdf/resourceGroups/qwer/providers/Microsoft.Network/virtualNetworks/vnet-dev-uks-asdf-transit/subnets/AzureFirewallSubnet"
"GatewaySubnet" = "/subscriptions/asdf/resourceGroups/qwer/providers/Microsoft.Network/virtualNetworks/vnet-dev-uks-asdf-transit/subnets/GatewaySubnet"
"sn-dev-uks-asdf-app-dynamic" = "/subscriptions/asdf/resourceGroups/asdf/providers/Microsoft.Network/virtualNetworks/vnet-dev-uks-asdf-shared-services/subnets/sn-dev-uks-asdf-app-dynamic"
"sn-dev-uks-asdf-artifactory" = "/subscriptions/asdf/resourceGroups/asdf/providers/Microsoft.Network/virtualNetworks/vnet-dev-uks-asdf-shared-services/subnets/sn-dev-uks-asdf-artifactory"
"sn-dev-uks-asdf-bind-dns" = "/subscriptions/asdf/resourceGroups/qwer/providers/Microsoft.Network/virtualNetworks/vnet-dev-uks-asdf-transit/subnets/sn-dev-uks-asdf-bind-dns"
}
答案 1 :(得分:0)
一位同事可以使用以下代码回答这个问题:
locals {
subnet_list = {
for key, value in module.vnets:
key => value.vnet_subnets
}
subnet_map = merge(values(local.subnet_list)...)
}
这是...
运算符,是这方面的关键。您可以在这里查找; https://www.terraform.io/docs/configuration/expressions.html#expanding-function-arguments
...
将展开项列表以提供功能参数,因此您可以调用merge来合并地图列表