Провиженеры
Вы можете использовать провиженеры для моделирования определённых действий на локальном или удалённом компьютере, чтобы подготовить серверы или другие объекты инфраструктуры к работе.
Провиженеры — крайняя мера
OpenTofu включает концепцию провиженеров как прагматичное решение, поскольку всегда есть действия, которые невозможно напрямую представить в декларативной модели OpenTofu.
Однако они также значительно усложняют использование OpenTofu и делают его менее предсказуемым. Во-первых, OpenTofu не может включить действия провиженеров в план, поскольку теоретически они могут выполнять любые действия. Во-вторых, для успешного использования провиженеров требуется согласовать гораздо больше деталей, чем обычно необходимо при работе с OpenTofu: прямой сетевой доступ к серверам, передача учётных данных OpenTofu для входа, установка всего необходимого внешнего программного обеспечения и т. д.
В следующих разделах описаны ситуации, которые в принципе можно решить с помощью провиженеров, но для которых доступны и более эффективные решения. Мы не рекомендуем использовать провиженеры ни для одного из описанных далее сценариев.
Даже если ваш конкретный сценарий не описан в следующих разделах, мы всё равно рекомендуем сначала попытаться решить задачу другими способами и использовать провиженеры, только если других вариантов нет.
Передача данных виртуальным машинам и другим вычислительным ресурсам
При развёртывании виртуальных машин и других подобных вычислительных ресурсов нам часто требуется передать сведения о связанной инфраструктуре, необходимые программному обеспечению на сервере для выполнения его задач.
Различные провиженеры, взаимодействующие с удалёнными серверами по SSH или WinRM, потенциально можно использовать для передачи таких данных: для этого нужно войти на сервер и передать данные напрямую. Однако большинство облачных платформ предоставляют механизмы передачи данных экземплярам при их создании, благодаря чему данные доступны сразу после загрузки системы. Например:
- Alibaba Cloud:
user_dataвalicloud_instanceилиalicloud_launch_template. - Amazon EC2:
user_dataилиuser_data_base64вaws_instance,aws_launch_templateиaws_launch_configuration. - Amazon Lightsail:
user_dataвaws_lightsail_instance. - Microsoft Azure:
custom_dataвazurerm_virtual_machineилиazurerm_virtual_machine_scale_set. - Google Cloud Platform:
metadataвgoogle_compute_instanceилиgoogle_compute_instance_group. - Oracle Cloud Infrastructure:
metadataилиextended_metadataвoci_core_instanceилиoci_core_instance_configuration. - VMware vSphere: подключите виртуальный CDROM к
vsphere_virtual_machineс помощью блокаcdrom, содержащего файл с именемuser-data.txt.
Многие официальные образы дисков дистрибутивов Linux включают программное обеспечение cloud-init, которое может автоматически обрабатывать различными способами данные, переданные описанными выше средствами. Это позволяет запускать произвольные сценарии и выполнять базовую настройку системы непосредственно во время загрузки, не подключаясь к компьютеру по SSH.
Если вы создаёте собственные образы машин, то можете использовать «пользовательские данные» или «метаданные», передаваемые описанными выше способами, так, как это подходит вашему приложению. Инструкции по доступу к данным во время выполнения см. в документации поставщика.
Этот подход необходим, если вы планируете использовать механизм автоматического запуска и остановки серверов в группе, предоставляемый вашим облачным провайдером: в этом случае отдельные серверы будут запускаться без участия OpenTofu, и OpenTofu не сможет их настроить.
Даже если вы развёртываете отдельные серверы непосредственно с помощью OpenTofu, передача данных таким способом ускорит загрузку и упростит развёртывание, поскольку не потребуется обеспечивать прямой сетевой доступ от OpenTofu к новому серверу и передавать учётные данные для удалённого доступа.
Подготовка файлов с помощью cloud-config
Добавьте cloudinit_config источник данных в конфигурацию OpenTofu и укажите файлы, которые нужно подготовить, в виде содержимого text/cloud-config. Источник данных cloudinit_config формирует конфигурации MIME с несколькими частями для использования с cloud-init. Передайте файлы в поле content в виде конфигураций, закодированных в YAML, используя блок write_files.
В следующем примере источник данных my_cloud_config задаёт часть MIME типа text/cloud-config с именем cloud.conf. Для поля part.content задано значение yamlencode, которое кодирует JSON-объект write_files в YAML, чтобы система могла подготовить указанные файлы.
data "cloudinit_config" "my_cloud_config" {
gzip = false
base64_encode = false
part {
content_type = "text/cloud-config"
filename = "cloud.conf"
content = yamlencode(
{
"write_files" : [
{
"path" : "/etc/foo.conf",
"content" : "foo contents",
},
{
"path" : "/etc/bar.conf",
"content" : file("bar.conf"),
},
{
"path" : "/etc/baz.conf",
"content" : templatefile("baz.tpl.conf", { SOME_VAR = "qux" }),
},
],
}
)
}
}Запуск программного обеспечения для управления конфигурацией
Для удобства пользователей, которым приходится использовать стандартные образы дистрибутивов операционных систем, OpenTofu включает несколько специализированных провиженеров для запуска определённых продуктов управления конфигурацией.
Мы настоятельно рекомендуем не использовать их, а выполнять настройку системы в процессе создания пользовательского образа. Например, HashiCorp Packer предлагает аналогичный набор провиженеров для управления конфигурацией и может выполнять этапы установки в отдельном процессе сборки — до создания образа системного диска, который можно развернуть многократно.
Если вы используете программное обеспечение для управления конфигурацией с централизованным серверным компонентом, этап регистрации нужно отложить до загрузки конечной системы из пользовательского образа. Для этого воспользуйтесь одним из описанных выше механизмов, чтобы передать необходимые сведения каждому экземпляру. Тогда он сможет зарегистрироваться на сервере управления конфигурацией сразу после загрузки, не принимая команды от OpenTofu по SSH или WinRM.
Возможно, провайдер уже поддерживает нужную функциональность
Технически можно использовать провиженер local-exec для запуска интерфейса командной строки целевой системы, чтобы создавать, обновлять и иным образом взаимодействовать с удалёнными объектами этой системы.
Если вы пытаетесь использовать новую функцию удалённой системы, которая ещё не поддерживается её провайдером, это может быть единственным вариантом. Однако, если провайдер поддерживает нужную вам функцию, отдайте предпочтение функциональности провайдера, а не провиженеру. Так OpenTofu сможет полностью учитывать объект и правильно управлять его дальнейшими изменениями.
Даже если сегодня нужная вам функциональность недоступна в провайдере, мы рекомендуем рассматривать использование local-exec как временное решение, а также создать задачу в репозитории соответствующего провайдера, чтобы обсудить добавление полноценной поддержки. Команды разработчиков провайдеров часто расставляют приоритеты в зависимости от интереса пользователей, поэтому создание задачи поможет сообщить о вашей заинтересованности в этой функции.
Провиженеры используются для запуска сценариев на локальном или удалённом компьютере в рамках создания или уничтожения ресурса. С их помощью можно выполнить начальную настройку ресурса, очистку перед уничтожением, запуск управления конфигурацией и т. д.
Как использовать провиженеры
Используйте провиженеры только в крайнем случае. Для большинства распространённых задач есть более эффективные альтернативы. Дополнительную информацию см. в разделах выше.
Если после изучения рекомендаций в разделах выше вы уверены, что провиженеры — лучший способ решить вашу задачу, добавьте блок provisioner внутрь блока resource вычислительного экземпляра.
resource "aws_instance" "web" {
# ...
provisioner "local-exec" {
command = "echo The server's IP address is ${self.private_ip}"
}
}Провиженер local-exec не требует дополнительной настройки, но большинству других провиженеров необходимо подключаться к удалённой системе по SSH или WinRM. Добавьте блок connection, чтобы OpenTofu знал, как взаимодействовать с сервером.
В OpenTofu есть несколько встроенных провиженеров. Вы также можете использовать сторонние провиженеры в виде плагинов, разместив их в %APPDATA%\terraform.d\plugins, ~/.terraform.d/plugins, $XDG_DATA_HOME/opentofu/plugins или в том же каталоге, где установлен двоичный файл OpenTofu. Однако мы не рекомендуем использовать какие-либо провиженеры, кроме встроенных file, local-exec и remote-exec.
Все провиженеры поддерживают метааргументы when и on_failure, описанные ниже (см. разделы Провиженеры при уничтожении и Поведение при сбоях).
Объект self
Выражения в блоках provisioner не могут ссылаться на родительский ресурс по имени. Вместо этого они могут использовать специальный объект self.
Объект self представляет родительский ресурс провиженера и содержит все атрибуты этого ресурса. Например, используйте self.public_ip, чтобы обратиться к атрибуту public_ip ресурса aws_instance.
Здесь нельзя ссылаться на ресурсы, поскольку ссылки создают зависимости. Ссылка на ресурс по имени внутри его собственного блока привела бы к циклической зависимости.
Скрытие журналов провиженеров в выводе CLI
Конфигурация блока provisioner может содержать чувствительные значения, например чувствительные переменные sensitive или чувствительные выходные значения sensitive. В этом случае весь вывод журнала провиженера автоматически скрывается, чтобы чувствительные значения не отображались.
Провиженеры при создании
По умолчанию провиженеры запускаются при создании ресурса, внутри которого они определены. Провиженеры при создании запускаются только во время создания, но не при обновлении или на других этапах жизненного цикла. Они предназначены для начальной настройки системы.
Если провиженер при создании завершится с ошибкой, ресурс помечается как повреждённый. При следующем tofu apply для повреждённого ресурса будет запланировано уничтожение и повторное создание. OpenTofu делает это потому, что сбой провиженера может оставить ресурс в частично настроенном состоянии. Поскольку OpenTofu не может определить, что именно делает провиженер, единственный способ гарантировать правильное создание ресурса — создать его заново. Это и называется пометкой ресурса как повреждённого.
Это поведение можно изменить, задав атрибут on_failure, который подробно описан ниже.
Провиженеры при уничтожении
Если задано when = destroy, провиженер запускается при уничтожении ресурса, внутри которого он определён.
resource "aws_instance" "web" {
# ...
provisioner "local-exec" {
when = destroy
command = "echo 'Destroy-time provisioner'"
}
}Провиженеры при уничтожении запускаются до уничтожения ресурса. Если они завершатся с ошибкой, OpenTofu сообщит об ошибке и повторно запустит провиженеры при следующем tofu apply. Поэтому провиженеры при уничтожении должны безопасно выполняться несколько раз.
Провиженеры при уничтожении этого ресурса не запускаются, если create_before_destroy задано как true.
Провиженеры при уничтожении могут запускаться, только если они остаются в конфигурации на момент уничтожения ресурса. Если блок ресурса с провиженером при уничтожении полностью удалить из конфигурации, вместе с ним удалится и конфигурация провиженера, поэтому он не запустится. Чтобы обойти это ограничение и безопасно удалить ресурс с провиженером при уничтожении, можно выполнить следующие действия:
- Измените конфигурацию ресурса, добавив
count = 0. - Примените конфигурацию, чтобы уничтожить все существующие экземпляры ресурса, в том числе запустить провиженер при уничтожении.
- Полностью удалите блок ресурса из конфигурации вместе с блоками
provisioner. - Выполните повторное применение. На этом этапе дополнительных действий не потребуется, поскольку ресурсы уже уничтожены.
Из-за этого ограничения используйте провиженеры при уничтожении редко и с осторожностью.
Провиженер при уничтожении ресурса, помеченного как повреждённый, не запустится. Это относится и к ресурсам, помеченным как повреждённые из-за сбоя провиженера при создании, и к ресурсам, помеченным вручную с помощью tofu taint.
Несколько провиженеров
В одном ресурсе можно указать несколько провиженеров. Они выполняются в том порядке, в котором определены в файле конфигурации.
Можно также комбинировать провиженеры для создания и уничтожения. Запускаются только провиженеры, подходящие для текущей операции. Они выполняются в том порядке, в котором определены в файле конфигурации.
Пример использования нескольких провиженеров:
resource "aws_instance" "web" {
# ...
provisioner "local-exec" {
command = "echo first"
}
provisioner "local-exec" {
command = "echo second"
}
}Поведение при сбоях
По умолчанию сбой провиженера приводит к сбою самого выполнения команды apply в OpenTofu. Это поведение можно изменить с помощью параметра on_failure. Допустимые значения:
-
continue— игнорировать ошибку и продолжить создание или уничтожение. -
fail— выдать ошибку и прекратить применение конфигурации (поведение по умолчанию). Если это провиженер при создании, ресурс помечается как повреждённый.
Пример:
resource "aws_instance" "web" {
# ...
provisioner "local-exec" {
command = "echo The server's IP address is ${self.private_ip}"
on_failure = continue
}
}
Copyright (c) The OpenTofu Authors
Copyright (c) 2014 HashiCorp, Inc.
Mozilla Public License, version 2.0
https://opentofu.org/docs/v1.9/language/resources/provisioners/syntax/