【问题标题】:Nested Map data in TerraformTerraform 中的嵌套地图数据
【发布时间】:2021-09-28 17:25:07
【问题描述】:

假设我有一个名为“env”的字符串类型变量(值可以是“dev”或“production”)

通过以下数据,如何获取“dev”或“production”中第一个元素的setting1的值?

locals{
   environments = {
      dev = {
         "hello001" = {
            setting1 = "abc"
            setting2 = "def"
            setting3 = "ghi"
         }
         "hello002" = {
            setting1 = "jkl"
            setting2 = "mno"
            setting3 = "pqr"
         }
      }
      production = {
         "hello003" = {
            setting1 = "abc"
            setting2 = "def"
            setting3 = "ghi"
         }
         "hello004" = {
            setting1 = "jkl"
            setting2 = "mno"
            setting3 = "pqr"
         }
      }
   }
}

我试过了

local.environments[var.env][0].setting1

但收到错误“此值没有任何索引”

【问题讨论】:

  • 如果键对于特定的环境映射无关紧要,那么您可以将它们转换为列表。本质上,您可以将其从 map(map(map(object(...string...))) 转换为 map(map(list(object(...string...))) 吗?

标签: terraform


【解决方案1】:

首先我得到的错误信息略有不同:

│ Error: Invalid index
[...]
│ The given key does not identify an element in this collection value. An object only supports looking up attributes by name, not by numeric index.

但我猜这是因为 Terraform 版本不同。我有 1.0.7。

解释/上下文

不过,问题与mentioned by Matt in the comment 完全相同——Terraform HCL 中的地图不支持整数索引。 IE。你不能在地图上做[0]。一些编程语言提供了这种可能性,而 Terraform 没有。

见:

locals {
 my_dictionary = {
   "one" = 1
   "two" = 2
 }
}

如果我尝试local.someMapping[0],它会失败并出现同样的错误。

出路

这取决于您希望如何访问您的 hello001、hello002s 等。

要么将最内部的地图更改为列表,例如

locals{
   environments = {
      dev = [
         {
            setting1 = "abc"
            setting2 = "def"
            setting3 = "ghi"
         },
         {
            setting1 = "jkl"
            setting2 = "mno"
            setting3 = "pqr"
         }
      ]
      production = [
         {
            setting1 = "abc"
            setting2 = "def"
            setting3 = "ghi"
         },
         {
            setting1 = "jkl"
            setting2 = "mno"
            setting3 = "pqr"
         }
      ]
   }
}

然后你可以local.environments["dev"][0].setting1

... 或坚持使用地图,但是您需要以某种方式迭代地图,例如使用for_each为每个hello00x定义一个资源:

locals{
   environments = {
      dev = {
         "hello001" = {
            setting1 = "ami-0c55b159cbfafe1f0"
            setting2 = "t3.micro"
         }
         "hello002" = {
            setting1 = "ami-01d7c2b5c4fc0218a"
            setting2 = "m4.large"
         }
      }
   }
}

resource "aws_instance" "my_server" {
 for_each = local.environments["dev"]
 
 ami = each.value.setting1
 instance_type = each.value.setting2

 tags = {
  Name = each.key
 }
}

在这里,我为两个 hello 中的每一个定义了一个 aws_instance

【讨论】:

    猜你喜欢
    • 2021-06-01
    • 2020-12-09
    • 2020-09-25
    • 2021-09-15
    • 2021-07-04
    • 2021-06-29
    • 2022-11-09
    • 2021-09-08
    • 1970-01-01
    相关资源
    最近更新 更多