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)