Terraform and OpenTofu Cheat Sheet: Commands and HCL Syntax
Terraform and OpenTofu quick reference #
Replace terraform with tofu to use OpenTofu: every command below works in both. For explanations, see the tutorials.
Main workflow #
| Command | What it does |
|---|---|
terraform init |
Downloads providers and modules and configures the backend |
terraform init -upgrade |
Updates providers and modules within the version constraints |
terraform init -reconfigure |
Reconfigures the backend ignoring the saved configuration |
terraform init -migrate-state |
Moves the state to a new backend |
terraform fmt -recursive |
Formats the code |
terraform validate |
Checks syntax and consistency |
terraform plan |
Shows the changes that would be made |
terraform plan -out=tfplan |
Saves the plan to a file |
terraform apply |
Applies the changes after confirmation |
terraform apply tfplan |
Applies a saved plan, with no confirmation |
terraform apply -auto-approve |
Applies without asking (CI only) |
terraform destroy |
Destroys everything managed |
Useful plan and apply flags #
| Flag | Use |
|---|---|
-var 'name=value' |
Sets a variable |
-var-file=pro.tfvars |
Loads variables from a file |
-target=aws_instance.web |
Limits the run to a resource (use in emergencies only) |
-replace=aws_instance.web |
Forces recreating a resource |
-refresh-only |
Updates the state with reality, changes no infrastructure |
-destroy |
Plans a destroy |
-parallelism=20 |
Number of concurrent operations (default 10) |
-lock=false |
Does not lock the state (avoid) |
-input=false |
Never asks for input (CI) |
State #
| Command | What it does |
|---|---|
terraform state list |
Lists the resources in the state |
terraform state show aws_instance.web |
Shows the attributes of one resource |
terraform state mv A B |
Renames a resource in the state |
terraform state rm A |
Removes a resource from the state without destroying it |
terraform state pull |
Prints the remote state |
terraform import A id |
Imports an existing resource |
terraform force-unlock ID |
Releases a stuck lock |
Prefer import, moved and removed blocks: see import, moved and removed.
Output, console and graph #
$ terraform output
$ terraform output -raw vpc_id
$ terraform show
$ terraform console # evaluate expressions
$ terraform graph | dot -Tpng > graph.png
$ terraform providers
$ terraform version
Workspaces #
$ terraform workspace list
$ terraform workspace new dev
$ terraform workspace select dev
$ terraform workspace delete dev
See workspaces vs directories.
Debugging #
$ export TF_LOG=DEBUG
$ export TF_LOG_PATH=terraform.log
More in how to debug Terraform.
Environment variables #
| Variable | Use |
|---|---|
TF_VAR_name |
Value of the variable name |
TF_LOG |
Log level: TRACE, DEBUG, INFO, WARN, ERROR |
TF_INPUT=0 |
Disables prompts |
TF_CLI_ARGS_plan |
Default arguments for plan |
TF_DATA_DIR |
Location of the .terraform directory |
TF_WORKSPACE |
Workspace to use |
HCL syntax #
# Resource
resource "aws_instance" "web" {
ami = var.ami
instance_type = "t3.micro"
}
# Data source
data "aws_region" "current" {}
# Variable, local and output
variable "name" { type = string }
locals { prefix = "ditwl-${var.name}" }
output "id" { value = aws_instance.web.id }
# Module
module "network" {
source = "./modules/network"
cidr = "10.0.0.0/16"
}
# Meta-arguments
# count, for_each, depends_on, provider, lifecycle
# Conditional
instance_type = var.env == "pro" ? "m6i.large" : "t3.micro"
# for expressions
names = [for s in var.subnets : upper(s)]
map = { for k, v in var.items : k => v.id }
# Splat
ids = aws_instance.web[*].idSee for_each vs count, dynamic blocks and lifecycle.
Common functions #
| Function | Example |
|---|---|
merge |
merge(local.tags, { Name = "x" }) |
lookup |
lookup(var.map, "key", "default") |
format |
format("web-%02d", count.index + 1) |
join, split |
join(",", var.list) |
toset, tolist, tomap |
toset(var.names) |
length |
length(var.list) |
cidrsubnet |
cidrsubnet("10.0.0.0/16", 8, 1) returns 10.0.1.0/24 |
file, templatefile |
templatefile("init.tftpl", { name = "x" }) |
jsonencode, yamlencode |
jsonencode({ a = 1 }) |
try, coalesce |
try(var.obj.value, "default") |
The full list is in Terraform functions.