Terraform Provisioners
Learn how to use Terraform provisioners in various scenarios with practical examples and code snippets.
Documentation References
- Local Exec Provisioner (opens in a new tab)
- Remote Exec Provisioner (opens in a new tab)
- Connection Block (opens in a new tab)
- File Function (opens in a new tab)
Local-Exec Provisioner
Base Code Example
resource "aws_instance" "myec2" {
ami = "ami-04e5276ebb8451442"
instance_type = "t2.micro"
}
Final Code with Local-Exec Provisioner
resource "aws_instance" "myec2" {
ami = "ami-04e5276ebb8451442"
instance_type = "t2.micro"
provisioner "local-exec" {
command = "echo ${self.private_ip} >> server_ip.txt"
}
}
Alternative Example
resource "aws_instance" "myec2" {
ami = "ami-082b5a644766e0e6f"
instance_type = "t2.micro"
provisioner "local-exec" {
command = "echo ${aws_instance.myec2.private_ip} >> private_ips.txt"
}
}
Remote-Exec Provisioner
Base Code Example
resource "aws_instance" "myec2" {
ami = "ami-04e5276ebb8451442"
instance_type = "t2.micro"
}
Final Code with Remote-Exec Provisioner
resource "aws_instance" "myec2" {
ami = "ami-04e5276ebb8451442"
instance_type = "t2.micro"
key_name = "terraform-key"
vpc_security_group_ids = ["sg-0edf854d7112cfbf4"]
connection {
type = "ssh"
user = "ec2-user"
private_key = file("./terraform-key.pem")
host = self.public_ip
}
provisioner "remote-exec" {
inline = [
"sudo yum -y install nginx",
"sudo systemctl start nginx",
]
}
}
Null Resource Provisioner Examples
Example 1
provider "aws" {
region = "ap-southeast-1"
access_key = "YOUR-KEY"
secret_key = "YOUR-KEY"
}
resource "aws_eip" "lb" {
vpc = true
depends_on = [null_resource.health_check]
}
resource "null_resource" "health_check" {
provisioner "local-exec" {
command = "curl https://google.com"
}
}
Example 2
provider "aws" {
region = "ap-southeast-1"
access_key = "YOUR-KEY"
secret_key = "YOUR-KEY"
}
resource "aws_eip" "lb" {
vpc = true
count = 0
}
resource "null_resource" "ip_check" {
triggers = {
latest_ips = join(",", aws_eip.lb[*].public_ip)
}
provisioner "local-exec" {
command = "echo Latest IPs are ${null_resource.ip_check.triggers.latest_ips} > sample.txt"
}
}
Creation-Time Provisioner
Base Code
resource "aws_iam_user" "lb" {
name = "demo-provisioner-user"
provisioner "local-exec" {
command = "echo1 This is creation time provisioner"
}
}
Final Code with On-Failure Continue
resource "aws_iam_user" "lb" {
name = "demo-provisioner-user"
provisioner "local-exec" {
command = "echo1 This is creation time provisioner"
on_failure = continue
}
}
Creation and Destroy Time Provisioner
Base Code
resource "aws_iam_user" "lb" {
name = "provisioner-user"
provisioner "local-exec" {
command = "echo This is creation time provisioner"
}
provisioner "local-exec" {
command = "echo This is destroy time provisioner"
when = destroy
}
}
Simulating Failure to See Tainting of Resource
resource "aws_iam_user" "lb" {
name = "provisioner-user"
provisioner "local-exec" {
command = "This is creation time provisioner"
}
provisioner "local-exec" {
command = "echo This is destroy time provisioner"
when = destroy
}
}
Additional Local-Exec Provisioner Scenarios
Base Code
resource "aws_iam_user" "lb" {
name = "demoiamuser"
provisioner "local-exec" {
command = "echo local-exec provisioner is starting"
}
}
Scenario 2
resource "aws_iam_user" "lb" {
name = "demoiamuser"
provisioner "local-exec" {
command = "echo local-exec provisioner is starting"
}
provisioner "local-exec" {
command = "echo local-exec provisioner is starting for 2nd time"
}
}
Important Note
Make sure to have the ec2-key.pem
file present in the working directory for the provisioner to be able to connect to the instance.
Demo Code Used During Demo
provider "aws" {
region = "ap-southeast-1"
access_key = "YOUR-KEY"
secret_key = "YOUR-KEY"
}
resource "aws_security_group" "allow_ssh" {
name = "allow_ssh"
description = "Allow SSH inbound traffic"
ingress {
description = "SSH into VPC"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
description = "Outbound Allowed"
from_port = 0
to_port = 65535
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_instance" "myec2" {
ami = "ami-0b1e534a4ff9019e0"
instance_type = "t2.micro"
key_name = "ec2-key"
vpc_security_group_ids = [aws_security_group.allow_ssh.id]
provisioner "remote-exec" {
inline = [
"sudo yum -y install nano"
]
}
provisioner "remote-exec" {
when = destroy
inline = [
"sudo yum -y remove nano"
]
}
connection {
type = "ssh"
user = "ec2-user"
private_key = file("./ec2-key.pem")
host = self.public_ip
}
}