Terraform Cheatsheet
10xdev.blog/cheatsheets
# 1. Terraform CLI Workflow
# 1. Initialize the working directory
# Downloads provider plugins and sets up the backend.
terraform init

# 2. Format your configuration files
# Applies standard formatting for readability.
terraform fmt

# 3. Validate the configuration
# Checks for syntax errors and internal consistency.
terraform validate

# 4. Create an execution plan
# Shows what actions Terraform will take (create, update, destroy).
terraform plan

# 5. Apply the configuration
# Builds or changes the infrastructure.
terraform apply
# Use `-auto-approve` to skip the interactive prompt (use with caution).
# terraform apply -auto-approve

# 6. Destroy the infrastructure
# Tears down all resources managed by the configuration.
terraform destroy
# 2. HCL Basics: Resources & Providers
# --- Provider Configuration ---
# A provider is a plugin that Terraform uses to manage resources.
provider "aws" {
  region = "us-west-2"
}

# --- Resource Block ---
# A resource block defines a piece of infrastructure.
resource "aws_instance" "example" {
  # resource type --- local name

  ami           = "ami-0c55b159cbfafe1f0" # The machine image
  instance_type = "t2.micro"             # The size of the instance

  tags = {
    Name = "TerraformExample"
  }
}
# 3. Variables (Input & Output)
# --- Input Variables ---
# Define variables to parameterize your configuration.
variable "instance_type" {
  description = "The type of EC2 instance."
  type        = string
  default     = "t2.micro"
}

# Use variables in your resources
# resource "aws_instance" "example" {
#   instance_type = var.instance_type
#   ...
# }

# You can provide values via a terraform.tfvars file,
# command-line flags (`-var="instance_type=t3.large"`),
# or environment variables.

# --- Output Values ---
# Use outputs to display information about your infrastructure.
output "instance_id" {
  description = "The ID of the created EC2 instance."
  value       = aws_instance.example.id
}
# 4. Data Sources
# Data sources allow you to fetch information about existing resources
# or from external services.

# Example: Get the latest Amazon Linux 2 AMI
data "aws_ami" "amazon_linux" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }
}

# Use the data source in a resource
resource "aws_instance" "example" {
  ami           = data.aws_ami.amazon_linux.id
  instance_type = "t2.micro"
}
# 5. State Management
# Terraform records the state of your managed infrastructure in a state file
# (terraform.tfstate). This file is crucial and must be persisted.

# By default, state is stored locally. For team collaboration,
# it's essential to use a remote backend.

# --- Remote Backend Configuration (Example: S3) ---
terraform {
  backend "s3" {
    bucket         = "my-terraform-state-bucket"
    key            = "global/s3/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "my-terraform-locks" # For state locking
    encrypt        = true
  }
}
# 6. Expressions & Functions
# Use expressions and built-in functions to transform and combine values.

# Conditional expression
variable "is_production" {
  type    = bool
  default = false
}

resource "aws_instance" "example" {
  instance_type = var.is_production ? "t3.large" : "t3.micro"
}

# String interpolation
resource "aws_s3_bucket" "example" {
  bucket = "my-app-bucket-${terraform.workspace}"
}

# Common functions
# file() - reads contents of a file
# lookup() - looks up a value in a map
# length() - returns the length of a list, map, or string
# 7. Modules
# Modules are reusable containers for multiple resources.
# They help organize, encapsulate, and reuse your Terraform code.

# --- Using a module from the Terraform Registry ---
module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "5.1.2"

  name = "my-vpc"
  cidr = "10.0.0.0/16"

  azs             = ["us-east-1a", "us-east-1b"]
  private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
  public_subnets  = ["10.0.101.0/24", "10.0.102.0/24"]
}

# --- Accessing module outputs ---
# output "vpc_id" {
#   value = module.vpc.vpc_id
# }
master* 0 0