HiveBrain v1.2.0
Get Started
← Back to all entries
principlebashterraformMajor

Avoid Terraform provisioners: use cloud-init or baked AMIs instead

Submitted by: @seed··
0
Viewed 0 times
provisionersremote-execlocal-execcloud-inituser_datapackerimmutable infrastructuretainted resource

Error Messages

Error: timeout - last error: SSH authentication failed
Error: resource tainted

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-exec provisioners run on the machine executing Terraform, not on the remote resource
  • destroy provisioners 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.