терраформирование файла шаблона с помощью для и экранирования последней запятой

#amazon-web-services #templates #terraform #terraform-provider-aws #terraform-template-file

Вопрос:

Я создаю набор стеков AWS (на уровне организации), который написан в облаке. Для формирования облака он записывается в файл шаблона terraform, чтобы переменные передавались из terraform. Однако есть одна часть, с которой у меня возникли проблемы.

В for разделе необходимо просмотреть участников и создать Principal блок в шаблоне. Однако последний индекс цикла содержит запятую, которая сделает шаблон стека недействительным.

Есть ли в terraform способ предотвратить последнюю запятую в цикле?

main.tf:

 variable "cross_account" {
  type = list(object({
    principals  = list(string)
  }))
  default = [
    {
      principals  = ["ACCOUNT_ID1","ACCOUNT_ID2","ACCOUNT_ID3"]
    }
  ]
}
output "test" {
  value = templatefile("./json.tpl", {
    principals = var.cross_account[0].principals
  })
}
 

Файл шаблона (json.tpl):

 "Principal": {
"AWS": [
  %{ for princ in principals ~}
      {
        "Fn::Sub": "arn:aws:iam::${princ}:root"
      }
  , # <--------------- Need to prevent this line on the last loop index
  %{ endfor ~}
]
 

Я сократил код только до тех битов, которые нужны выше. Спасибо

Ответ №1:

Вы можете использовать jsonencode:

 "Principal": {
"AWS": ${jsonencode([
  for princ in principals:
      {
        "Fn::Sub": "arn:aws:iam::${princ}:root"
      }
])}
 

Или вы можете использовать его для всех шаблонов, как показано здесь, в зависимости от того, как именно определен ваш шаблон.

Комментарии:

1. Попытался обновить файл json.tmp и терраформировать его, что не устраивает ${ в файлах шаблонов: Call to function "templatefile" failed: ./json.tpl:9,1-2: Extra characters after interpolation expression; Expected a closing brace to end the interpolation expression, but found extra characters.

2. @TD4091433, пожалуйста, проверьте еще раз. Код работает. Вы либо неправильно его использовали, либо ваш вопрос не соответствует вашему реальному коду.

3. Я пробовал разные варианты, я пытался обновить json.tpl с помощью вашего кода, но, поскольку он не имеет терраформирования, ему не нравится ${ , поэтому вы должны его использовать %{ . Я также попробовал обновление главных.ТФ с ` выходного «тестирования» { значение = templatefile(«./в формате JSON.ТПЛ», { принципалов = jsonencode([ для Пренс в ВАР.cross_account[0].участники: { «ФН::подпункт»: «Арн:АРМ:в IAM::${д}:корневой» } ]) } } « и ее не по нраву "Fn::Sub": . На самом деле это приводит к следующей ошибке: │ A comma is required to separate each function argument from the next.

4. @TD4091433 Извините, не могли бы вы уточнить, что не является терраформом? Также что такое jsonencode([ for princ in var.cross_account[0].principals: ? Это не соответствует вашему вопросу, а это значит, что вы используете другой код, который вы опубликовали.

5. Я изменил этот код только на основе ссылки, которую вы отправили, пытаясь сгенерировать его из шаблона json, пока игнорируйте это. json.tpl это не файл terraform (.tf), это файл шаблона, который загружается из terraform main.tf в этой строке value = templatefile("./json.tpl", . Внесенные вами изменения нарушают работу шаблонов, поскольку ${ они запрещены в этом файле.

Ответ №2:

Поиграв некоторое время с помощью @Marcin, смог получить рабочий код:

main.tf:

 variable "cross_account" {
  type = list(object({
    principals  = list(string)
  }))
  default = [
    {
      principals  = ["ACCOUNT_ID1","ACCOUNT_ID2","ACCOUNT_ID3"]
    }
  ]
}

output "test" {
  value = templatefile("./json.tpl", {
    principals = jsonencode([for i in var.cross_account[0].principals: tomap({"Fn::Sub" = "arn:aws:iam::${i}:root"})])
  })
}
 

Файл шаблона (json.tpl):

 "Principal": {
"AWS":  ${principals}
}
 

приводит к следующему без дополнительной запятой:

 test = <<-EOT
        "Principal": {
        "AWS":  [{"Fn::Sub":"arn:aws:iam::ACCOUNT_ID1:root"},{"Fn::Sub":"arn:aws:iam::ACCOUNT_ID2:root"},{"Fn::Sub":"arn:aws:iam::ACCOUNT_ID3:root"}]
        }
    EOT