liveBook · Manning

Provisioner

As explained in Terraform in Depth: Infrastructure as Code with Terraform and OpenTofu

A Terraform provisioner is a feature that executes custom code locally or on a separate machine, typically to configure infrastructure after creation.

Suppose an instance needs a command Terraform cannot express through its resource configuration. A provisioner can run a command or create files locally or on another machine when Terraform creates or destroys a resource. Use one only when a better option is unavailable: provisioners add failure points, deployment time, and behavior that can be difficult to debug. section 10.3

Choose where the command runs:

  • remote-exec runs on another machine and requires a connection. Use inline commands, one script, or an ordered list of scripts; each provisioner block selects only one form. section 10.3.2
  • local-exec runs where Terraform runs, needs no connection, and accepts a command that can itself launch a script. section 10.3.2

Configure an instance over SSH

An aws_instance can use a connection block with type = "ssh", user = "ubuntu", and host = self.public_ip. Its remote-exec provisioner can then install nginx with inline commands or upload and run a script. A resource-level connection applies to its provisioners; a provisioner can instead define its own. Keep private SSH keys out of committed code. section 10.3.1 section 10.3.2

Listing 10.13 The remote-exec provisioner
resource "aws_instance" "main" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = "t2.micro"
 
  connection {
    type        = "ssh"
    user        = "ubuntu"
    private_key = file("~/.ssh/id_rsa")
    host        = self.public_ip
  }
 
  provisioner "remote-exec" {                    #1
    inline = [                                   #2
      "sudo apt-get update",
      "sudo apt-get install -y nginx"
    ]
  }
  provisioner "remote-exec" {                    #3
    script = "${path.module}/scripts/install.sh" #4
  }
 
  provisioner "remote-exec" {
    scripts = [                                  #5
      "${path.module}/scripts/install.sh",
      "${path.module}/scripts/configure.sh"
    ]
  }
}

Compare the three remote-exec command forms on an instance with an SSH connection. section 10.3.2

Provisioners run at creation by default. Set when = destroy for cleanup during destruction or replacement, but removing the resource block also removes that instruction. A failure normally stops apply and taints the resource for replacement on the next plan; on_failure = continue ignores the error instead. section 10.3.4

Use terraform_data when a provisioner should not belong to a particular infrastructure resource. Its depends_on can wait for several resources; triggers_replace can cause the provisioner to run again when selected values change. Older configurations may use null_resource for this role. section 10.3.5 section 6.8.4

Prefer prebuilt machine images for software installation and Cloud-Init for launch-time configuration or files. For machine metadata, consider output variables or the local provider. Provisioners cannot load external data into resources; the external provider serves that different need. section 10.3.6 section 10.4

How Terraform in Depth: Infrastructure as Code with Terraform and OpenTofu covers it

How deep it goes
Details command forms and lifecycle controls, including script selection, destroy-time execution, and failure handling.
Examples
Demonstrates installing nginx with remote-exec, logging instance IDs with local-exec, and deregistering an instance during destruction.
What it assumes
Assumes familiarity with Terraform resource blocks while explaining connection blocks and local versus remote execution.
What you can do after
Operate/configure it by choosing command provisioners and comparing them with machine images or Cloud-Init before deployment.
How it connects
Relates provisioners to terraform_data, resource dependencies, immutable infrastructure, and Cloud-Init.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Terraform in Depth: Infrastructure as Code with Terraform and OpenTofu. The section links point to the parts of the book it draws on.