Terraform Advanced — null_resource Escape Hatch

1 minute read

When Terraform doesn’t support what you need, null_resource and terraform_data fill the gap.


null_resource + local-exec

resource "null_resource" "db_setup" {
  triggers = {
    db_endpoint = aws_db_instance.main.endpoint
    schema_hash = filemd5("${path.module}/schema.sql")
  }

  provisioner "local-exec" {
    command = "psql -h ${aws_db_instance.main.address} -f schema.sql"
    environment = {
      PGPASSWORD = var.db_password
    }
  }
}

Re-runs when DB endpoint changes or schema file is modified.


terraform_data (Terraform 1.4+)

The modern replacement for null_resource:

resource "terraform_data" "bootstrap" {
  triggers_replace = [aws_instance.app.id]

  provisioner "remote-exec" {
    inline = ["sudo systemctl restart app"]
    connection {
      host = aws_instance.app.public_ip
      user = "ec2-user"
    }
  }
}

Common Use Cases

✅ Run a script after resource creation
✅ Trigger actions on dependency changes
✅ Wait for external process to complete
✅ Seed databases or configure third-party tools

Anti-Pattern Warning

# ❌ Don't use null_resource for everything
# If there's a proper Terraform resource, use it instead

# ❌ Bad
resource "null_resource" "s3_bucket" {
  provisioner "local-exec" {
    command = "aws s3 mb s3://my-bucket"
  }
}

# ✅ Good
resource "aws_s3_bucket" "my_bucket" {
  bucket = "my-bucket"
}

💡 Production Tip: null_resource and terraform_data should be your last resort. Always check if a proper Terraform resource or data source exists first.


What’s Next?

Practice production patterns.

← Cost Tagging & Drift Practice Exercises →

Updated: