Провижионеры
Вы можете использовать провижионеры для моделирования определённых действий на локальном или удалённом компьютере, чтобы подготовить серверы или другие объекты инфраструктуры к работе.
Провижионеры — крайняя мера
В 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.11/language/resources/provisioners/syntax/