- Modules introduce abstraction. Abstraction reduces duplication and centralizes logic, but it also adds an indirection layer you must understand.
- When teams copy/paste resource blocks across environments, small mistakes (typos, inconsistent tags, wrong SKUs) accumulate and increase drift.
- Modules let you define a resource pattern once and reuse it across
dev,test, andprod, making updates consistent and predictable.
- Without modules:
dev/main.tf,test/main.tf,prod/main.tf(each contains repeated resource blocks)
- With modules:
modules/storage/main.tf(storage logic defined once)dev/main.tf,test/main.tf,prod/main.tf(each calls the storage module)
module blocks in the root configuration to instantiate the module instead of copying resource blocks.
Callout on best practice
DRY (Don’t Repeat Yourself) is a core engineering principle: if you are replicating the same logic multiple times across environments, modularize it. Modules reduce duplication, increase consistency, and make updates easier to apply at scale.

Governance example
- Problem: Your company decides all storage accounts must use Geo-Redundant Storage (GRS) instead of Locally Redundant Storage (LRS).
- Without modules: you must find and edit every individual storage account block across the repo — easy to miss one.
- With modules: change the replication setting inside
modules/storage/main.tfand every instance inherits the new default.
- Wrong resource group or region
- Misspelled SKUs or missing tags
- Inconsistent lifecycle or identity settings
- Resource modules: focused on single services (e.g., Storage, Virtual Machines, API Management).
- Pattern modules: opinionated, higher-level architectures (e.g., AKS Enterprise, Container Apps Landing Zone, ALZ Connectivity Hub).

- Usage documentation (inputs, outputs, examples)
- Recommended configuration and dependency guidance
- Versioned releases so you can pin module versions for stability

- Keep module responsibilities narrow — one logical purpose per module (e.g., storage, network, compute).
- Document inputs and outputs clearly.
- Version modules and pin module sources in root configs.
- Apply governance via module inputs and policy-as-code where possible.
- Reuse AVM modules for common patterns and customize when organizational policy requires it.
- Azure Verified Modules (AVM): https://github.com/Azure/azure-verified-modules
- Terraform documentation: https://www.terraform.io/docs
- Azure Landing Zones guidance: https://learn.microsoft.com/azure/cloud-adoption-framework/landing-zones/