Guide

A module is a folder of .tf files with a clear interface: inputs in as variables, values out as outputs. Teams use modules to put a standard in one place, so every database gets the same encryption and backup rules. Environments such as dev, staging and prod then differ only in their inputs.

Concept

Before you start. Read state and locking. Each environment needs its own state, and that is what keeps them apart.

The big idea

A module works like an appliance with built-in safety features. You choose the size and the name, but not whether the safety valve exists.

Where the analogy breaks: a module cannot stop someone from copying its code into a new folder. Good modules make the safe choice the default, and they do not expose a knob for the unsafe one unless someone decided to.

Walking through a root module

A root module calls child modules and passes values between them.

hcl
module "vpc" {
  source = "./modules/vpc"
  cidr   = "10.20.0.0/16"
  azs    = ["us-east-1a", "us-east-1b", "us-east-1c"]
}

module "db" {
  source     = "./modules/postgres"
  vpc_id     = module.vpc.vpc_id
  subnet_ids = module.vpc.private_subnet_ids
  multi_az   = true
}

module.vpc.private_subnet_ids is an output of the VPC module. The database depends on it, so Terraform builds the VPC first.

Good modules encode policy. For example, RDS always has encryption, backups keep at least 7 days, and prod has deletion protection. Callers pass size and name. A storage_encrypted = false option exists only if someone deliberately exposed it.

Two ways to split environments

infra/
  modules/
    vpc/
    postgres/
  envs/
    dev/      # its own state key
    staging/  # its own state key
    prod/     # its own state key
Separate directoriesWorkspaces
StateOne state per environmentOne config, state chosen by name
IsolationObvious in the pull requestDepends on picking the right workspace
DuplicationA little wiringLeast
Best forLong-lived environmentsShort-lived previews

Trade-off

Directories duplicate a little wiring and make isolation obvious. Workspaces reduce duplication but raise the cost of one wrong select. Use directories for long-lived environments, and workspaces for short-lived copies.

Promote changes by editing variables, not by forking the module. Dev can use one AZ and a small instance. Prod can use three AZs and Multi-AZ:

hcl
multi_az            = var.env == "prod"
backup_retention    = var.env == "prod" ? 14 : 3
deletion_protection = var.env == "prod"

Common mistakes

  • Running terraform workspace select prod in the wrong shell. You can apply staging settings to prod state, or the reverse.
  • Building one huge root module. A state with thousands of resources makes plans slow and reviews hard. Split by blast radius, meaning how much damage one bad apply can do. Typical splits are network, data and app.
  • Forking a module per environment. The copies drift apart. Change variables instead.

Check yourself

  1. Dev and prod use separate directories. Can a bad apply in dev touch prod? Answer: no. Each environment has its own state, so dev's apply only sees dev's resources.
  2. Why do modules hide some options? Answer: so callers cannot turn off a safety default, such as encryption, by accident.

Key takeaways

  • Modules hold the standard. Callers set size and name.
  • Long-lived environments get separate directories and separate state.
  • Promote changes with variables, not forks.
  • Next, safe changes covers how to review and guard applies.

Further learning

Modules overview (Terraform docs)Modules are containers for multiple resources that are used together in a configuration. Find resources for using, developing, and publishing modules.Modules overview | Terraform | HashiCorp Developer Module composition (Terraform docs)Module composition allows infrastructure to be described from modular building blocks.Module Composition | Terraform | HashiCorp Developer How to create reusable infrastructure with Terraform modules (Gruntwork)Create reusable infrastructure with Terraform modules in Part 4 of the Comprehensive Guide to Terraform, the series that became Terraform: Up and Running.blog.gruntwork.io Terraform: Up and Running (Yevgeniy Brikman)This book is the fastest way to get up and running with Terraform, an open source tool that allows you to manage your infrastructure as code across a variety of cloud providers.Terraform: Up & Running