Lesson 15 · Senior IaC judgment

Module and Terragrunt API design: inputs, outputs, coupling, and scaling costs

How to think about modules and Terragrunt leaves as APIs, why DRY is not free, and how scaling a Terraform repo changes what “good design” looks like.

Your win: explain why module and Terragrunt structure are really API-design decisions, describe the repo’s scaling trade-offs honestly, and review Terraform layout choices without defaulting to “more DRY is always better.”

In plain English Plain English: modules and Terragrunt layouts are not just folder organization — they define how teams consume infrastructure building blocks and how safely they can change them later.

Why API thinking matters here

It is tempting to think of Terraform structure as mostly a file-layout concern. But once a repo grows, layout choices become interface choices. Inputs, outputs, dependencies, inherited config, and shared component logic start behaving like APIs that other engineers and automation systems depend on.

This repo is a good example. It has reusable modules, thin leaves, shared root config, env-org expansion, and dependency wiring that stretches across many components. That means a structural choice in Terraform is rarely only local. It often changes how many other leaves or workflows become easier or harder to reason about.

That is why the senior question here is not simply “is this DRY?” The better question is “what contract does this abstraction create for everyone else who has to use, review, debug, or extend it later?”

The API-design rule A strong answer explains modules and Terragrunt structure as interfaces: what a consumer must provide, what they get back, how much coupling is introduced, and how much future change pain the abstraction creates.

Why DRY helps — and why it can still hurt

Terragrunt and shared modules exist because repeating backend, provider, and dependency wiring hundreds of times would be painful and error-prone. That is the clear benefit. But abstraction is never free. If too much logic becomes indirect, the cost shifts from duplication to discoverability.

That is the trade-off a senior reviewer should be able to name. A structure can be beautifully DRY and still be harder for a newcomer to trace. A dependency chain can be technically correct and still make blast radius less obvious during review.

Backend use case In this repo, root.hcl, shared _env/*.hcl files, thin leaves, and cross-component dependency blocks keep the matrix manageable — but they also mean engineers must understand inheritance and wiring patterns before a change feels truly local.
Common mistake Praising a Terraform/Terragrunt layout as “clean and DRY” without asking whether consumers can still trace inputs, outputs, and blast radius quickly enough during review or incident response.

What stronger answers sound like

The strongest answers here sound like: “modules and Terragrunt leaves are infrastructure APIs; DRY matters, but the real question is whether consumers can still understand the contract, follow dependencies, and predict change impact without reverse-engineering too much hidden wiring.”

That answer is stronger because it treats layout as an operational interface, not just code style.

Read this next

Re-read Terragrunt and modules with interface thinking

Use the repo map and Terragrunt docs together so the abstraction boundaries stay concrete.

Terragrunt — Config blocks
HashiCorp — Modules
Repo IaC map

Check yourself (from memory)

Q1. Why is module/Terragrunt structure a senior IaC topic?

The real issue is interface quality, coupling, and operational readability at scale.
What is the senior way to review a Terraform/Terragrunt abstraction?
recall, then click to reveal
Review it like an API: what inputs are required, what outputs are produced, what dependencies are hidden or exposed, how easy blast radius is to see, and whether DRY has started to cost too much discoverability.
Want a “review this abstraction boundary” drill? Ask me.

Sources. Official Terraform/Terragrunt docs; repo IaC map.