首页 > 解决方案 > 如何使用 Terraform 0.11 访问其中包含地图的列表列表?

问题描述

我有几个EKS 节点组。我正在尝试访问autoscaling_groups name所有节点组(例如name = eks-e214c586716a)。在 0.12 中要容易得多,但我们仍在使用 0.11。

[
  [
    {
      "autoscaling_groups" = [
        {
          "name" = "eks-e214c586716a"
        },
      ]
      "remote_access_security_group_id" = "sg-name1"
    },
  ],
  [
    {
      "autoscaling_groups" = [
        {
          "name" = "eks-c866f3f2edb5"
        },
      ]
      "remote_access_security_group_id" = "sg-name2"
    },
  ],
]

这有效:aws_eks_node_group.node-group.resources.0.autoscaling_groups.0.name

但是,当我迭代时,我不成功。

count = "${length(var.nodegroups)}"
autoscaling_group_name    = "${element(aws_eks_node_group.node-group.resources.*.autoscaling_groups.*.name, count.index)}"

标签: amazon-web-servicesterraformterraform-provider-awsterraform0.11

解决方案


看起来您误读了那里的复杂数据结构。

您有一个节点组列表,该列表又包含另一个列表,该列表始终具有一个元素,该元素是具有键autoscaling_groups和的对象remote_access_security_group_id。然后,autoscaling_groups键也是另一个列表,其中一个元素包含带有键的对象name

您这样做的尝试是使用:

"${element(aws_eks_node_group.node-group.resources.*.autoscaling_groups.*.name, count.index)}"

这就是说循环最外面的列表,然后尝试autoscaling_groups从那里的对象获取键,此时它是一个包含 1 个元素的列表。然后,您还尝试遍历其中只有一个元素的最内层列表,因此如果您使用以下内容,您将超过索引:

"${element(aws_eks_node_group.node-group.resources.*.*.autoscaling_groups.*.name, count.index)}"

因为element在尝试访问 1 元素列表的第二个元素时,允许环绕您不会在此处获得超出范围的索引,但是 Terraform 不允许您使用嵌套的 splat 表达式:

Error: Nested splat expression not allowed

  on main.tf line 33, in resource "local_file" "asg_names":
  33:   content  = "${element(local.eks_node_group.*.*.autoscaling_groups.*.name, count.index)}"

A splat expression (*) cannot be used inside another attribute-only splat
expression.

因此,要获取要遍历最外层列表的自动缩放组名称,然后获取该列表的第一个元素,获取autoscaling_groups键,获取该列表的第一个元素,然后最终从name键中获取值。

这是一个访问此数据结构的基本工作示例,使用本地变量作为输入,使用local_file资源作为输出,以允许我们使用以下命令对其进行循环count

locals {
  eks_node_group = [
    [
      {
        "autoscaling_groups" = [
          {
            "name" = "eks-e214c586716a"
          },
        ]
        "remote_access_security_group_id" = "sg-name1"
      },
    ],
    [
      {
        "autoscaling_groups" = [
          {
            "name" = "eks-c866f3f2edb5"
          },
        ]
        "remote_access_security_group_id" = "sg-name2"
      },
    ],
  ]
}

resource "local_file" "asg_names" {
  count    = "${length(local.eks_node_group)}"
  filename = "${count.index}.output"
  content  = "${element(local.eks_node_group.*.0.autoscaling_groups.0.name, count.index)}"
}

运行该计划会显示以下预期输出:

  # local_file.asg_names[0] will be created
  + resource "local_file" "asg_names" {
      + content              = "eks-e214c586716a"
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "0.output"
      + id                   = (known after apply)
    }

  # local_file.asg_names[1] will be created
  + resource "local_file" "asg_names" {
      + content              = "eks-c866f3f2edb5"
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "1.output"
      + id                   = (known after apply)
    }

请注意,除非您想要上述的环绕功能,否则您element应该真正使用更直接的索引语法list[index]

resource "local_file" "asg_names" {
  count    = "${length(local.eks_node_group)}"
  filename = "${count.index}.output"
  content  = "${local.eks_node_group[count.index].0.autoscaling_groups.0.name}"
}

推荐阅读