🏗️ Provisioners & null_resource
local-exec, remote-exec, file provisioner, terraform_data
⚠️ Что такое Provisioner и когда его использовать?
Provisioner — выполнение команды/скрипта после создания (или удаления) ресурса. Противоречит идеологии Terraform: при сбое ресурс переходит в состояние "tainted". Используется только когда нет другого решения. Cloud-init, user_data — предпочтительная альтернатива.
💻 local-exec & remote-exec
local-exec: выполняет команду на машине, где запущен Terraform (AWS CLI, trigger скрипта). remote-exec: выполняет команду внутри ресурса (на EC2 через SSH/WinRM). Требуется блок
connection: host, user, private_key.📁 file Provisioner
Копирование файла с локальной машины на удалённую. Через SSH или WinRM. `source` (локальный путь) → `destination` (удалённый путь). Обычно используется вместе с `remote-exec`: загрузка файла + выполнение.
🔧 null_resource & terraform_data
null_resource — не создаёт никакого реального ресурса, используется только для provisioner или trigger. `triggers` map — определяет, когда запускать повторно. terraform_data (Terraform 1.4+) — замена null_resource, не требует отдельного native provider.
💡 Ключевые моменты
- Provisioner = крайняя мера, избегайте если возможно
- local-exec: локальная машина. remote-exec: удалённая VM
- null_resource: нет реальной инфраструктуры, только для provisioner
- terraform_data: замена null_resource (1.4+)
- Сбой: ресурс tainted → пересоздаётся
📋 Пример кода
# local-exec: resurs yaratilgandan keyin lokal script
resource "aws_instance" "web" {
ami = "ami-0abcdef1234567890"
instance_type = "t3.micro"
provisioner "local-exec" {
command = "echo ${self.public_ip} >> inventory.txt"
}
}
# null_resource: haqiqiy infra yaratmasdan trigger
resource "null_resource" "run_ansible" {
triggers = {
instance_id = aws_instance.web.id
}
provisioner "local-exec" {
command = "ansible-playbook -i ${aws_instance.web.public_ip}, playbook.yml"
}
}
# terraform_data (Terraform 1.4+)
resource "terraform_data" "bootstrap" {
triggers_replace = [aws_instance.web.id]
provisioner "local-exec" {
command = "bash setup.sh ${aws_instance.web.public_ip}"
}
}
🎯 Советы для экзамена
- При сбое provisioner ресурс становится "tainted" — в следующем plan выполнится destroy+recreate
- user_data (скрипт начальной загрузки EC2) — предпочтительнее provisioner и является декларативным
- local-exec: для вызова API, запуска Ansible playbook
- null_resource triggers: повторный запуск при изменении map
- Terraform 1.4+: `terraform_data` не зависит от провайдера hashicorp/null
⚠️ Частые ошибки
- Считать Provisioner нормальным паттерном IaC — это антипаттерн Terraform, только последнее средство
- Забывать блок connection для remote-exec — ожидать, что SSH credentials будут подхвачены автоматически
- Не учитывать, что provisioner не перезапустится, если triggers в null_resource не изменились
🧠 Для запоминания: "Provisioner = Пластырь" — временное решение проблемы, но для лечения раны лучше хирургия (cloud-init, user_data)
Проверьте себя по теме «Provisioners & null_resource»
Бесплатные интерактивные тесты, пробный экзамен и полные уроки — на платформе CertMaster.
Начать бесплатно →