Free Terraform Commands Cheat Sheet Online
Terraform is the de facto standard for Infrastructure as Code. It lets you define servers, databases, networks, DNS records, and thousands of other resources in declarative HCL files, then provision everything with a single command. Under the hood, Terraform builds a dependency graph, compares desired state to actual state, and calls cloud APIs to make reality match your configuration. The CLI is the interface to this entire system. And it is deep.
Our free interactive Terraform Commands Cheat Sheet covers more than 120 commands across ten categories: Core Workflow, State Operations, Configuration & HCL, Providers, Modules, Workspaces, Cloud & Enterprise, Import & Migration, Testing & Validation, and Advanced CLI & Automation. Every entry includes a plain-language description and a copyable example. The interface is searchable, filterable, and works entirely in your browser. No signup. No ads. No tracking. Bookmark it.
If you are working across the full DevOps stack, see our Kubernetes Commands Cheat Sheet for kubectl and Helm commands, our Docker Commands Expansion Cheat Sheet for advanced container operations, and our DevOps Commands Cheat Sheet for a cross-tool reference covering Docker, Kubernetes, AWS CLI, Helm, and Terraform essentials.
What is Terraform?
Terraform is HashiCorp's Infrastructure as Code tool. You write HCL (HashiCorp Configuration Language) files describing what infrastructure you want — EC2 instances, RDS databases, S3 buckets, IAM roles, Kubernetes namespaces, Cloudflare DNS records. Then you run terraform init to download the providers, terraform plan to preview changes, and terraform apply to make them real.
The architecture is elegant. Terraform maintains a state file (terraform.tfstate) that maps configuration resources to real-world resource IDs. On each plan, it reads the current state, reads your configuration, queries the real infrastructure via provider APIs, and computes a diff. The plan output shows exactly what will be created, modified, or destroyed. The state file is stored locally by default, but in production you use a remote backend — S3, GCS, Azure Blob, or Terraform Cloud — with DynamoDB or equivalent locking to prevent concurrent modifications.
Terraform is provider-agnostic. There are 3,000+ providers in the Terraform Registry covering every major cloud, SaaS platform, monitoring tool, and database. The provider plugin model means Terraform's core is a graph engine and state manager, while providers translate between HCL and API calls. This separation is why you can manage AWS, Cloudflare, GitHub, and Datadog from the same configuration using the same workflow.
Terraform Commands Cheat Sheet Overview
Our cheat sheet organizes Terraform CLI commands into ten categories mapped to real workflows:
- Core Workflow — init, plan, apply, destroy. The commands you run every day.
- State Operations — state list, show, mv, rm, pull, push, taint, force-unlock. Managing and debugging state files.
- Configuration & HCL — fmt, validate, console, output, show. Working with the configuration language.
- Providers — provider requirements, mirroring, lock files, version management, login.
- Modules — module sources (local, registry, git), versioning, for_each, providers passthrough.
- Workspaces — workspace create, select, list, delete. Environment isolation via state separation.
- Cloud & Enterprise — Terraform Cloud integration, remote execution, policy sets, private registry.
- Import & Migration — import, import blocks, moved/removed blocks, state refactoring.
- Testing & Validation — terraform test, variable validation, preconditions, postconditions, check blocks.
- Advanced CLI & Automation — graph, -chdir, -parallelism, JSON output, TF_LOG, CI/CD integration.
Each category covers the commands you actually reach for, with production-ready examples.
Core Workflow: init, plan, apply, destroy
The core Terraform workflow is a loop: init → plan → apply → (repeat). This is the foundation that every other command builds on.
terraform init is always the first command in any Terraform directory. It downloads provider plugins, initializes the backend (where state is stored), and downloads referenced modules. Without init, no other command works.
terraform init To upgrade providers to the latest allowed versions:
terraform init -upgrade To pass backend configuration from a file (instead of hardcoding in the terraform block):
terraform init -backend-config=backend.hcl To reconfigure the backend when changing backends or credentials:
terraform init -reconfigure terraform plan is the read-only preview. It compares state, configuration, and real infrastructure to show what would change. Run plan before every apply.
terraform plan To save a plan for later application (ensuring the reviewed plan is exactly what gets applied):
terraform plan -out=tfplan To plan changes for a specific resource only (partial plan, useful for incremental deployments):
terraform plan -target=aws_instance.web To override variable values at plan time:
terraform plan -var='region=us-east-1' To load variables from a file:
terraform plan -var-file=production.tfvars terraform apply executes the changes. It shows the plan again and prompts for confirmation unless you use -auto-approve.
terraform apply To skip the confirmation prompt (common in CI/CD):
terraform apply -auto-approve To apply a previously saved plan file:
terraform apply tfplan terraform destroy tears down all resources managed by the configuration. The confirmation prompt is mandatory here for good reason.
terraform destroy To destroy only a specific resource:
terraform destroy -target=aws_instance.web Always read the plan output before running apply in production. The plan tells you which resources are being added, changed, and destroyed. The yellow `~` means in-place update, green `+` means create, red `-` means destroy, and `-/+` means destroy-and-recreate (often because of an immutable attribute change).
State Management: The Source of Truth
Terraform's state file is the bridge between your HCL configuration and cloud reality. When you run terraform plan or apply, Terraform reads this file to know what resources it already manages. State corruption or drift is the most common cause of Terraform incidents, so understanding state commands is essential.
To list every resource tracked in state:
terraform state list To inspect a single resource's attributes as stored in state:
terraform state show aws_instance.web To rename a resource in state without destroying the real resource (critical for refactoring):
terraform state mv aws_instance.old_name aws_instance.new_name This command is how you restructure modules and rename resources safely. The real resource is untouched; only the state mapping changes. Use it when you move resources between modules, rename them, or change their index from count to for_each.
To remove a resource from state while keeping the real infrastructure running:
terraform state rm aws_instance.web After this, Terraform no longer manages the resource. It won't update it, destroy it, or even know it exists. Use this when migrating a resource out of Terraform management temporarily.
To export state as JSON for inspection or backup:
terraform state pull To mark a resource for recreation on the next apply (tainting):
terraform taint aws_instance.web To cancel a taint:
terraform untaint aws_instance.web To sync state with real infrastructure without changing anything:
terraform refresh To force-release a stuck state lock when a previous operation crashed:
terraform force-unlock LOCK_ID Only use force-unlock when you are absolutely certain no other process holds the lock. Force-unlocking while another apply is running will corrupt your state.
To replace a provider in state when migrating to a forked provider:
terraform state replace-provider hashicorp/aws registry.terraform.io/acme/aws Configuration & HCL: fmt, validate, console, output
HCL is designed to be human-readable and machine-friendly. terraform fmt enforces a canonical style; terraform validate catches structural errors before they reach the plan stage.
To format all .tf files to canonical style:
terraform fmt To format recursively through all subdirectories:
terraform fmt -recursive To check formatting without changing anything (ideal for CI):
terraform fmt -check -recursive To validate configuration syntax and references:
terraform validate Validate catches undefined variables, missing attributes, circular dependencies, and incorrect resource references. It does not check provider API compatibility — that is caught at plan time.
To open an interactive console for testing expressions:
terraform console Inside the console, you can evaluate HCL functions and expressions:
> max(1, 2, 3)
3
> cidrsubnet("10.0.0.0/16", 8, 1)
"10.0.1.0/24"
> formatdate("YYYY-MM-DD", timestamp())
"2026-05-17" To display output values defined in the root module:
terraform output To print a single output value (useful in scripts):
terraform output -raw instance_public_ip To display state or saved plan in human-readable format:
terraform show To export state as JSON for programmatic processing:
terraform show -json Providers: The Plugin Ecosystem
Providers translate HCL configuration into API calls. Each provider (AWS, Azure, GCP, Kubernetes, Cloudflare, Datadog, etc.) is a plugin downloaded during terraform init. The dependency lock file (.terraform.lock.hcl) records exact provider versions and checksums for reproducible builds.
To see which providers your configuration requires:
terraform providers To update the lock file with checksums for a specific platform:
terraform providers lock -platform=linux_amd64 -platform=darwin_arm64 To mirror provider plugins to a local directory for air-gapped environments:
terraform providers mirror /path/to/plugins To output provider schemas as JSON (for code generation tools):
terraform providers schema -json To check your Terraform and provider versions:
terraform version To declare providers with version constraints:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
} To use multiple provider configurations (multi-region, multi-account):
provider "aws" {
alias = "west"
region = "us-west-2"
}
resource "aws_instance" "west_server" {
provider = aws.west
# ...
} Provider aliases are essential for multi-region architectures and cross-account setups (using assume_role in the provider block).
Modules: Reusable Infrastructure Components
Modules are the primary mechanism for code reuse in Terraform. A module is a directory of .tf files that can be called from other configurations. Published modules in the Terraform Registry provide battle-tested infrastructure patterns.
To reference a module from the public registry:
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.0.0"
name = "main-vpc"
cidr = "10.0.0.0/16"
} To reference a module from a local path (organizing your own code):
module "networking" {
source = "./modules/networking"
} To reference a module from a Git repository:
module "security" {
source = "git::https://github.com/org/terraform-modules.git//security?ref=v2.0"
} To download and update modules without running init:
terraform get terraform get -update To pass specific provider configurations into a module:
module "west_app" {
source = "./app"
providers = {
aws = aws.west
}
} To create multiple module instances with for_each:
module "environments" {
for_each = toset(["dev", "staging", "prod"])
source = "./environment"
env_name = each.key
} Module outputs are accessed as module.MODULE_NAME.OUTPUT_NAME. This is how modules pass information back to the calling configuration — VPC IDs, subnet IDs, load balancer DNS names, etc.
Workspaces: Environment Isolation via State
Workspaces provide state isolation within a single configuration directory. Each workspace has its own state file, so applying in the "dev" workspace does not affect resources in the "prod" workspace.
To list existing workspaces:
terraform workspace list To create and switch to a new workspace:
terraform workspace new staging To switch between workspaces:
terraform workspace select staging To show the current workspace:
terraform workspace show To delete a workspace (and its state):
terraform workspace delete staging To reference the current workspace in configuration:
name = "app-${terraform.workspace}" Workspaces are convenient for rapid environment switching within the same infrastructure shape. However, they share the same backend, credentials, and configuration. For stronger isolation between production and development, use separate directories or Git branches.
Terraform Cloud & Enterprise
Terraform Cloud (TFC) runs Terraform remotely, providing state management, run history, policy enforcement, cost estimation, and team collaboration through a web UI and API.
To authenticate with Terraform Cloud:
terraform login To remove stored credentials:
terraform logout To configure Terraform Cloud integration in configuration:
terraform {
cloud {
organization = "my-org"
workspaces {
name = "my-workspace"
}
}
} Once the cloud block is configured, terraform plan and apply execute remotely in TFC's managed runners. The local CLI becomes a client that sends configuration to TFC and receives plan results.
For state storage only (without remote execution), use the remote backend:
terraform {
backend "remote" {
organization = "my-org"
workspaces {
name = "production"
}
}
} TFC workspaces support run triggers (auto-plan when another workspace applies), policy sets (Sentinel or OPA), cost estimation, and a private module registry. For teams managing shared infrastructure, TFC eliminates the problem of "it worked on my laptop" by providing a single, auditable execution environment.
Import & Migration: Bringing Brownfield Under Management
Most real-world Terraform adoption starts with existing infrastructure. Import commands bring unmanaged resources under Terraform control.
The classic import workflow — CLI-only, requires you to write matching HCL configuration separately:
terraform import aws_instance.web i-0a1b2c3d4e5f6g7h With Terraform 1.5+, you can declare imports in configuration using import blocks:
import {
to = aws_instance.web
id = "i-0a1b2c3d4e5f6g7h"
} And automatically generate configuration for imported resources:
terraform plan -generate-config-out=generated.tf This is a massive improvement over the classic workflow. Terraform reads the resource from the cloud API and writes a best-effort HCL configuration. You review, clean up, and commit.
To refactor resource names without destroying them (Terraform 1.1+):
moved {
from = aws_instance.old_name
to = aws_instance.new_name
} To remove a resource from state (Terraform 1.7+):
removed {
from = aws_instance.deprecated
lifecycle {
destroy = false
}
} For bulk imports from a CSV inventory:
while IFS=, read -r address id; do
terraform import "$address" "$id"
done < inventory.csv Testing & Validation: Infrastructure Quality Assurance
Terraform 1.6+ introduced a native testing framework. Test files (.tftest.hcl) sit alongside your configuration and define integration tests that apply real modules and assert outputs.
To run all tests:
terraform test A test file defines run blocks that apply modules, then assert conditions:
run "validate_vpc" {
command = apply
assert {
condition = module.vpc.vpc_id != ""
error_message = "VPC ID must not be empty"
}
} Variable validation catches bad inputs before plan:
variable "environment" {
type = string
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "Environment must be dev, staging, or prod."
}
} Preconditions and postconditions validate resource attributes:
lifecycle {
precondition {
condition = data.aws_region.current.name == "us-east-1"
error_message = "This module only supports us-east-1."
}
postcondition {
condition = self.arn != ""
error_message = "Resource ARN must not be empty after creation."
}
} Check blocks (Terraform 1.5+) provide continuous validation using data sources:
check "s3_encryption" {
data "aws_s3_bucket" "main" {
bucket = "my-bucket"
}
assert {
condition = data.aws_s3_bucket.main.server_side_encryption_configuration[0].rule[0].apply_server_side_encryption_by_default[0].sse_algorithm == "aws:kms"
error_message = "S3 bucket must use KMS encryption."
}
} Advanced CLI & Automation
When integrating Terraform into CI/CD pipelines and automation scripts, these commands unlock advanced workflows.
To generate a visual dependency graph:
terraform graph | dot -Tsvg > graph.svg To run terraform from a different working directory:
terraform -chdir=environments/prod apply To output a machine-readable plan for policy engines:
terraform plan -json To limit concurrent resource operations (tune API load):
terraform apply -parallelism=5 To force replacement of a specific resource without tainting first:
terraform apply -replace=aws_instance.web To detect infrastructure drift without applying changes:
terraform plan -refresh-only To enable debug logging for troubleshooting:
TF_LOG=DEBUG terraform plan To write debug logs to a file:
TF_LOG=TRACE TF_LOG_PATH=terraform.log terraform apply To set default CLI flags for an entire session (useful in CI):
export TF_CLI_ARGS='-no-color'
export TF_CLI_ARGS_plan='-compact-warnings'
export TF_CLI_ARGS_apply='-auto-approve' For CI/CD pipelines, a typical Terraform workflow looks like:
# On pull request:
terraform fmt -check -recursive
terraform validate
terraform plan -out=tfplan
# On merge:
terraform apply tfplan Production Terraform Workflow: A Real Example
Here is a production workflow that ties together the most important commands:
# 1. Start fresh
git checkout main && git pull
# 2. Create a workspace for your environment
terraform workspace select staging || terraform workspace new staging
# 3. Initialize with the right backend
terraform init -upgrade
# 4. Format and validate
terraform fmt -recursive
terraform validate
# 5. Preview changes
terraform plan -out=tfplan
# 6. Review the plan output carefully
# 7. Apply
terraform apply tfplan
# 8. Verify outputs
terraform output
# 9. If something went wrong, check state
terraform state list
terraform state show aws_instance.web
# 10. If you need to rollback, check what changed
terraform show tfplan This workflow catches formatting issues, validation errors, and unexpected changes before they reach production. The saved plan file ensures exactly what you reviewed is what gets applied.
Conclusion
Terraform's CLI is large because Infrastructure as Code is a large problem. You manage state, dependency graphs, provider ecosystems, modules, multi-environment configurations, team workflows, and CI/CD integration — all from the command line. The 120+ commands in our cheat sheet cover the workflows you actually encounter when provisioning and managing cloud infrastructure day to day.
Keep the cheat sheet open during your next Terraform session. When you hit a state lock issue, need to refactor module structure without downtime, or debug a plan diff, the answer is there. Combine it with our Kubernetes Commands Cheat Sheet and Docker Commands Expansion Cheat Sheet for a complete DevOps command reference. For broader infrastructure reference, our DevOps Commands Cheat Sheet spans Docker, Kubernetes, Terraform, and AWS CLI essentials in one place.
Now go provision something. That is what Terraform does best.