What is the Purpose of a null_resource in Terraform?
What is the Purpose of a null_resource in Terraform?
A null_resource is a special Terraform resource that does not manage any real cloud infrastructure. Instead, it acts as a placeholder to trigger side effects — like running scripts or commands — at the right point in the Terraform lifecycle.
When to Use null_resource
Use it when you need to:
- Run a local or remote script after certain infrastructure is ready.
- Execute a command that does not map to a Terraform resource.
- Trigger actions based on changes to other resources.
Basic Example: Run a Local Script
resource "null_resource" "run_setup_script" {
provisioner "local-exec" {
command = "bash ./scripts/setup.sh"
}
depends_on = [aws_instance.web]
}
This runs setup.sh on your local machine after the EC2 instance is created.
Using triggers to Re-run on Change
By default, a null_resource only runs once. Use triggers to re-execute it when a value changes:
resource "null_resource" "redeploy_app" {
triggers = {
app_version = var.app_version
instance_id = aws_instance.web.id
}
provisioner "local-exec" {
command = "ansible-playbook -i '${aws_instance.web.public_ip},' deploy.yml"
}
}
Every time app_version or the instance ID changes, this resource will be destroyed and recreated, triggering the provisioner again.
Remote Execution with remote-exec
resource "null_resource" "configure_server" {
connection {
type = "ssh"
user = "ubuntu"
private_key = file("~/.ssh/id_rsa")
host = aws_instance.web.public_ip
}
provisioner "remote-exec" {
inline = [
"sudo apt-get update -y",
"sudo apt-get install -y nginx",
"sudo systemctl start nginx"
]
}
depends_on = [aws_instance.web]
}
Modern Alternative: terraform_data (Terraform 1.4+)
# null_resource is being replaced by terraform_data in newer versions
resource "terraform_data" "run_script" {
triggers_replace = [var.app_version]
provisioner "local-exec" {
command = "echo Deploying version ${var.app_version}"
}
}
Key Takeaway
null_resource is your escape hatch for actions Terraform cannot model as a resource. Use it sparingly with provisioners for bootstrapping or triggering scripts. For Terraform 1.4 and above, prefer the built-in terraform_data resource instead.