Terraform 中的嵌套地图数据

sag*_*age 2 terraform

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

使用以下数据,如何获取“dev”或“product”中第一个元素的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"
         }
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

我尝试过

local.environments[var.env][0].setting1
Run Code Online (Sandbox Code Playgroud)

但出现错误“该值没有任何索引”

Grz*_*zki 5

首先,我收到的错误消息略有不同:

\n
\xe2\x94\x82 Error: Invalid index\n[...]\n\xe2\x94\x82 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.\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

解释/上下文

\n

尽管如此,问题正如Matt 在评论中提到的那样- Terraform HCL 中的地图不支持整数索引。[0]即你不能在地图上做。某些编程语言提供了这种可能性,而 Terraform 则不提供。

\n

看:

\n
locals {\n my_dictionary = {\n   "one" = 1\n   "two" = 2\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

出路

\n

这取决于您想要如何访问 hello001、hello002 等。

\n

要么将最里面的地图更改为列表,例如

\n
locals{\n   environments = {\n      dev = [\n         {\n            setting1 = "abc"\n            setting2 = "def"\n            setting3 = "ghi"\n         },\n         {\n            setting1 = "jkl"\n            setting2 = "mno"\n            setting3 = "pqr"\n         }\n      ]\n      production = [\n         {\n            setting1 = "abc"\n            setting2 = "def"\n            setting3 = "ghi"\n         },\n         {\n            setting1 = "jkl"\n            setting2 = "mno"\n            setting3 = "pqr"\n         }\n      ]\n   }\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

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

\n
locals{\n   environments = {\n      dev = {\n         "hello001" = {\n            setting1 = "ami-0c55b159cbfafe1f0"\n            setting2 = "t3.micro"\n         }\n         "hello002" = {\n            setting1 = "ami-01d7c2b5c4fc0218a"\n            setting2 = "m4.large"\n         }\n      }\n   }\n}\n\nresource "aws_instance" "my_server" {\n for_each = local.environments["dev"]\n \n ami = each.value.setting1\n instance_type = each.value.setting2\n\n tags = {\n  Name = each.key\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

aws_instance这里我为两个问候分别定义了一个。

\n