Терраформ 0.12 вложенный в петли - PullRequest
1 голос
/ 08 мая 2019

Я пытаюсь реализовать вложенные циклы, используя новые функции Terraform 0.12, чтобы проходить через пользователей AWS IAM, к каждому из которых может быть прикреплена одна или несколько политик. Переменная, используемая для представления этого списка, имеет тип карты (список (строка)) и выглядит примерно так:

{
  "user 1" = [ "policy1", "policy2" ],
  "user 2" = [ "policy1" ]
}

Получение списка пользователей для создания достаточно просто с помощью keys(), но поскольку в настоящее время в Terraform отсутствует механизм для создания вложенных циклических ресурсов, вложения политики должны выполняться в виде отдельного цикла, независимого от каждого пользователя. Итак, я пытаюсь составить список связей пользователя и политики из входных данных карты, которые будут выглядеть примерно так на основе приведенного выше примера:

[
  [ "user1", "policy1" ],
  [ "user1", "policy2" ],
  [ "user2", "policy1" ]
]

Я пытаюсь создать этот список и сохранить его в локальной переменной, например, где var.iam-user-policy-map - карта ввода:

locals {
  ...
  association-list = [
    for user in keys(var.iam-user-policy-map):
    [
      for policy in var.iam-user-policy-map[user]:
      [user, policy]
    ]
  ]
  ...
}

Однако я получаю ошибки при попытке получить доступ к значениям в этом вложенном списке. Я пытаюсь получить доступ к пользовательской части ассоциации со ссылкой local.association-list[count.index][0] и политике с local.association-list[count.index][1], но при запуске terraform plan выдает ошибку:

Error: Incorrect attribute value type

  on main.tf line 27, in resource "aws_iam_user_policy_attachment" "test-attach":
  27:   user = local.association-list[count.index][0]

Inappropriate value for attribute "user": string required.


Error: Incorrect attribute value type

  on main.tf line 27, in resource "aws_iam_user_policy_attachment" "test-attach":
  27:   user = local.association-list[count.index][0]

Inappropriate value for attribute "user": string required.


Error: Invalid index

  on main.tf line 28, in resource "aws_iam_user_policy_attachment" "test-attach":
  28:   policy_arn = "arn:aws-us-gov:iam::aws:policy/${local.association-list[count.index][1]}"
    |----------------
    | count.index is 0
    | local.association-list is tuple with 2 elements

The given key does not identify an element in this collection value.


Error: Invalid template interpolation value

  on main.tf line 28, in resource "aws_iam_user_policy_attachment" "test-attach":
  28:   policy_arn = "arn:aws-us-gov:iam::aws:policy/${local.association-list[count.index][1]}"
    |----------------
    | count.index is 1
    | local.association-list is tuple with 2 elements

Cannot include the given value in a string template: string required.

Что я делаю не так?

1 Ответ

2 голосов
/ 09 мая 2019

Выражение for в вашем локальном значении association-list создает список списков строк, но ваши ссылки на него обрабатывают его как список списков строк.

Чтобы получить сглаженное представление, которое вы хотели, вы можете использовать функцию flatten, но, поскольку в противном случае она сгруппировала бы все в плоский список single , я бы рекомендовал вместо этого сделать внутреннее значение объектом. (Это также сделает ссылки на него более понятными.)

locals {
  association-list = flatten([
    for user in keys(var.iam-user-policy-map) : [
      for policy in var.iam-user-policy-map[user] : {
        user   = user
        policy = policy
      }
    ]
  ])
}

Результат этого выражения будет иметь следующую форму:

[
  { user = "user1", policy = "policy1" },
  { user = "user1", policy = "policy2" },
  { user = "user2", policy = "policy2" },
]

Ваши ссылки на него могут быть в следующем виде:

user = local.association-list[count.index].user
policy_arn = "arn:aws-us-gov:iam::aws:policy/${local.association-list[count.index].policy}"
...