Cloud and infrastructure as code
Terraform modules and environments
Modules package a standard into a reusable folder. Separate directories, each with its own state, keep dev and prod apart. Workspaces are useful but easy to misuse.
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.
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 directories | Workspaces | |
|---|---|---|
| State | One state per environment | One config, state chosen by name |
| Isolation | Obvious in the pull request | Depends on picking the right workspace |
| Duplication | A little wiring | Least |
| Best for | Long-lived environments | Short-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:
multi_az = var.env == "prod"
backup_retention = var.env == "prod" ? 14 : 3
deletion_protection = var.env == "prod"Common mistakes
- Running
terraform workspace select prodin 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
- 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.
- 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
Related
Infrastructure as code with Terraform
Declaring infrastructure in code — providers, state, plans, modules, environments and the habits that keep apply safe.
Terraform state and locking
The state file maps your code to real resources. Keep it in a remote backend with locking, and treat import, move and remove as production surgery.
Configuration, environments and feature flags
Twelve-factor config, environment parity, secrets injection, feature flags and the blast radius of a bad config push.