📖 Guide
Terraform Commands Cheat Sheet — Complete Reference
Every Terraform command you need, from init to state management, modules, and HCL syntax. Searchable and organized.
122 commands across 11 categories
Core WorkflowState ManagementWorkspacesImport & MoveHCL Syntax BasicsResource BlocksProvidersModulesFunctionsBackend ConfigurationBest Practices
Core Workflow
| Command | Description |
|---|---|
terraform init | Initialize a working directory (download providers & modules) |
terraform init -upgrade | Upgrade providers and modules to latest allowed versions |
terraform init -backend-config=backend.hcl | Initialize with external backend configuration |
terraform init -migrate-state | Migrate state to a new backend during init |
terraform plan | Preview changes without applying |
terraform plan -out=plan.tfplan | Save plan to a file for later apply |
terraform plan -target=aws_instance.web | Plan changes for a specific resource only |
terraform plan -var 'region=us-east-1' | Pass a variable via command line |
terraform plan -var-file=prod.tfvars | Use a variable definitions file |
terraform plan -destroy | Preview what would be destroyed |
terraform apply | Apply changes (prompts for confirmation) |
terraform apply -auto-approve | Apply without confirmation prompt |
terraform apply plan.tfplan | Apply a saved plan file |
terraform apply -parallelism=20 | Apply with increased parallelism (default 10) |
terraform destroy | Destroy all managed infrastructure |
terraform destroy -auto-approve | Destroy without confirmation |
terraform destroy -target=aws_instance.web | Destroy a specific resource |
terraform validate | Check configuration syntax and consistency |
terraform fmt | Format configuration files to canonical style |
terraform fmt -recursive | Format all files in subdirectories too |
terraform fmt -check | Check if files are formatted (exit 1 if not) |
State Management
| Command | Description |
|---|---|
terraform state list | List all resources in the state |
terraform state show aws_instance.web | Show detailed state for a resource |
terraform state pull | Pull remote state and output to stdout |
terraform state push state.tfstate | Push a local state file to the remote backend |
terraform state rm aws_instance.web | Remove a resource from state (without destroying) |
terraform state mv aws_instance.old aws_instance.new | Rename a resource in state |
terraform state mv -state-out=other.tfstate aws_instance.web aws_instance.web | Move resource to another state file |
terraform state replace-provider hashicorp/aws registry.example.com/aws | Replace provider in state |
terraform refresh | Update state to match real infrastructure (deprecated — use plan -refresh-only) |
terraform plan -refresh-only | Detect drift without changing infrastructure |
terraform show | Show the current state in human-readable format |
terraform show plan.tfplan | Show a saved plan file |
terraform show -json | Output state as JSON |
terraform output | Show all output values |
terraform output -json | Show outputs as JSON |
terraform output instance_ip | Show a specific output value |
Workspaces
| Command | Description |
|---|---|
terraform workspace list | List all workspaces |
terraform workspace new staging | Create a new workspace |
terraform workspace select production | Switch to a workspace |
terraform workspace show | Show the current workspace name |
terraform workspace delete staging | Delete a workspace |
terraform.workspacee.g. tags = { env = terraform.workspace } | Reference current workspace name in HCL |
Import & Move
| Command | Description |
|---|---|
terraform import aws_instance.web i-1234567890 | Import existing infrastructure into state |
import {\n to = aws_instance.web\n id = "i-1234567890"\n} | Import block (Terraform 1.5+ — declarative import) |
terraform plan -generate-config-out=generated.tf | Generate config for imported resources |
moved {\n from = aws_instance.old\n to = aws_instance.new\n} | Moved block — refactor without destroy/recreate |
terraform taint aws_instance.web | Mark a resource to be recreated on next apply (deprecated) |
terraform untaint aws_instance.web | Remove the taint from a resource |
terraform apply -replace=aws_instance.web | Force replacement of a resource (preferred over taint) |
HCL Syntax Basics
| Command | Description |
|---|---|
variable "name" {\n type = string\n default = "world"\n} | Declare an input variable |
variable "port" {\n type = number\n description = "App port"\n validation {\n condition = var.port > 0\n error_message = "Must be positive"\n }\n} | Variable with validation |
variable "tags" {\n type = map(string)\n default = {}\n} | Map variable type |
variable "zones" {\n type = list(string)\n} | List variable type |
output "ip" {\n value = aws_instance.web.public_ip\n} | Declare an output value |
output "password" {\n value = random_password.db.result\n sensitive = true\n} | Sensitive output (hidden in CLI) |
locals {\n env = terraform.workspace\n prefix = "${local.env}-app"\n} | Define local values |
data "aws_ami" "ubuntu" {\n most_recent = true\n filter { ... }\n} | Data source — read existing infrastructure |
data "aws_vpc" "main" {\n default = true\n} | Look up the default VPC |
var.name | Reference an input variable |
local.prefix | Reference a local value |
data.aws_ami.ubuntu.id | Reference a data source attribute |
Resource Blocks
| Command | Description |
|---|---|
resource "aws_instance" "web" {\n ami = data.aws_ami.ubuntu.id\n instance_type = "t3.micro"\n} | Basic resource definition |
count = 3 | Create multiple instances of a resource |
count = var.create ? 1 : 0 | Conditionally create a resource |
for_each = toset(["web", "api"]) | Create instances from a set |
for_each = var.instances | Iterate over a map variable |
depends_on = [aws_iam_role.app] | Explicit dependency between resources |
lifecycle {\n create_before_destroy = true\n} | Create replacement before destroying old |
lifecycle {\n prevent_destroy = true\n} | Prevent accidental destruction |
lifecycle {\n ignore_changes = [tags]\n} | Ignore specific attribute changes |
lifecycle {\n replace_triggered_by = [null_resource.trigger]\n} | Replace resource when trigger changes |
provisioner "local-exec" {\n command = "echo ${self.public_ip}"\n} | Run local command after resource creation |
timeouts {\n create = "30m"\n delete = "15m"\n} | Custom timeout for resource operations |
Providers
| Command | Description |
|---|---|
terraform {\n required_providers {\n aws = {\n source = "hashicorp/aws"\n version = "~> 5.0"\n }\n }\n} | Declare a required provider with version constraint |
provider "aws" {\n region = "us-east-1"\n} | Configure a provider |
provider "aws" {\n alias = "west"\n region = "us-west-2"\n} | Provider alias for multi-region |
resource "aws_instance" "web" {\n provider = aws.west\n} | Use an aliased provider |
terraform {\n required_version = ">= 1.5.0"\n} | Require a minimum Terraform version |
terraform providers | List providers required by configuration |
terraform providers lock | Generate or update dependency lock file |
terraform providers mirror /path/to/mirror | Mirror provider plugins locally |
Modules
| Command | Description |
|---|---|
module "vpc" {\n source = "./modules/vpc"\n cidr = "10.0.0.0/16"\n} | Use a local module |
module "vpc" {\n source = "terraform-aws-modules/vpc/aws"\n version = "5.0.0"\n} | Use a module from the Terraform Registry |
module "app" {\n source = "git::https://example.com/repo.git//modules/app?ref=v1.0"\n} | Use a module from a Git repository |
module.vpc.vpc_id | Reference a module output |
terraform get | Download and update modules |
terraform get -update | Force update of already-downloaded modules |
terraform init -upgrade | Upgrade modules and providers during init |
Functions
| Command | Description |
|---|---|
join(", ", var.list) | Join list elements with a separator |
split(",", var.csv) | Split a string into a list |
length(var.list) | Get length of a list, map, or string |
lookup(var.map, "key", "default") | Look up a key in a map with default |
merge(var.map1, var.map2) | Merge multiple maps |
concat(var.list1, var.list2) | Concatenate lists |
flatten([var.list1, var.list2]) | Flatten nested lists into a single list |
coalesce(var.a, var.b, "default") | Return first non-null, non-empty value |
try(var.obj.key, "fallback") | Try an expression, return fallback on error |
file("${path.module}/script.sh") | Read file contents |
templatefile("tpl.sh", { name = var.name }) | Render a template with variables |
cidrsubnet("10.0.0.0/16", 8, 1)e.g. cidrsubnet("10.0.0.0/16", 8, 1) → "10.0.1.0/24" | Calculate a subnet CIDR |
format("Hello, %s!", var.name) | Format a string (printf-style) |
replace(var.str, "old", "new") | Replace substring in a string |
regex("^([a-z]+)", var.str) | Extract regex match from a string |
toset(var.list) | Convert a list to a set (deduplicate) |
jsonencode(var.object) | Encode a value as JSON |
yamldecode(file("config.yaml")) | Decode YAML content |
base64encode(var.data) | Base64 encode a string |
Backend Configuration
| Command | Description |
|---|---|
terraform {\n backend "s3" {\n bucket = "my-tfstate"\n key = "prod/terraform.tfstate"\n region = "us-east-1"\n }\n} | S3 backend configuration |
terraform {\n backend "azurerm" {\n resource_group_name = "tfstate"\n storage_account_name = "tfstate"\n container_name = "tfstate"\n key = "prod.tfstate"\n }\n} | Azure Storage backend |
terraform {\n backend "gcs" {\n bucket = "my-tfstate"\n prefix = "prod"\n }\n} | Google Cloud Storage backend |
terraform {\n backend "local" {\n path = "terraform.tfstate"\n }\n} | Local file backend (default) |
terraform {\n cloud {\n organization = "my-org"\n workspaces { name = "prod" }\n }\n} | Terraform Cloud / HCP backend |
terraform force-unlock <LOCK_ID> | Manually unlock a locked state |
Best Practices
| Command | Description |
|---|---|
terraform plan -out=plan.tfplan && terraform apply plan.tfplan | Always save and apply plan files in CI/CD |
.terraform/\n*.tfstate\n*.tfstate.backup\n*.tfvars | Add to .gitignore — never commit state or secrets |
terraform {\n required_version = ">= 1.5"\n} | Pin Terraform version in every project |
version = "~> 5.0" | Use pessimistic version constraints for providers |
terraform consolee.g. > length(["a", "b"])
2 | Interactive console to test expressions |
terraform graph | dot -Tsvg > graph.svg | Generate a visual dependency graph |
TF_LOG=DEBUG terraform plan | Enable debug logging |
TF_LOG_PATH=terraform.log terraform plan | Write debug logs to a file |
📖 Free, searchable command reference. Bookmark this page for quick access.