terraform initInitialize the working directory: download providers, set up the backend, and install modules. Must be run before any other command in a new checkout or after adding a new provider.
terraform init
cd infra/prod && terraform init
Terraform cheat sheet — 90+ commands for init, plan, apply, state, workspaces, import, and debug with real examples.
56 commands
terraform initInitialize the working directory: download providers, set up the backend, and install modules. Must be run before any other command in a new checkout or after adding a new provider.
terraform init
cd infra/prod && terraform init
terraform init -upgradeUpgrade all providers and modules to the latest allowed version according to version constraints. Without -upgrade, init reuses cached downloads.
⚠ Common pitfall: Running -upgrade in production without testing in staging first can pull in a breaking provider change.
terraform init -upgrade
terraform init -backend-config=backend.hclLoad backend configuration from an external file instead of hardcoding credentials in main.tf. Useful for keeping secrets out of version control.
terraform init -backend-config=backend.hcl
terraform init -backend-config="bucket=my-tfstate" -backend-config="region=us-east-1"
terraform init -migrate-stateReconfigure the backend and migrate existing state to the new location. Use when switching from local state to S3 or between S3 buckets.
⚠ Common pitfall: Back up your state file before migrating — a bad migration can leave you with no state.
terraform init -migrate-state
terraform init -reconfigureReconfigure the backend without migrating existing state. Use when you want to point at a fresh backend (e.g. a new workspace) and start clean.
terraform init -reconfigure
terraform planShow a preview of changes Terraform will make on the next apply. Refreshes state from the provider before comparing. Exit code 0 = no changes, 2 = changes present.
terraform plan
terraform plan 2>&1 | tee plan.log
terraform plan -out=plan.tfplanSave the plan to a file so the subsequent apply runs exactly what was reviewed. The gold standard for CI/CD: plan in one job, apply in another.
⚠ Common pitfall: Never run terraform apply without -out in automated pipelines — infra changes between plan and apply can cause surprises.
terraform plan -out=plan.tfplan
terraform apply plan.tfplan
terraform plan -target=aws_instance.webLimit planning to a specific resource (and its dependencies). Useful for iterating on a single resource without touching the rest of the config.
⚠ Common pitfall: -target can leave the state inconsistent. Use it only for iterative development, not as a standard practice.
terraform plan -target=aws_instance.web
terraform plan -target=module.vpc
terraform plan -var="key=value"Pass a variable inline on the command line. Overrides defaults and tfvars files. Good for one-off overrides in development.
terraform plan -var="env=prod"
terraform plan -var="region=eu-west-1" -var="instance_type=t3.medium"
terraform plan -var-file=prod.tfvarsLoad variable values from a .tfvars file. Files ending in .auto.tfvars or named terraform.tfvars are loaded automatically — all others require -var-file.
terraform plan -var-file=prod.tfvars
terraform plan -var-file=common.tfvars -var-file=prod.tfvars
terraform plan -destroyPreview the destroy plan without actually destroying anything. Equivalent to terraform destroy but stops before applying.
terraform plan -destroy
terraform plan -destroy -target=aws_rds_cluster.main
terraform plan -refresh-onlySync Terraform state with real infra without proposing any configuration changes. Use to accept drift after manual cloud changes.
terraform plan -refresh-only
terraform apply -refresh-only -auto-approve
terraform applyApply changes to real infrastructure. Shows a plan and prompts for confirmation before making any changes.
terraform apply
terraform apply -var-file=prod.tfvars
terraform apply -auto-approveApply without interactive approval. Required in CI/CD pipelines where stdin is not available. Only safe when applying a pre-reviewed plan file.
⚠ Common pitfall: Never use -auto-approve directly on terraform apply without a plan file in shared environments — you skip the review step.
terraform apply -auto-approve plan.tfplan
terraform apply -auto-approve -var-file=staging.tfvars
terraform apply plan.tfplanApply a previously saved plan file exactly as reviewed. This is the recommended CI/CD workflow: plan → review → apply plan file.
terraform apply plan.tfplan
terraform apply -auto-approve plan.tfplan
terraform apply -replace=aws_instance.webForce a specific resource to be destroyed and recreated in the same apply. Replaces the deprecated `terraform taint` command.
terraform apply -replace=aws_instance.web
terraform apply -replace=aws_launch_template.app -auto-approve
terraform apply -target=module.vpcApply changes to only a specific resource or module and its dependencies. Useful for phased rollouts or fixing a broken resource.
⚠ Common pitfall: Applying with -target repeatedly can cause state drift. Use it sparingly, and always follow up with a full apply.
terraform apply -target=module.vpc
terraform apply -target=aws_security_group.allow_tls
terraform apply -parallelism=20Set the number of resources Terraform operates on concurrently. Default is 10. Increase for large deployments where provider rate limits are not a concern.
terraform apply -parallelism=20
terraform apply -parallelism=5 -var-file=prod.tfvars
terraform destroyDestroy ALL resources managed by the current configuration. Shows a plan and prompts for confirmation. Use with extreme caution in production.
⚠ Common pitfall: terraform destroy removes EVERYTHING in the workspace. Use -target for selective teardown.
terraform destroy
terraform destroy -var-file=staging.tfvars
terraform destroy -target=aws_instance.webDestroy only a specific resource (and resources that depend on it). Much safer than a full destroy when you need to tear down one part of the stack.
terraform destroy -target=aws_instance.web
terraform destroy -target=module.rds -auto-approve
terraform destroy -auto-approveDestroy without interactive confirmation. Only safe in ephemeral CI environments where the workspace is intentionally being torn down.
terraform destroy -auto-approve
terraform destroy -auto-approve -target=module.test_env
terraform state listList all resources currently tracked in the state file. Add a filter to narrow down: `terraform state list aws_instance.*`.
terraform state list
terraform state list aws_s3_bucket.*
terraform state list module.vpc.*
terraform state show aws_instance.webDisplay all attributes of a specific resource in the state file. Useful for debugging unexpected diffs or verifying imported resource attributes.
terraform state show aws_instance.web
terraform state show module.vpc.aws_vpc.main
terraform state mv aws_instance.old aws_instance.newRename a resource in the state file without destroying and recreating it. Update the .tf configuration to match, then run terraform plan to confirm zero changes.
⚠ Common pitfall: Always run `terraform plan` after state mv to confirm there are no unexpected changes before apply.
terraform state mv aws_instance.old aws_instance.new
terraform state mv module.app module.web
terraform state mv aws_instance.web "module.ec2.aws_instance.web"
terraform state rm aws_instance.legacyRemove a resource from the state file WITHOUT deleting it in the cloud. Use when you want Terraform to stop managing a resource but keep it running.
⚠ Common pitfall: `state rm` does NOT delete the cloud resource. After removing, the resource is simply untracked and will not appear in plans.
terraform state rm aws_instance.legacy
terraform state rm module.old_module.aws_s3_bucket.data
terraform state pullPull the remote state and print it to stdout as JSON. Use to inspect or backup the current state from a remote backend.
terraform state pull
terraform state pull > backup-$(date +%F).tfstate
terraform state push terraform.tfstatePush a local state file to the remote backend. Use with extreme caution — pushing an older state will overwrite the current one and can cause data loss.
⚠ Common pitfall: state push overwrites the remote state unconditionally. Always pull first and verify the state is correct.
terraform state push terraform.tfstate
terraform force-unlock LOCK_IDRelease a stuck state lock. Use when a previous run crashed and left the lock unreleased. The lock ID is printed in the error message.
⚠ Common pitfall: Only force-unlock if you are certain no other apply is running. Unlocking during an active run can corrupt state.
terraform force-unlock 7ef08c27-5b32-4e9a-af67-a72f5fdca6a8
terraform workspace listList all workspaces in the current backend. The active workspace is prefixed with *.
terraform workspace list
terraform workspace showPrint the name of the currently active workspace. Useful in scripts to branch behavior by environment.
terraform workspace show
ENV=$(terraform workspace show)
terraform workspace new stagingCreate a new workspace and switch to it. Each workspace gets its own isolated state, allowing the same config to manage multiple environments.
terraform workspace new staging
terraform workspace new feature-vpc
terraform workspace select prodSwitch to an existing workspace. All subsequent commands operate against that workspace's state.
⚠ Common pitfall: Forgetting which workspace is active before running apply is a common cause of deploying to the wrong environment.
terraform workspace select prod
terraform workspace select default
terraform workspace delete stagingDelete a workspace. The workspace must be empty (no resources in its state). Use `terraform destroy` first if needed.
terraform workspace delete staging
terraform workspace delete -force old_env
terraform import aws_s3_bucket.logs my-logs-bucketImport an existing cloud resource into Terraform state. Write the resource block first, then run import with the provider-specific ID. The import does not generate config — you must write it yourself.
⚠ Common pitfall: After import, always run `terraform plan` to find attributes missing from your config. A wrong config causes immediate drift.
terraform import aws_s3_bucket.logs my-logs-bucket
terraform import aws_instance.web i-1234567890abcdef0
terraform import aws_route53_record.www Z1PA6795UKMFR9_www_A
terraform import -var="region=us-east-1" aws_vpc.main vpc-12345678Pass variables during import. Necessary when the provider configuration itself depends on variables (e.g. region, account ID).
terraform import -var="region=eu-west-1" aws_vpc.main vpc-12345678
terraform import -var-file=prod.tfvars aws_db_instance.main db-identifier
terraform outputPrint all root module output values from the current state. Reads from state — no provider calls, no infra changes.
terraform output
terraform output | grep instance_ip
terraform output instance_ipPrint a single output value by name. The value is quoted by default.
terraform output instance_ip
terraform output db_endpoint
terraform output -jsonPrint all outputs as a JSON object. Ideal for piping to jq or consuming in scripts and CI systems.
terraform output -json
terraform output -json | jq .instance_ip.value
IP=$(terraform output -json | jq -r .instance_ip.value)
terraform output -raw instance_ipPrint a single output value without surrounding quotes. Use in shell scripts where you want the raw string, not a JSON-quoted value.
IP=$(terraform output -raw instance_ip)
ssh ubuntu@$(terraform output -raw instance_ip)
terraform fmtReformat all .tf files in the current directory to the canonical Terraform style. Safe to run at any time — only changes whitespace and indentation.
terraform fmt
terraform fmt main.tf
terraform fmt -recursiveRecursively format all .tf files in the current directory and all subdirectories. Use before committing in a monorepo.
terraform fmt -recursive
terraform fmt -recursive .
terraform fmt -checkExit with a non-zero code if any files need formatting, without changing them. Use in CI to enforce code style.
terraform fmt -check
terraform fmt -check -recursive || (echo "Run terraform fmt" && exit 1)
terraform fmt -diffShow a diff of the formatting changes without applying them. Use during review to see what fmt would change.
terraform fmt -diff
terraform fmt -diff -recursive
terraform validateCheck the configuration for syntax errors and semantic issues (invalid references, missing required arguments). Does not access the provider or remote state.
⚠ Common pitfall: validate only checks static syntax — it cannot catch errors that depend on provider schema or runtime values.
terraform validate
terraform validate && echo "OK"
terraform providersPrint a tree of the providers required by the current configuration, with version constraints and their source.
terraform providers
terraform providers lockCreate or update the .terraform.lock.hcl dependency lock file. Should be committed to version control so all team members use identical provider versions.
terraform providers lock
terraform providers lock -platform=linux_amd64 -platform=darwin_amd64
terraform providers mirror /local/mirrorDownload all required providers into a local directory. Use to set up an air-gapped environment where the CI runner cannot reach the public Terraform Registry.
terraform providers mirror /tmp/tf-providers
terraform providers mirror /mnt/shared/providers
terraform getDownload and install modules referenced in the configuration. Called automatically by terraform init — use explicitly after adding a new module without re-initing.
terraform get
terraform get -update
terraform get -updateCheck for newer versions of installed modules and download updates. Use to pull in module bugfixes without a full re-init.
terraform get -update
TF_LOG=DEBUG terraform planEnable verbose debug logging for a single command. Log levels: TRACE, DEBUG, INFO, WARN, ERROR. DEBUG shows every provider API call.
⚠ Common pitfall: DEBUG logs include credential values and sensitive data. Never share or commit log files without scrubbing them.
TF_LOG=DEBUG terraform plan
TF_LOG=INFO terraform apply
TF_LOG=TRACE terraform init 2>&1 | head -200
TF_LOG_PATH=./terraform.log terraform applyRedirect debug logs to a file instead of stderr. Combine with TF_LOG to control verbosity. Essential when logs are too long to inspect in a terminal.
TF_LOG=DEBUG TF_LOG_PATH=./tf-debug.log terraform plan
TF_LOG=INFO TF_LOG_PATH=/var/log/terraform.log terraform apply
TF_LOG_CORE=DEBUG TF_LOG_PROVIDER=OFF terraform planSeparate log levels for the Terraform core engine vs. provider plugins. Use to silence noisy provider logs while debugging a core issue.
TF_LOG_CORE=DEBUG TF_LOG_PROVIDER=OFF terraform plan
TF_LOG_CORE=OFF TF_LOG_PROVIDER=TRACE terraform apply
terraform showDisplay a human-readable representation of the current state file or a saved plan file.
terraform show
terraform show plan.tfplan
terraform show -json plan.tfplan | jq .
terraform consoleOpen an interactive HCL expression REPL against the current state. Evaluate expressions, test functions, and inspect resource attributes without writing a plan.
terraform console
# Inside console:
aws_instance.web.public_ip
jsonencode({ key = "value" })cidrsubnet("10.0.0.0/16", 8, 2)terraform graphOutput the dependency graph of resources in DOT format. Pipe to Graphviz to create a visual diagram.
terraform graph
terraform graph | dot -Tpng > graph.png
terraform graph | dot -Tsvg > graph.svg && open graph.svg
terraform versionPrint the Terraform version and the versions of all installed providers. Use in bug reports and to verify the environment in CI.
terraform version
terraform version -json
Searchable Terraform cheat sheet with 90+ commands organized into eleven sections DevOps engineers reach for daily. Init: terraform init, -upgrade to refresh providers, -backend-config for external backend files, -migrate-state to switch backends, -reconfigure to reset without migrating. Plan: terraform plan, -out to save a plan file for safe apply, -target to scope to one resource, -var and -var-file for variable injection, -destroy to preview teardown, -refresh-only to sync state only. Apply: terraform apply, -auto-approve for CI pipelines, apply a saved plan file, -replace (modern taint replacement), -parallelism for faster runs. Destroy: terraform destroy, -target for selective teardown. State: state list, state show, state mv to rename without recreation, state rm to untrack without deleting, state pull/push for manual manipulation, force-unlock for stuck locks. Workspaces: workspace list / new / select / show / delete for environment isolation. Import: terraform import with resource address and cloud provider ID. Output: terraform output, -json for scripting, -raw for shell variables. Format and validate: terraform fmt -recursive, -check for CI gates, -diff for review; terraform validate for syntax checks. Providers: providers lock and providers mirror for air-gapped environments; terraform get -update for modules. Debug: TF_LOG levels, TF_LOG_PATH file redirect, terraform console as HCL REPL, terraform graph for dependency diagrams. Every entry has bilingual descriptions, a copy-ready example, and a pitfall callout. Search across command, description, pitfall, and examples. One-click copy. 100% client-side.
Paste or drop your content into the tool panel.
Click the button. All processing is local in your browser.
Copy the result or download to disk in one click.
Use it in the small gaps between coding, reviewing, debugging, and shipping.
These links move the current task into a more complete workflow.
A team member's apply crashed mid-run and left a `.lock` on the S3 backend. You find the lock ID in the error message, run `terraform force-unlock <id>`, confirm with yes, and the next apply proceeds. Without this entry you'd be editing DynamoDB by hand.
You refactored `module.app` to `module.web` and `terraform plan` wants to destroy and recreate 14 resources. You run `terraform state mv module.app module.web` instead, plan again, and get zero changes. Infra never reboots.
A bucket was created manually six months ago and now needs to be managed as code. You write the `aws_s3_bucket` resource block, run `terraform import aws_s3_bucket.assets my-assets-bucket`, then `terraform plan` to find the gaps in your config.
Before adding a new CI runner, you run `terraform providers lock -platform=linux_amd64 -platform=darwin_amd64` so the lock file covers both macOS devs and Linux CI. No more "provider not found" on the first pipeline run.
Running `terraform apply` without `-out` in CI means the plan and apply may differ if infra changes between the two steps. Always `plan -out=plan.tfplan` then `apply plan.tfplan`.
`terraform state rm` removes a resource from state but does NOT delete it in the cloud. Use it only when you want Terraform to forget a resource, not when you want to delete it.
Using `terraform destroy` instead of `-target` removes ALL resources in the workspace. Prefer `terraform destroy -target=<address>` for surgical teardowns.
Everything runs in your browser. The command list is a static in-memory array. The search box, category chips, and copy button never make a network request. Nothing you type is logged or sent anywhere, and the search query is not written to the URL. The sheet works offline, on an air-gapped CI runner, or behind a corporate proxy — which is exactly where DevOps teams tend to need Terraform references the most.
Folks in your role tend to reach for these alongside this tool.