Как использовать формат для списка строк в terraform 0.12.20? - PullRequest
0 голосов
/ 21 апреля 2020

Я создаю ресурс данных для создания документа политики, позволяющего пользователям получать доступ к rds, но я застрял в том, как использовать формат для передачи account_id и resource_id rds,

Код:

   data "aws_iam_policy_document" "iam_authentication_doc" {
      depends_on = [aws_db_instance.name]
      statement {
        effect = "Allow"
        actions = [
          "rds-db:connect"
        ]
        resources = flatten([format("arn:aws:rds-db:us-east-1:${var.account_id}:dbuser:${aws_db_instance.name.resource_id}/%s", var.usernames)])
      }
}

Ошибка:

resources = flatten([format("arn:aws:rds-db:us-east-1:${var.account_id}:dbuser:${aws_db_instance.pgauth.resource_id}/%s", var.usernames)])
    |----------------
    | aws_db_instance.pgauth.resource_id is "db-xxxxxxxxxxxxxxxx"
    | var.account_id is 8.12345678901+11
    | var.usernames is list of string with 12 elements

Call to function "format" failed: unsupported value for "%s" at 75: string
required.

Я попытался передать

[formatlist("arn:aws:rds-db:us-east-1:%s:dbuser:%s/%s", var.account_id, aws_db_instance.pgauth.resource_id, var.amp_usernames)] получил ошибку

  22:     resources = [formatlist("arn:aws:rds-db:us-east-1:%s:dbuser:%s/%s", var.account_id, aws_db_instance.name.resource_id, var.usernames)]
    |----------------
    | aws_db_instance.name.resource_id is "db-xxxxxxxxxxxxxxx"
    | var.account_id is "123456789012"
    | var.usernames is list of string with 12 elements

Inappropriate value for attribute "resources": element 0: string required.

Я хочу такие ресурсы, как

arn:aws:rds-db:us-east1:1234567890:dbuser:db-xxxxxxxxxxxxxx/foo, 
arn:aws:rds-db:us-east1:1234567890:dbuser:db-xxxxxxxxxxxxxx/bar, 
arn:aws:rds-db:us-east1:1234567890:dbuser:db-xxxxxxxxxxxxxx/tim

Ответы [ 2 ]

1 голос
/ 21 апреля 2020

Первый пример с format не сработал, потому что format ожидает, что все его аргументы будут единичными значениями, и выдает одно значение.

Как вы видели, функция formatlist Это один из способов решения вашей проблемы: он создает список в качестве своего результата, и если какой-либо из его аргументов является списком, то он повторяет процесс форматирования один раз для каждого набора элементов с одинаковым индексом в списках.

Ваш второй пример не сработал, потому что вы поместили вызов в formatlist в [ ... ], который составляет список. Becuse formatlist возвращает сам список, поэтому результатом был список списков строк, а не просто список строк.

Мы можем заставить его работать, убрав лишние скобки:

  resources = formatlist("arn:aws:rds-db:us-east-1:%s:dbuser:%s/%s", var.account_id, aws_db_instance.name.resource_id, var.usernames)

Еще один способ написать это - использовать выражение for , которое позволит сделать повторение более явным в вашей конфигурации:

  resources = [for u in var.usernames : "arn:aws:rds-db:us-east-1:${var.account_id}:dbuser:${aws_db_instance.name.resource_id}/${u}"]

Какой из них легче понять, так это Конечно, субъективно: подход formatlist показывает строку формата заранее, но подразумевает, что мы повторяем на основе элементов var.usernames. Подход с выражением for выдвигает шаблон к концу строки, но делает повторение на основе var.usernames более явным.

0 голосов
/ 21 апреля 2020
resources = flatten(formatlist("arn:aws:rds-db:us-east-1:%s:dbuser:%s/%s", var.account_id, aws_db_instance.pgauth.resource_id, var.usernames))

Я не указал тип для account_id.

...