Terraform modules are reusable packages of .tf configuration. A root module calls child modules (local or registry) with input variables and receives output values — enabling DRY, composable, testable infrastructure.
GitOps-style Terraform pipeline with plan-then-apply pattern and saved plan files.
Source can be: local path (./modules/network), Terraform Registry (hashicorp/consul/aws), git URL (git::https://...), or GitHub shorthand (github.com/org/repo//module). Pin versions in production.
Use for_each = var.environments on a module block to create multiple instances with different variables. Cleaner than copy-pasting module blocks. Access each with module.name[key].output.
Terraform locks state during apply. If apply is interrupted, state is partially written. Run terraform refresh + plan to reconcile. Never manually edit tfstate in production.
Pass module outputs as inputs to other modules: subnet_id = module.network.subnet_id. Terraform resolves the dependency graph and deploys in the correct order.
Pass providers explicitly to modules using the providers meta-argument when a module needs a different provider config (e.g., multi-subscription deployments). Required when aliasing providers.
Use Terratest (Go) to write integration tests for modules. Deploy to a real subscription, verify outputs, tear down. Run in CI for every module change — catches provider API breaking changes.
Sign in to share your feedback and join the discussion.