首页 > 解决方案 > 如何在嵌套地图上按循环创建集合

问题描述

我有一张地图,我想在当地人中阅读并从中生成一张新地图。新地图中的一个字段将是一组包含来自嵌套数据结构的值。我无法弄清楚执行此操作的语法。

//I want to generate a set of all zones from the nested zone fields
variable "my_var" {
  type = object({
    name = string
    google_bigtable_clusters    = any
  })
  default = {
    app_name = "sdfsdfds"
    instances = {
      instance01 = [
        {
          zone = "asia-east1-a"
          num_nodes = 1
        },
        {
          zone = "asia-east1-b"
          num_nodes = 1
        },
        {
          zone = "asia-east1-c"
          num_nodes = 1
        },
        {
          zone = "asia-east2-a"
          num_nodes = 1
        },
      ],
      instance02 = [
        {
          zone = "europe-west2-a"
          num_nodes = 1
        },
        {
          zone = "europe-west2-b"
          num_nodes = 1
        },
        {
          zone = "europe-west2-c"
          num_nodes = 1
        },
        {
          zone = "europe-west3-a"
          num_nodes = 1
        },
      ]
    }
  }
}

这抛出The key expression produced an invalid result: string required.

// locals
new_map = {
    some_field = "arbitrary string"
    set_of_zones = {
        for item in var.my_var.instances : item => {
          for subitem in item : subitem.zone => {
            zone = subitem.zone
          }
        }
    }
}

我也尝试获取密钥名称,但没有奏效:for item in var.my_var.instances : item.key => {

编辑

我能够做到这一点,但我不明白为什么我无法访问此处的密钥名称。我想在这里使用instance01, instance02, etc 键名:for item in var.my_var.instances : item[0].zone => {.

标签: terraform

解决方案


首先,你type的变量都搞砸了。你有:

type = object({
  name = string
  google_bigtable_clusters    = any
})

这意味着只有当 Terraform 具有以下两个字段时,Terraform 才会接受变量的值:(name字符串)和google_bigtable_clusters(可以是任何东西)。

您的默认值没有这些字段。相反,它只包含app_nameand instances,因此这可能是第一个问题的原因。

关于为什么您不能在for循环中访问键名,您需要同时指定键和值:

set_of_zones = {
  for key, val in var.my_var.instances : 
    key => {
      for subval in val: 
        subval.zone => {
          zone = subval.zone
        }
    }
}

这是一件非常奇怪的事情,因为你最终会得到一张看起来像这样的地图:

set_of_zones = {
  instance01 = {
    "asia-east1-a" => {
      zone = "asia-east1-a"
    }
  }
}

这似乎不是很有帮助,因为每个映射中只有一个属性,并且该属性的值与该映射的键相同。


推荐阅读