Skip to main content

Terraform Provisioners

Imagine you’ve just built a brand‑new house with Terraform. The structure is solid, but it’s empty without furniture, no wiring, no paint. You need a way to run commands inside the house to finish setup.

That’s what provisioners do in Terraform: they let you run scripts or commands on resources after they’re created, bridging the gap between infrastructure provisioning and configuration management.

Provisioners are not meant to replace tools like Ansible, Chef, or Puppet, but they act as a last‑mile helper when you need quick setup tasks directly from Terraform.


Key Concepts

1. What is a Provisioner?

  • A provisioner is a Terraform mechanism to run scripts or commands on a resource after it’s created or destroyed.
  • Types include:
    • local-exec → Runs a command locally on the machine running Terraform.
    • remote-exec → Runs commands on a remote resource via SSH or WinRM.
    • file → Copies files from local to remote resources.

2. Why Use Provisioners?

  • Bootstrapping: Install software or configure a resource immediately after creation.
  • Quick fixes: Run ad‑hoc scripts without a full configuration management tool.
  • Integration: Trigger external processes (e.g., notify CI/CD pipeline).
  • Cleanup: Run commands when destroying resources (e.g. deregister from monitoring).

3. Example Use Cases

  • Install Apache on a new EC2 instance using remote-exec.
  • Copy configuration files to a VM using file.
  • Trigger a shell script locally after infra deployment using local-exec.
  • Run cleanup scripts when destroying resources.

4. Limitations & Cautions

  • Provisioners are not idempotent which means they don’t guarantee repeatable results.
  • Failures can cause Terraform runs to fail unpredictably.
  • Better suited for small tasks, not full configuration management.
  • Use sparingly - prefer dedicated tools (Ansible, Chef, Puppet) for complex setups.

Hands‑On Lab / Demo

Lab: Using a local-exec Provisioner

resource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"

  provisioner "local-exec" {
    command = "echo Instance ${self.id} created >> instances.log"
  }
}
  • After the instance is created, Terraform logs its ID locally.

Lab: Using a remote-exec Provisioner

resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"

  provisioner "remote-exec" {
    inline = [
      "sudo apt-get update",
      "sudo apt-get install -y apache2"
    ]
  }
}
  • Installs Apache on the EC2 instance immediately after creation.

Pro Tips & Best Practices

  • Use provisioners only for tasks that cannot be handled otherwise.
  • Keep scripts simple and idempotent.
  • Always test provisioners in staging before production.
  • Prefer configuration management tools for complex setups.
  • Document why a provisioner is used - future maintainers will thank you.

Summary & Cheatsheet

  • Provisioners = Last‑mile helpers.
  • Types: local-exec, remote-exec, file.
  • Use cases: bootstrapping, quick fixes, integration, cleanup.
  • Limitations: not idempotent, fragile, use sparingly.
Quick mnemonic: Provisioners = Run, Fix, Finish

The Hackers Notebook

Provisioners are the bridge between infrastructure and configuration. They let you run commands or scripts directly from Terraform, making them handy for bootstrapping and quick fixes. But like duct tape, they’re best used sparingly.


Tips, Tricks, Roadmaps, Resources, Networking, Motivation, Guidance, and Cool Stuff ♥

Updated on Dec 31, 2025