Terraform is HashiCorp's Infrastructure as Code tool for defining cloud resources in declarative configuration files. This reference covers every CLI command organized by workflow stage: init, validate, plan, apply, state management, and destroy.
🧭 The Terraform Workflow
Every Terraform project follows this lifecycle:
init → validate → plan → apply → state → destroy
Think of it like building a house: you prep the site (init), check the blueprints (validate), preview what you're building (plan), actually build it (apply), keep track of what exists (state), and tear it down when you're done (destroy).
🚀 Getting Started
These commands help you confirm Terraform is installed and discover what's available.
| Command | What It Does |
|---|---|
terraform version | Shows your installed Terraform version |
terraform help | Lists all available commands |
terraform -help | Same as above — your go-to when you're stuck |
Right after installing Terraform, or when you forget a command name.
📦 Initialization
Before Terraform can do anything, it needs to download providers and set up your working directory.
| Command | What It Does |
|---|---|
terraform init | Downloads providers & modules, sets up your project — run this first |
terraform init -upgrade | Updates providers and modules to latest compatible versions |
terraform init -reconfigure | Resets backend config (useful when switching environments) |
terraform init -backend=false | Initializes without connecting to a remote backend |
terraform init -migrate-state | Moves your state file to a new backend |
Use tfenv to manage multiple Terraform versions across projects. Install it with brew install tfenv.

Introduction to Terraform on Azure - Cloudlearn.io
Learn the basics of Infrastructure as Code with Terraform by deploying an Azure storage account. Master essential commands and configuration concepts.
✅ Validation and Formatting
Catch errors before they cost you time.
| Command | What It Does |
|---|---|
terraform validate | Checks .tf files for syntax errors — run before every plan |
terraform validate -json | Outputs validation results in JSON (great for CI/CD) |
terraform fmt | Auto-formats your code to standard style |
terraform fmt -recursive | Formats all .tf files in subdirectories too |
terraform fmt -check | Tells you if files need formatting — without changing them |
terraform fmt -diff | Shows exactly what formatting changes would be made |
Before every commit. In real teams, fmt -check runs in your CI pipeline to enforce style.
🔮 Planning
This is Terraform's superpower — see exactly what will happen before anything changes.
| Command | What It Does |
|---|---|
terraform plan | Shows what Terraform will do — your "dry run" |
terraform plan -out=tfplan | Saves the plan to a file for exact execution later |
terraform plan -var="key=value" | Pass a variable directly |
terraform plan -var-file=vars.tfvars | Use a variables file — best practice |
terraform plan -target=resource.name | Plan for one specific resource only |
terraform plan -destroy | Preview what a destroy would remove |
terraform plan -refresh=false | Skip checking real infrastructure state |
Always review terraform plan output before applying. A careless apply on production can cause real damage.
🏗️ Apply
This is where Terraform actually creates, updates, or modifies your cloud infrastructure.
| Command | What It Does |
|---|---|
terraform apply | Applies changes (asks for confirmation) |
terraform apply tfplan | Applies a previously saved plan file — safest approach |
terraform apply -auto-approve | Skips confirmation — use in CI/CD only |
terraform apply -var-file=vars.tfvars | Apply using a specific variables file |
terraform apply -target=resource.name | Apply changes to one specific resource |
-auto-approve is powerful but dangerous. In production, always use saved plan files instead of auto-approve.
🗑️ Destroy
Remove infrastructure Terraform is managing. Essential for dev/test to avoid surprise cloud bills.
| Command | What It Does |
|---|---|
terraform destroy | Destroys all managed resources (asks for confirmation) |
terraform destroy -auto-approve | Destroys without asking — use with extreme caution |
terraform destroy -target=resource.name | Destroy only a specific resource |
Always destroy lab and test resources when you're done. Forgotten resources lead to surprise cloud bills.
🗄️ State Management
Terraform keeps a state file mapping your code to real cloud resources.
| Command | What It Does |
|---|---|
terraform state list | Shows all resources Terraform is managing |
terraform state show <resource> | Displays full details of a specific resource |
terraform state pull | Downloads state from remote backend |
terraform state push | Uploads local state to remote backend |
terraform state mv <old> <new> | Rename or move a resource in state |
terraform state rm <resource> | Removes a resource from state — Terraform "forgets" it |
terraform state replace-provider <old> <new> | Swap providers in state |
Troubleshooting drift, refactoring code, or when imports go wrong.
🗄️ Workspaces
Use the same Terraform code for different environments with separate state files.
| Command | What It Does |
|---|---|
terraform workspace list | Shows all workspaces |
terraform workspace show | Displays current workspace name |
terraform workspace new <name> | Creates a new workspace |
terraform workspace select <name> | Switches to a different workspace |
terraform workspace delete <name> | Deletes a workspace |
🔌 Providers and Modules
Providers connect Terraform to cloud platforms. Modules are reusable building blocks.
| Command | What It Does |
|---|---|
terraform providers | Lists required providers |
terraform providers mirror <dir> | Downloads providers locally |
terraform get | Downloads modules in your config |
terraform get -update | Re-downloads latest module versions |
📥 Import
Already built something manually? Import lets Terraform start managing it.
| Command | What It Does |
|---|---|
terraform import <resource_type.name> <cloud_id> | Links an existing cloud resource to your Terraform code |
Import only updates the state file. You still need to write the matching .tf code manually.
🔄 Refresh and Show
Keep your state in sync with what actually exists in the cloud.
| Command | What It Does |
|---|---|
terraform refresh | Updates state to match real infrastructure |
terraform show | Displays current state or a saved plan |
terraform show -json | Same but in JSON for scripting |
🔍 Debugging
When things go wrong, logs are your best friend.
| Command | What It Does |
|---|---|
TF_LOG=TRACE terraform apply | Maximum verbosity |
TF_LOG=DEBUG terraform plan | Detailed debug output |
TF_LOG_PATH=terraform.log terraform apply | Saves logs to a file |
When you get cryptic errors, provider auth failures, or state conflicts.
🎛️ Advanced Commands
You won't use these daily, but they're powerful when needed.
| Command | What It Does |
|---|---|
terraform taint <resource> | Marks a resource for recreation on next apply |
terraform untaint <resource> | Removes the taint mark |
terraform force-unlock <lock_id> | Releases a stuck state lock |
terraform graph | Outputs a dependency graph in DOT format |
terraform console | Opens an interactive shell for testing expressions |
terraform test | Runs Terraform's built-in testing framework |
taint is being replaced by terraform apply -replace=<resource> in newer versions. Prefer the newer syntax.