Можно ли повторно использовать шаблоны Terraform для разных ресурсов, предоставляя разные значения для переменных?

Я использую Terraform для настройки нескольких капель, работающих под управлением Consul на DigitalOcean. Возможно, я упускаю что-то простое, но, кажется, удивительно сложно обеспечить правильную конфигурацию для них.

resource "digitalocean_droplet" "prime" {
  count  = 3
  image  = "${data.digitalocean_image.prime.image}"
  name   = "${format("%s-%02d-%s", "prime", count.index + 1, var.region)}"
  private_networking = true

  # ...
}

У каждой машины есть два сетевых интерфейса - публичный и приватный. При такой настройке кажется необходимым предоставить bind_addr, указывающий на частный IP-адрес каждой капли - в противном случае консул завершает работу с ошибкой, указывающей, что их несколько частные (?!) адреса.

Самым простым решением было бы предоставить каждому компьютеру файл конфигурации, который в каждом случае почти одинаков, но имеет различное значение для bind_addr, вот так:

{
  "server": true,
  "data_dir": "/var/consul/data",
  "ui": true,
  "bind_addr": "${ private_ipv4_address }"
}

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

data "template_file" "consul-config" {
  template = "${file("templates/consul-config.json.tpl")}"

  vars {
    private_ipv4_address = "10.0.0.1" # At this point the real address is not known
  }
}

resource "digitalocean_droplet" "prime" {
  ...

  provisioner "file" {
    content = "${data.template_file.consul-config.rendered}"
    destination = "/etc/consul.d/server.json"

    # At this point the address is known: ${ self.private_ipv4_address },
    # but is it possible to pass it to the template?
  }
}

Я пытался вложить блок данных в блок ресурсов, но затем я получаю такую ​​ошибку:

Error: resource 'digitalocean_droplet.prime' provisioner file (#7): unknown resource 'data.template_file.consul-config' referenced in variable data.template_file.consul-config.rendered

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

resource "digitalocean_droplet" "prime" {
  # ...

  provisioner "file" {
    content = "${data.template_file.consul-config.rendered}"
    destination = "/etc/consul.d/server.json"
  }

  # This is a custom configuration for each particular droplet
  provisioner "file" {
    content = "{ \"bind_addr\": \"${ self.ipv4_address_private }\", \"bootstrap\": ${ count.index == 0 }  }"
    destination = "/etc/consul.d/custom.json"
  }
}

Это работает, но читаемость затруднена по нескольким причинам:

  1. Все кавычки должны быть экранированы

  2. Все должно быть в одной строке (?)

  3. Нет подсветки синтаксиса или аналогичной справки в текстовом редакторе

В качестве альтернативы я рассмотрел возможность использования внешней программы (например, envsubst) для визуализации шаблона или использования встроенный в format функция вместе с файловой функцией , но каждый из них кажется громоздким.

Есть ли прямой способ достичь того, чего я хочу?

4 голоса | спросил Tadeusz Łazurski 23 PMpMon, 23 Apr 2018 17:11:25 +030011Monday 2018, 17:11:25

2 ответа


0
Вы пытались использовать написание модуля?Это может быть хорошей отправной точкой: https://blog.gruntwork.io/how-to-create-reusable-infrastructure-with-terraform-modules-25526d65f73d
ответил Juan Manuel García 24 AMpTue, 24 Apr 2018 05:31:23 +030031Tuesday 2018, 05:31:23
0
Шаблоны предназначены для получения значений от Terraform (будь то из переменных файлов, локальных источников, ресурсов данных и т. Д.) И включения их в шаблонный файл.Как правило, я видел, что полученные файлы представляют собой сценарии, которые будут выполняться вашим возможным ресурсом (экземпляром EC2 для AWS, Droplet для DigitalOcean).Модули (упомянутые в другом ответе) используются для настройки набора ресурсов (скажем, сервера, балансировщика нагрузки, некоторых сетевых ресурсов) с единой точкой входа.Я считаю, что вы правы, что это не относится к вашей ситуации.Я бы выполнил нечто похожее на то, что вы хотите (получить IP-адрес после создания ресурса), - это создать шаблон сценария и передать его вашей капле.Затем попросите этот скрипт спросить у дроплета, какой у него IP.Так что вам нужно определить ресурс user_data в вашей капле:Тогда у вас также есть шаблон данных:который рендерится в скрипт оболочки (или python, perl, что угодно)
ответил Necoras 20 J000000Friday18 2018, 21:42:51

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132