Discover why running commands directly on servers can cause more harm than good in your cloud setup!
Why provisioners are a last resort in Terraform - The Real Reasons
Imagine you have to set up a new server every day by logging in manually and running commands one by one.
You write scripts that run on the server after it is created to install software or configure settings.
This manual or script-based approach is slow and fragile.
If the server setup fails halfway, you must start over or fix it by hand.
Scripts can break if the server environment changes or if commands run in the wrong order.
Terraform encourages using built-in resource settings and external configuration tools instead of running commands directly on servers.
This keeps infrastructure setup predictable, repeatable, and easier to manage.
resource "aws_instance" "example" { # ... provisioner "remote-exec" { inline = ["sudo apt-get update", "sudo apt-get install -y nginx"] } }
resource "aws_instance" "example" { # ... user_data = <<-EOF #!/bin/bash apt-get update apt-get install -y nginx EOF }
It enables infrastructure to be created and configured reliably without fragile manual steps or scripts that can fail unexpectedly.
Instead of running commands on a new virtual machine to install software, you provide a startup script or use a configuration management tool that runs automatically and consistently.
Manual commands on servers are slow and error-prone.
Provisioners run commands but can cause fragile setups.
Using built-in features or external tools leads to stable, repeatable infrastructure.
Practice
Solution
Step 1: Understand provisioner behavior
Provisioners run commands after resource creation but can fail unpredictably and are not guaranteed to run only once.Step 2: Compare with Terraform best practices
Terraform encourages using native resource configuration or external tools to avoid errors and maintain idempotency.Final Answer:
Because they can cause unpredictable errors and are not idempotent -> Option AQuick Check:
Provisioners cause errors = A [OK]
- Thinking provisioners are the fastest method
- Believing provisioners auto-update resources
- Assuming provisioners replace state management
Solution
Step 1: Recall Terraform provisioner syntax
Terraform uses the block syntax with quotes for provisioner type and equals sign for attributes.Step 2: Match correct syntax
provisioner "local-exec" { command = "echo Hello" } correctly uses "local-exec" in quotes and sets command with equals sign.Final Answer:
provisioner "local-exec" { command = "echo Hello" } -> Option CQuick Check:
Correct syntax uses quotes and equals = D [OK]
- Using underscores instead of hyphens in provisioner type
- Using colons instead of equals signs
- Using parentheses instead of braces
resource "aws_instance" "example" {
ami = "ami-123456"
instance_type = "t2.micro"
provisioner "remote-exec" {
inline = ["sudo apt-get update", "sudo apt-get install -y nginx"]
}
}Solution
Step 1: Understand provisioner failure behavior
If a provisioner command fails, Terraform treats the resource creation as failed and stops the apply process.Step 2: Recognize rollback behavior
Terraform attempts to roll back or destroy the partially created resource to keep state consistent.Final Answer:
Terraform will stop and roll back the resource creation -> Option AQuick Check:
Provisioner failure stops apply and rolls back = A [OK]
- Assuming resource is created despite failure
- Thinking Terraform ignores provisioner errors
- Believing provisioners retry automatically
resource "null_resource" "example" {
provisioner "local-exec" {
command = "echo Hello"
}
}After running terraform apply, the provisioner does not run. What is the most likely cause?
Solution
Step 1: Understand provisioner trigger conditions
Provisioners run only when the resource is created or replaced, not on every apply if no changes.Step 2: Analyze the resource state
If the null_resource has no changes, Terraform skips running the provisioner.Final Answer:
The resource has no changes, so provisioner is not triggered -> Option DQuick Check:
Provisioners run only on resource changes = B [OK]
- Assuming provisioners run every apply
- Thinking local-exec syntax is wrong here
- Placing provisioner block outside resource
Solution
Step 1: Identify risks with provisioners and sensitive data
Provisioners can expose sensitive data in logs and are not idempotent, risking security and reliability.Step 2: Choose better alternatives
Using configuration management tools like Ansible or cloud-init handles complex setup securely and reliably outside Terraform.Final Answer:
Avoid provisioners because they can leak sensitive data; use configuration management tools like Ansible -> Option BQuick Check:
Provisioners risk data leaks; prefer config tools = C [OK]
- Assuming provisioners handle sensitive data securely
- Thinking provisioners run before resource creation
- Believing provisioners guarantee idempotency
Ready to prove it?
Pass the test and this pattern moves unknown
