Как создать файл с террафом и включить переменную как литерал? - PullRequest
1 голос
/ 19 сентября 2019

Используя terraform v0.12.9 и создавая файл с использованием источника данных template_file, я не мог использовать двойные знаки доллара $$ для обработки ввода $ {data_directory} как литералов.

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

Я пытался использовать двойной знак доллара (например,в приведенном ниже примере кода) для выделения этого $ {data_directory} в качестве литералов в выходном файле.

Вот код, который я пытаюсь использовать для создания файла postfix main.cfс помощью terraform:

variable "hostname" {
  default = "test"
}

variable "domain_name" {
  default = "test.com"
}

variable "fn_main_cf" {
  default = "main.cf"
}

data "template_file" "main_cf" {
  template = <<EOF
##
## Network settings
##
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
inet_interfaces = 127.0.0.1, ::1, 120.121.123.124, 2a03:b0a0:3:d0::5e79:4001
myhostname = ${var.hostname}.${var.domain_name}

###
### Outbound SMTP connections (Postfix as sender)
###
smtp_tls_session_cache_database = btree:$${data_directory}/smtp_scache
EOF
}

  data "template_cloudinit_config" "main_cf" {
    gzip          = false
    base64_encode = false

    part {
      filename     = "${var.fn_main_cf}"
      content_type = "text/cloud-config"
      content      = "${data.template_file.main_cf.rendered}"
    }
  }

  resource "null_resource" "main_cf" {
    triggers = {
      template = "${data.template_file.main_cf.rendered}"
    }

    provisioner "local-exec" {
      command = "echo \"${data.template_file.main_cf.rendered}\" > ~/projects/mail-server/files/etc/postfix/${var.fn_main_cf}"
    }

}

Как вы можете видеть, существует множество переменных, и все это работает нормально, но $ {data_directory} следует рассматривать не как переменную, а как литералы, и она должна оставаться такой, как есть.в файле вывода на диске.

Ожидаемый вывод в файле main.cf , сохраненном на диске, должен выглядеть следующим образом:

##
## Network settings
##
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
inet_interfaces = 127.0.0.1, ::1, 120.121.123.124, 2a03:b0a0:3:d0::5e79:4001 
myhostname = test.test.com

###
### Outbound SMTP connections (Postfix as sender)
###
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

Итак $ {data_directory} долженне обрабатывается terraform как переменная terraform, а просто как группа символов, литералов (обычный ввод текста).

Выполнение план terraform вывод с двойными знаками доллара $$ выглядит следующим образом:

Error: failed to render : <template_file>:11,43-57: Unknown variable; There is no variable named "data_directory".

1 Ответ

1 голос
/ 19 сентября 2019

template_file остается доступным в Terraform в основном для пользователей Terraform 0.11.В Terraform 0.12 нет необходимости использовать template_file, поскольку он был заменен двумя другими функциями:

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

Ресурс local_file также является лучшим способом создания локального файла на диске, чем использование поставщика local-exec,Используя template_file и local-exec, вы вынуждены бороться с двумя уровнями дополнительного экранирования: экранирование шаблона Terraform для получения литерального шаблона в источник данных template_file, а затем экранирование оболочки внутри вашего провайдера.

Вот более прямой способ представления вашего шаблона и вашего файла:

variable "postfix_config_path" {
  # Note that for my example this is expected to be the full path
  # to the file, not just the filename. Terraform idiom is to be
  # explicit about this sort of thing, rather than relying on
  # environment variables like HOME.
  type = string
}

locals {
  postfix_config = <<-EOT
    ##
    ## Network settings
    ##
    mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
    inet_interfaces = 127.0.0.1, ::1, 120.121.123.124, 2a03:b0a0:3:d0::5e79:4001
    myhostname = ${var.hostname}.${var.domain_name}

    ###
    ### Outbound SMTP connections (Postfix as sender)
    ###
    smtp_tls_session_cache_database = btree:$${data_directory}/smtp_scache
  EOT
}

resource "local_file" "postfix_config" {
  filename = var.postfix_config_path
  content  = local.postfix_config
}

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

Обратите внимание, что более стандартная схема использования Terraform будетдля Terraform, которая будет использоваться для запуска новой виртуальной машины, которая будет запускать Postfix и передавать необходимую конфигурацию через специфический для поставщика аргумент user_data или metadata.

Если сервер postfix управляется отдельно отэта конфигурация Terraform, а затем альтернативный шаблон состоит в том, чтобы Terraform записывал необходимые данные в общее хранилище конфигурации (например, хранилище параметров AWS SSM или HashiCorp Consul), а затем использовал отдельное программное обеспечение на постфиксном сервере, чтобы прочитать это и обновить main.cf файл.Для HashiCorp Consul это отдельное программное обеспечение может быть consul-template .Аналогичное программное обеспечение существует для других хранилищ параметров, что позволяет вам отделить конфигурацию отдельных виртуальных машин от конфигурации вашей общей инфраструктуры.

...