principlebashterraformMajor
Avoid Terraform provisioners: use cloud-init or baked AMIs instead
Viewed 0 times
provisionersremote-execlocal-execcloud-inituser_datapackerimmutable infrastructuretainted resource
Error Messages
Problem
Terraform provisioners (
remote-exec, local-exec, file) are used to run scripts on resources after creation. They are fragile: they run only once, failures leave resources in a tainted state, they require SSH/WinRM access from the Terraform runner, and they introduce imperative steps in a declarative workflow.Solution
Prefer immutable approaches: bake configuration into AMIs with Packer, or use cloud-init user data for first-boot configuration. Use
local-exec only for rare post-deployment integrations that have no Terraform resource equivalent.# Prefer: cloud-init user_data
resource "aws_instance" "web" {
ami = data.aws_ami.base.id
instance_type = "t3.micro"
user_data = base64encode(templatefile("${path.module}/cloud-init.yaml", {
app_version = var.app_version
}))
# Do NOT do this:
# provisioner "remote-exec" {
# inline = ["apt-get install -y nginx"]
# }
}Why
Provisioners break the Terraform model — they are not idempotent, not visible in
terraform plan, and not retryable without destroying and recreating the resource. They couple Terraform's lifecycle to runtime SSH access.Gotchas
- A failed provisioner taints the resource — subsequent plans will destroy and recreate it
local-execprovisioners run on the machine executing Terraform, not on the remote resourcedestroyprovisioners run before the resource is destroyed and can prevent the destroy if they fail- null_resource with local-exec is a common workaround for running scripts but still suffers the same fragility
Context
Bootstrapping EC2 instances or other compute resources with initial configuration
Revisions (0)
No revisions yet.