Understanding provisioners in terraform: file, remote-exec, and local-exec provisioners

Divyanshi SinghDivyanshi Singh
3 min read

When managing infrastructure, sometimes you'll need to perform specific actions during the setup process of your resources. This is where Terraform provisioners come in!

Provisioners in Terraform are used to execute scripts, copy files, or run commands on your instances, helping you configure or initialize your infrastructure after it's been created. While they can be powerful tools, provisioners should be used with caution and considered a last resort when resources, modules, or data sources can't achieve the desired outcome.

Let’s dive into the three most commonly used provisioners in Terraform: file, remote-exec, and local-exec.

1. File Provisioner

The file provisioner copies files or directories from your local machine to a remote instance. This is useful for transferring configuration files, scripts, or other assets that are needed to set up or customize the instance.

Example:

hclCopy coderesource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
}

provisioner "file" {
  source      = "local/path/to/localfile.txt"
  destination = "/path/on/remote/instance/file.txt"
  connection {
    type        = "ssh"
    user        = "ec2-user"
    private_key = file("~/.ssh/id_rsa")
  }
}

In this example, the file provisioner is copying localfile.txt from your local machine to tyour AWS EC2 instance’s specified path.

2. Remote-Exec Provisioner

The remote-exec provisioner allows you to execute commands on a remote instance via SSH (or WinRM for Windows). This is helpful for installing software, configuring services, or performing any setup actions on the remote machine after it’s provisioned.

Example:

hclCopy coderesource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
}

provisioner "remote-exec" {
  inline = [
    "sudo yum update -y",
    "sudo yum install -y httpd",
    "sudo systemctl start httpd",
  ]

  connection {
    type        = "ssh"
    user        = "ec2-user"
    private_key = file("~/.ssh/id_rsa")
    host        = aws_instance.example.public_ip
  }
}

In this case, the remote-exec provisioner connects to the AWS instance and runs commands to update packages, install Apache HTTP Server, and start it. It’s a quick way to make your instance operational with the software and services you need.

3. Local-Exec Provisioner

The local-exec provisioner executes commands locally, on the machine running Terraform, instead of on a remoteinstance. This can be useful for local tasks like initializing a database or setting up local configurations that don't require remote access.

Example:

hclCopy coderesource "null_resource" "example" {
  triggers = {
    always_run = "${timestamp()}"
  }

  provisioner "local-exec" {
    command = "echo 'This is a local command'"
  }
}

In this example, a null_resource is used with a local-exec provisioner to echo a message to the console each time Terraform is applied. The timestamp() function ensures that it runs each time, as it changes on every execution, triggering the provisioner.

When to Use Provisioners

They’re best used as they introduce potential dependencies and complexities. When possible, use native Terraform resources and avoid relying on provisioners for tasks that can be managed in other ways. They can be beneficial when you need to execute specific setup steps that can’t otherwise be managed by terraform alone

0
Subscribe to my newsletter

Read articles from Divyanshi Singh directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Divyanshi Singh
Divyanshi Singh