Terraform’s own documentation teaches you the language. This cluster teaches you the repository.
Those are different subjects, and the second is where infrastructure teams actually struggle. Writing a correct aws_security_group resource is a solved problem with good documentation. Deciding whether production lives in a directory, a workspace or a separate repository — and what a reviewer must see before approving a change to it — is not, and getting it wrong is how a small team ends up unable to change anything safely.
What this cluster answers
Section titled “What this cluster answers”Ten lessons, each owning one decision.
The organising idea
Section titled “The organising idea”A Terraform pull request contains two things a reviewer must understand, and only one of them is in the diff.
The source diff shows what the configuration will say. The plan shows what will happen to real infrastructure if that configuration is applied — and the relationship between the two is not obvious. A variable default changed by one character can produce a plan that replaces a database, because a provider marked that attribute as forcing replacement.
Everything in this cluster follows from that gap:
The Git workflow puts the plan in front of the reviewer before the merge.
Repository structure and environments decide how large the blast radius of any one change can be.
Modules decide whether a shared change reaches production deliberately or by accident.
Pull request validation and CI/CD generate the evidence, and control who can act on it.
State is the one that bites hardest when misunderstood, because state is not a source file and treating it as one leaks secrets.
Branching decides how long a change can sit un-applied — which for infrastructure is a drift question rather than a merge-conflict question.
OpenTofu and the comparison cover the fork honestly: broadly compatible, genuinely divergent in places, and not a decision this site makes for you.
The decisions this cluster forces
Section titled “The decisions this cluster forces”Infrastructure repositories go wrong slowly. Nothing fails on the day a bad structural decision is made; it fails eighteen months later when a team of nine cannot ship a change without three people coordinating. These are the decisions that determine which way it goes.
How much does one apply touch? A single root module covering an entire account means every change plans against everything, every plan is slow, and one mistake reaches everything. Splitting it means more coordination and more state files. There is no free option — only a choice about which cost you prefer.
Who can change production, and how is that enforced? CODEOWNERS expresses ownership; a ruleset enforces review. Teams routinely add the first and assume they got the second.
What does production consume? A module referenced by branch changes underneath you the moment somebody merges. A module referenced by tag changes when somebody deliberately upgrades it. That one character in a source reference is the difference between an infrastructure estate you can reason about and one you cannot.
Where does state live and who can read it? State contains resource attributes, and resource attributes routinely include database passwords and private keys. Read access to a state backend is often equivalent to read access to your secrets.
How does a change reach environments? In order, with the same configuration and different values? Or as three independent changes that drift apart? The first is promotion. The second is how staging stops predicting anything about production.
How long does a change wait? An un-applied merged change is drift with a paper trail. Infrastructure branching strategy is mostly about minimising the window between merge and apply.
Each of those has a lesson. None has a universally correct answer, and any source claiming otherwise has not operated enough different estates.
Terraform and OpenTofu
Section titled “Terraform and OpenTofu”Both are covered. Where behaviour is shared, lessons say “Terraform” and the OpenTofu equivalent is the same command with a different binary name. Where behaviour genuinely differs — state encryption, early variable evaluation, the .tofu file extension — the lessons say so explicitly rather than pretending the tools are interchangeable.
This site takes no position on which you should use. The comparison lesson lays out what actually differs from a Git and workflow perspective and leaves the choice where it belongs.
A worked reading order
Section titled “A worked reading order”The lessons are numbered for sequence, but there are faster routes if you have a specific problem.
“Our Terraform reviews are rubber stamps.” Start with pull request validation, then the Git workflow. The usual cause is that reviewers cannot see the plan, so they approve the diff.
“We are frightened of our own repository.” Start with repository structure and environments. Fear is usually a blast-radius problem wearing a different hat.
“Somebody committed state.” Go straight to state and Git, and treat it as a credential exposure rather than a tidiness problem — the rotation guidance in Pillar 5 applies immediately.
“A module change broke production unexpectedly.” Modules with Git. Almost always a mutable source reference.
“We are evaluating OpenTofu.” OpenTofu with Git then the comparison.
What this cluster is not
Section titled “What this cluster is not”Not a Terraform language reference. Resource syntax, provider arguments and function signatures belong in the provider documentation, which is generated and correct.
Not a cloud architecture course. Whether you want a transit gateway is out of scope; how the decision to add one gets reviewed is not.
Not a duplicate of Pillar 4. Terraform CI and Terraform CD teach the workflow files. This cluster teaches the repository those workflows run against, and links across rather than repeating.