合并模块输出图

问题描述

我正在模块上试用新的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
)
}

对此将提供任何帮助!

解决方法

我不确定我是否正确理解了输入图,但是我尝试复制创建一些 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"
}
,

一位同事可以使用以下代码回答这个问题:

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来合并地图列表

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...