Передача сложных, не примитивных типов данных поставщику шаблонов Terraform - PullRequest
0 голосов
/ 07 февраля 2020

Имея более сложный объект списка, подобный этому

variable "proxy" {
  type = list(object({
    enabled = bool
    host = string
    port = number
    user = string
    password = string
  }))
  default = [
    {
      enabled = false
      host = ""
      port = 0
      user = ""
      password = ""
    }
  ]
}

Я хочу использовать это во внешнем шаблоне (cloudinit в моем случае). Директива template_file позволяет передавать переменные в шаблон. К сожалению, не для более сложных типов:

Обратите внимание, что все переменные должны быть примитивами. Прямые ссылки на списки или карты вызовут ошибку проверки.

Так что-то вроде этого

data "template_file" "cloudinit_data" {
  template = file("cloudinit.cfg")
  vars = {
    proxy = var.proxy
  }
}

приведет к ошибке

Неуместное значение для атрибута "vars": элемент "proxy": обязательная строка.

Это приводит меня к двум вопросам:

  1. Как передать переменную в шаблон? Я предполагаю, что мне нужно преобразовать его в примитивный тип, подобный этому:

    vars = {
        proxy_host = var.proxy.host
    }
    

Это не работает:

Это значение не имеет любые атрибуты.

Есть ли альтернативный способ передать этот объект непосредственно в шаблон?

Я использую v0.12.17.

1 Ответ

0 голосов
/ 11 февраля 2020

Источник данных template_file продолжает существовать только для совместимости с конфигурациями, написанными для Terraform 0.11. Поскольку вы используете Terraform 0.12, вам следует использовать функцию templatefile , которая является встроенной частью языка и поддерживает все типы значений.

Поскольку templatefile функция, вы можете вызывать ее из любого места, где ожидаются выражения. Если вы хотите использовать результат визуализации несколько раз, вы можете определить его как именованное локальное значение , например:

locals {
  cloudinit_data = templatefile("${path.module}/cloudinit.cfg", {
    proxy = var.proxy
  })
}

Если вам нужен только один раз, например , если вы используете его просто для заполнения user_data единственного aws_instance ресурса - тогда вы можете просто написать это выражение встроенным в блоке ресурса, чтобы сохранить все вместе и сделать конфигурацию (субъективно) проще для чтения :

resource "aws_instance" "example" {
  # ...

  user_data = templatefile("${path.module}/cloudinit.cfg", {
    proxy = var.proxy
  })
}
...