Провиженеры
Вы можете использовать провиженеры для моделирования определенных действий на локальном или удаленном компьютере, чтобы подготовить серверы или другие объекты инфраструктуры к работе.
Провиженеры — крайняя мера
В 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 к новому серверу и предоставлении учетных данных для удаленного доступа.
Подготовка файлов с помощью cloud-config
Добавьте в конфигурацию OpenTofu источник данных cloudinit_config и укажите файлы, которые нужно подготовить, в виде содержимого 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.
Здесь ссылки на ресурсы ограничены, поскольку они создают зависимости. Ссылка на ресурс по имени внутри его собственного блока привела бы к циклической зависимости.
Скрытие журналов провиженеров в выводе интерфейса командной строки
Конфигурация блока 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"
}
}Поведение при сбое
По умолчанию сбой провиженера приводит к сбою самой операции применения 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.12/language/resources/provisioners/syntax/