ENGIMY.IO - CHEATSHEET
TERRAFORM × QUICK REFERENCE
REFERENCE v1.0

Terraform Quick Reference

Everything you need day‑to‑day – HCL, providers, resources, state, and modules.

Core Concepts

Key Concepts
  • Infrastructure as Code (IaC) – declarative infrastructure
  • HCL – HashiCorp Configuration Language
  • Provider – plugin for cloud/services (AWS, GCP, Azure, etc.)
  • Resource – infrastructure component (EC2, S3, VPC, etc.)
  • Data Source – read‑only information from providers
  • Module – reusable collection of resources
  • State – mapping of resources to real infrastructure
  • Workspace – isolated state environments
Common Workflow
  • Write – define configuration (.tf files)
  • Initterraform init (download providers)
  • Planterraform plan (preview changes)
  • Applyterraform apply (create/update resources)
  • Destroyterraform destroy (remove resources)

Installation & Setup

# macOS
brew tap hashicorp/tap
brew install hashicorp/tap/terraform

# Linux
wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install terraform

# Windows (Chocolatey)
choco install terraform

# Verify installation
terraform --version

HCL Syntax

Basic Structure

# main.tf

# Provider configuration
provider "aws" {
  region = "us-east-1"
}

# Resource
resource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"

  tags = {
    Name = "example-instance"
  }
}

Resource Syntax

resource "resource_type" "local_name" {
  argument1 = value1
  argument2 = value2

  block {
    nested_argument = nested_value
  }
}

# Example
resource "aws_security_group" "web" {
  name        = "web-sg"
  description = "Allow HTTP and SSH"

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["10.0.0.0/8"]
  }
}

Variables

# variables.tf
variable "instance_type" {
  description = "EC2 instance type"
  type        = string
  default     = "t3.micro"
}

variable "environment" {
  description = "Environment name"
  type        = string
  default     = "dev"
}

variable "tags" {
  description = "Resource tags"
  type        = map(string)
  default = {
    Environment = "dev"
    Terraform   = "true"
  }
}

variable "instance_count" {
  description = "Number of instances"
  type        = number
  default     = 1
  validation {
    condition     = var.instance_count > 0 && var.instance_count <= 10
    error_message = "Instance count must be between 1 and 10."
  }
}

Outputs

# outputs.tf
output "instance_id" {
  description = "ID of the EC2 instance"
  value       = aws_instance.example.id
}

output "instance_public_ip" {
  description = "Public IP of the EC2 instance"
  value       = aws_instance.example.public_ip
}

output "instance_tags" {
  description = "Tags of the instance"
  value       = aws_instance.example.tags
  sensitive   = false
}

Data Sources

data "aws_ami" "amazon_linux" {
  most_recent = true
  owners      = ["amazon"]

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

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }
}

resource "aws_instance" "example" {
  ami           = data.aws_ami.amazon_linux.id
  instance_type = var.instance_type
}

Locals

locals {
  environment = "prod"
  project     = "myapp"
  common_tags = {
    Environment = local.environment
    Project     = local.project
    ManagedBy   = "Terraform"
  }
  name_prefix = "${local.environment}-${local.project}"
}

resource "aws_instance" "example" {
  tags = local.common_tags
  name = "${local.name_prefix}-server"
}

Modules

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

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

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

  enable_nat_gateway = true
  enable_vpn_gateway = false

  tags = local.common_tags
}

# Access module outputs
output "vpc_id" {
  value = module.vpc.vpc_id
}

Conditionals

# Ternary operator
resource "aws_instance" "example" {
  instance_type = var.environment == "prod" ? "t3.large" : "t3.micro"
  ami           = "ami-0c55b159cbfafe1f0"

  # count with conditional
  count = var.environment == "prod" ? 3 : 1
}

# Condition with dynamic block
dynamic "ebs_block" {
  for_each = var.attach_ebs ? [1] : []
  content {
    device_name = "/dev/sdh"
    volume_type = "gp3"
    volume_size = 100
  }
}

Loops (for_each & count)

# count – iterate by number
resource "aws_instance" "example" {
  count         = var.instance_count
  instance_type = var.instance_type
  ami           = data.aws_ami.amazon_linux.id

  tags = {
    Name = "instance-${count.index}"
  }
}

# for_each – iterate over set/map
variable "users" {
  type = list(string)
  default = ["alice", "bob", "charlie"]
}

resource "aws_iam_user" "users" {
  for_each = toset(var.users)
  name     = each.value
}

# for_each with map
variable "instances" {
  type = map(object({
    instance_type = string
    ami           = string
  }))
  default = {
    "web" = {
      instance_type = "t3.micro"
      ami           = "ami-0c55b159cbfafe1f0"
    }
    "app" = {
      instance_type = "t3.medium"
      ami           = "ami-0c55b159cbfafe1f0"
    }
  }
}

resource "aws_instance" "custom" {
  for_each      = var.instances
  instance_type = each.value.instance_type
  ami           = each.value.ami
  tags = {
    Name = each.key
  }
}

Functions

# String functions
upper("hello")   # HELLO
lower("WORLD")   # world
join(", ", ["a", "b", "c"])  # a, b, c
split("-", "a-b-c")  # ["a", "b", "c"]
replace("foo", "o", "x")  # fxx

# Collection functions
length(["a", "b", "c"])  # 3
element(["a", "b", "c"], 1)  # b
lookup({a=1, b=2}, "a", 0)  # 1
keys({a=1, b=2})  # ["a", "b"]
values({a=1, b=2})  # [1, 2]

# CIDR functions
cidrsubnet("10.0.0.0/16", 8, 1)  # 10.0.1.0/24
cidrhost("10.0.1.0/24", 10)  # 10.0.1.10

# File functions
file("path/to/file.txt")
templatefile("path/to/template.tpl", { var = "value" })

Terraform CLI Commands

Core Commands

Command Description
terraform init Initialize directory, download providers
terraform plan Preview changes (dry run)
terraform apply Create/update resources (with approval)
terraform apply -auto-approve Apply without approval
terraform destroy Delete all resources
terraform destroy -auto-approve Destroy without approval
terraform validate Validate configuration syntax
terraform fmt Format HCL files

State Commands

Command Description
terraform state list List resources in state
terraform state show resource Show resource details
terraform state mv src dst Move resource in state
terraform state rm resource Remove resource from state
terraform refresh Update state with real infrastructure

Workspace Commands

Command Description
terraform workspace list List all workspaces
terraform workspace new name Create new workspace
terraform workspace select name Switch workspace
terraform workspace delete name Delete workspace
terraform workspace show Show current workspace

Module Commands

Command Description
terraform get Download and update modules
terraform providers List required providers

Advanced Commands

Command Description
terraform output Display output values
terraform output -json Output as JSON
terraform graph Generate dependency graph (DOT format)
terraform graph | dot -Tpng > graph.png Generate graph as PNG
terraform show Show state or plan
terraform console Interactive console for expressions
terraform taint resource Force resource recreation on next apply
terraform untaint resource Remove taint from resource
terraform import resource id Import existing resource into state

Common CLI Flags

# General flags
-var="key=value"              # Set variable value
-var-file="vars.tfvars"       # Use variable file
-state="path/to/state.tfstate" # Custom state file
-chdir=./subdir               # Change working directory

# Plan & Apply
-target=resource              # Only apply to specific resource
-replace=resource             # Force replacement
-destroy                      # Plan for destroy
-out=plan.tfplan              # Save plan to file

# Examples
terraform plan -var="environment=prod"
terraform apply -target=aws_instance.example
terraform apply -replace=aws_instance.example
terraform plan -destroy -out=destroy-plan

Backend Configuration

Local Backend (Default)

terraform {
  backend "local" {
    path = "terraform.tfstate"
  }
}

S3 Backend (Remote State)

terraform {
  backend "s3" {
    bucket         = "my-terraform-state"
    key            = "prod/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    dynamodb_table = "terraform-locks"
  }
}

Azure Backend

terraform {
  backend "azurerm" {
    resource_group_name  = "my-rg"
    storage_account_name = "myterraformstate"
    container_name       = "tfstate"
    key                  = "prod.terraform.tfstate"
  }
}

GCS Backend (Google Cloud)

terraform {
  backend "gcs" {
    bucket = "my-terraform-state"
    prefix = "prod"
  }
}

Provider Configuration

AWS Provider

provider "aws" {
  region = var.aws_region
  access_key = var.aws_access_key
  secret_key = var.aws_secret_key

  default_tags {
    tags = {
      Environment = var.environment
      Project     = var.project
    }
  }
}

Multiple Providers

provider "aws" {
  alias  = "us-east-1"
  region = "us-east-1"
}

provider "aws" {
  alias  = "us-west-2"
  region = "us-west-2"
}

resource "aws_instance" "east" {
  provider    = aws.us-east-1
  ami         = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"
}

resource "aws_instance" "west" {
  provider    = aws.us-west-2
  ami         = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"
}

Required Providers

terraform {
  required_version = ">= 1.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 5.0.0"
    }
    random = {
      source  = "hashicorp/random"
      version = "~> 3.0"
    }
  }
}

Common Patterns

Random Resource

resource "random_id" "suffix" {
  byte_length = 4
}

resource "random_pet" "name" {
  length    = 2
  separator = "-"
}

resource "aws_s3_bucket" "example" {
  bucket = "my-bucket-${random_id.suffix.hex}-${random_pet.name.id}"
}

Lifecycle Rules

resource "aws_instance" "example" {
  lifecycle {
    create_before_destroy = true
    prevent_destroy       = false
    ignore_changes = [
      ami,
      user_data,
    ]
  }
}

Depends On

resource "aws_security_group" "web" {
  # ...
}

resource "aws_instance" "web" {
  depends_on = [aws_security_group.web]
  # ...
}

Provisioners

resource "aws_instance" "web" {
  ami           = data.aws_ami.amazon_linux.id
  instance_type = "t3.micro"

  user_data = templatefile("${path.module}/user_data.sh", {
    app_name = var.app_name
  })

  connection {
    type        = "ssh"
    user        = "ec2-user"
    private_key = file("${path.module}/key.pem")
    host        = self.public_ip
  }

  provisioner "file" {
    source      = "script.sh"
    destination = "/tmp/script.sh"
  }

  provisioner "remote-exec" {
    inline = [
      "chmod +x /tmp/script.sh",
      "/tmp/script.sh"
    ]
  }
}

State Management

State Commands Example

# List all resources
terraform state list

# Show specific resource
terraform state show aws_instance.example

# Move resource
terraform state mv aws_instance.example module.ec2.aws_instance.example

# Remove resource from state (then import later)
terraform state rm aws_instance.example

# Import existing resource
terraform import aws_instance.example i-1234567890abcdef0

State Locking

# DynamoDB table for locking (AWS)
resource "aws_dynamodb_table" "terraform_locks" {
  name         = "terraform-locks"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "LockID"

  attribute {
    name = "LockID"
    type = "S"
  }
}

Best Practices

  • Use remote state – store state in S3, GCS, Azure Storage (not local)
  • Enable state locking – prevent concurrent modifications
  • Version your state – enable versioning on state bucket
  • Use modules – organise and reuse code
  • Use variables and locals – avoid hardcoding
  • Tag resources – for cost tracking and identification
  • Use workspaces – separate environments (dev, staging, prod)
  • Use `.tfvars` files – separate config from code
  • Run `terraform plan` – always review changes before applying
  • Use `terraform fmt` – maintain consistent formatting
  • Use `terraform validate` – catch syntax errors early
  • Use `terraform apply -target` – for focused changes (use sparingly)
  • Set `create_before_destroy` – avoid downtime during updates
  • Avoid hardcoding secrets – use HashiCorp Vault, AWS Secrets Manager
  • Use provisioners sparingly – prefer user_data and configuration management
  • Version your modules – use semantic versioning
  • Use CI/CD – automate Terraform runs (GitHub Actions, GitLab CI, Atlantis)
  • Plan and apply in CI – with approval gates

Directory Structure

.
├── main.tf
├── variables.tf
├── outputs.tf
├── locals.tf
├── providers.tf
├── terraform.tfvars
├── modules/
│   ├── network/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   └── outputs.tf
│   └── compute/
│       ├── main.tf
│       ├── variables.tf
│       └── outputs.tf
└── environments/
    ├── dev/
    │   └── terraform.tfvars
    ├── staging/
    │   └── terraform.tfvars
    └── prod/
        └── terraform.tfvars
📌 Quick Reference
Init: terraform init
Plan: terraform plan
Apply: terraform apply
Destroy: terraform destroy
State: terraform state list, terraform state show
Workspace: terraform workspace new/select/show
Backend: S3 (AWS), GCS (GCP), Azurerm (Azure) – remote state
Resources: resource "provider_type" "name"
Variables: variable "name" { type = string }
Modules: Reusable collections, source from registry or local path
← Back to All Cheatsheets