Cheatsheet - Terraform / OpenTofu
This is a cheatsheet of Terraform and OpenTofu configurations.
- For HCL syntax, check out Cheatsheet - HCL page.
- For Terraform CLI and Tofu CLI, check out Cheatsheet - Terraform CLI / Tofu CLI page.
Terraform Blocks
Hierarchy:
terraform => provider => resource
                      => data
- Resource: Generate; e.g. generate a local file resource "local_file" "foo" {}
- Data Source: Read; e.g. read a local file data "local_file" "foo" {}, then content can be referenced bydata.local_file.foo.content
3 types of values:
- variable: input variable (like the arguments of a func)
- output: output variable (like the return value of a func)
- locals: local values (like temp / local vars in a func)
Terraform
Top level configs, e.g. required_providers, required_version, etc.
terraform {
  required_version = "1.5.7"
  required_providers {
    docker = {
      source  = "kreuzwerker/docker"
      version = "2.15.0"
    }
  }
}
Providers
providers = terraform plugins; Each provider adds a set of resource types and/or data sources that Terraform can manage.
The Terraform Registry is the main directory of publicly available Terraform providers
official: hashicorp
- source address: registry.terraform.io/hashicorp/http
- default registry host: registry.terraform.io
- namespace: hashicorp
- type: http
For example:
provider "aws" {
  region = "us-east-1"
}
required provider:
terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = ">=x.y.0"
    }
  }
  ...
}
provider "google" {
  ...
}
hashicorp/google, its preferred local name is google
if you do not use the preferred local name, must use a meta-argument provider = <local name> to specify the provider in data and resource etc.
version:
- >=minimum version
- ~>only allowing the rightmost component of a version to increment
version = "~> 1.0.4" allow only patch releases within a specific minor release:
Built-in Providers do not need to be declared in required_providers
Resource
Each resource block describes one or more infrastructure objects, such as virtual networks, compute instances, or higher-level components such as DNS records.
Format:
resource <type> <local_name> {}
For example:
resource "aws_instance" "example" {
  ami           = "ami-0abcdef1234567890"
  instance_type = "t2.micro"
  tags = {
    Name = "MyExampleInstance"
  }
}
Most arguments in this section depend on the resource type
Each resource type is implemented by a provider; By convention, resource type names start with their provider's preferred local name.
Variable
Input values for your Terraform configuration. Defined in variables.tf (or inline).
variable "instance_type" {
  description = "The type of EC2 instance to create"
  type        = string
  default     = "t2.micro"
}
  To use: var.instance_type
  To set: terraform apply -var="instance_type=t2.small" or terraform.tfvars file.
Data
Data sources allow Terraform to use information defined outside of Terraform, defined by another separate Terraform configuration, or modified by functions. Read from data_source and export the result under local_name
data <data_source> <local_name> {
}
For example:
data "aws_ami" "ubuntu" {
  most_recent = true
  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
  }
  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }
  owners = ["099720109477"] # Canonical
}
Output
Values that are exported by a Terraform configuration. Defined in outputs.tf.
output "instance_id" {
  description = "The ID of the EC2 instance"
  value       = aws_instance.example.id
}
Output value can be referenced by module.<MODULE NAME>.<OUTPUT NAME>, e.g. module.web_server.instance_ip_addr.
Check
The check block can validate your infrastructure outside the usual resource lifecycle.
Import blocks
available in >=1.5
Module
A Module is a collection of .tf and/or .tf.json files kept together in a directory.
Reusable, encapsulated configurations.
module "vpc" {
  source = "./modules/vpc" # Local path
  # source = "terraform-aws-modules/vpc/aws" # Registry module
  cidr_block = "10.0.0.0/16"
  # ... other module inputs
}
State File
terraform.tfstate: A JSON file that maps real-world resources to your configuration. Crucial for Terraform's operation. Do not edit manually. Store remotely for team collaboration (e.g., S3, Azure Blob, GCS).
terraform {
  backend "s3" {
    bucket = "my-terraform-state-bucket"
    key    = "path/to/my/key.tfstate"
    region = "us-east-1"
  }
}
Advanced Features
- 
    count: Creates multiple instances of a resource based on a numerical count.resource "aws_instance" "app_server" { count = 3 ami = "ami-0abcdef1234567890" instance_type = "t2.micro" tags = { Name = "AppServer-${count.index}" } }
- 
    for_each: Creates multiple instances of a resource based on a map or set of strings, providing more stable identifiers.variable "regions" { type = map(string) default = { "us-east-1" = "ami-0abcdef1234567890" "us-west-2" = "ami-0fedcba9876543210" } } resource "aws_instance" "region_instance" { for_each = var.regions ami = each.value instance_type = "t2.micro" tags = { Name = "Instance-${each.key}" Region = each.key } }
- 
    depends_on: Explicitly specifies resource dependencies when Terraform cannot infer them.resource "aws_instance" "web" { # ... depends_on = [ aws_db_instance.main ] }
- 
    Tainting: terraform taint [resource_address]marks a resource for recreation on the nextapply.
- 
    Untainting: terraform untaint [resource_address]removes a tainting mark.
- 
    Import: terraform import [resource_address] [resource_id]imports existing infrastructure into Terraform state.
Functions
Terraform provides many built-in functions for manipulating data.
- concat(list1, list2)
- merge(map1, map2)
- lookup(map, key, [default])
- file(path)
- length(collection)
- join(separator, list)
- split(separator, string)
- lower(string),- upper(string)
- cidrsubnet(prefix, newbits, netnum)
Registries
When HashiCorp changed its license from the open-source Mozilla Public License to the more restrictive Business Source License, it also put the future of the Terraform Registry under the same license. For OpenTofu to be a viable long-term solution, it needed an independent source for providers and modules that would remain free and open.
- Terraform Registry: https://registry.terraform.io/
- OpenTofu Registry: https://search.opentofu.org
Providers
Built-in providers:
- hashicorp/local
- hashicorp/http
- hashicorp/tls
- hashicorp/random
Public Cloud providers:
- hashicorp/aws
- hashicorp/google
- hashicorp/azurerm
- aliyun/alicloud
- oracle/oci
Kubernetes / container / VM providers:
- hashicorp/kubernetes
- kreuzwerker/docker
- vmware/nsxt (for NSX-T virtualization platform)
