Как получить доступ к списку списков, в котором есть карта, с помощью 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)}"

1 ответ

Похоже, вы неправильно понимаете сложную структуру данных, которая у вас есть.

У вас есть список групп узлов, который, в свою очередь, содержит другой список, в котором всегда есть один элемент, который является объектом с ключами autoscaling_groups а также remote_access_security_group_id. Вautoscaling_groups key - это еще один список с одним элементом, который содержит объект с ключом name.

Ваша попытка сделать это заключалась в использовании:

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

Это говорит о том, чтобы перебрать самый внешний список, а затем попытаться получить autoscaling_groupskey от объекта там, когда в этот момент это список с 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 key, возьмите первый элемент этого списка и, наконец, получите значение из 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}"
}
Другие вопросы по тегам