【问题标题】:Merging module output map合并模块输出图
【发布时间】:2020-08-12 21:26:45
【问题描述】:

我正在一个模块上尝试新的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"
  }

这里我指定了 ONE 对象的输出,但我想一键动态指定两个对象的输出。

所以我想要这个;

  "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
)
}

对此的任何帮助将不胜感激!

【问题讨论】:

    标签: terraform


    【解决方案1】:

    我不确定我是否正确理解了输入映射,但我尝试复制创建一些模拟变量的问题。

    为此,我创建了以下变量:

    
    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"
    }
    

    【讨论】:

    • 干杯,但问题是你知道你要传入 2 张地图。我可能有一个包含 2、5、10 个项目的对象,我希望它迭代。跨度>
    【解决方案2】:

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

    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 来合并映射列表

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-19
      • 1970-01-01
      • 1970-01-01
      • 2019-04-19
      • 2021-02-24
      • 1970-01-01
      相关资源
      最近更新 更多