Terraform Modules
This domain tests your ability to create reusable infrastructure components, consume modules from various sources, manage module versioning, and understand when modules provide value versus when they add unnecessary complexity. HashiCorp does not publish objective weightings for Terraform Associate 004, so this is one of the estimated-even-weight topic areas under the current blueprint rather than a confirmed percentage — do not rely on a specific question count. Expect scenario-based questions asking you to identify correct syntax, choose the right module source type, trace outputs through module composition, and apply module best practices.
Module Structure: main.tf, variables.tf, outputs.tf, README.md
A Terraform module is any directory containing .tf files. The convention-based structure that the exam expects you to know:
| File | Purpose | Required? |
|---|---|---|
main.tf | Primary resource definitions and logic | Strongly recommended |
variables.tf | All variable blocks for the module | Strongly recommended |
outputs.tf | All output blocks for the module | Strongly recommended |
README.md | Human-readable documentation | Required for registry publishing |
versions.tf | terraform block with required providers | Best practice |
locals.tf | Local value definitions | Optional, common |
The exam treats main.tf, variables.tf, and outputs.tf as the canonical three-file structure. You do not have to use these filenames — Terraform reads all .tf files in a directory — but these names are the standard the exam tests.
README.md is specifically required for publishing to the Terraform Registry. A module without a README cannot be published there.
Common traps
- Believing you must split code across those three files — Terraform doesn't enforce filenames; convention is the only driver.
- Confusing
versions.tfwithvariables.tf. Theterraform { required_providers {} }block lives inversions.tfby convention, notvariables.tf. - Assuming a single
main.tfis invalid — a module with onlymain.tfis perfectly legal.
Root Module vs Child Modules
Root module: The working directory where you run terraform init / terraform apply. Every Terraform configuration has exactly one root module. It is the top-level caller.
Child module: Any module called by another module using a module block. A child module can itself call additional child modules (nested modules).
The root module is the top-level caller in a Terraform configuration.
Key behavioral differences:
| Attribute | Root Module | Child Module |
|---|---|---|
Where terraform apply runs | Here | Never directly |
| Can access provider config directly | Yes | Inherits from caller |
terraform.tfstate lives here | Yes | No separate state |
Uses source argument | No | Yes (required) |
| Version constraints apply | Via required_providers | Via version in module block |
Passing providers to child modules: By default, child modules inherit the default provider configurations from the root module. You can explicitly pass providers using the providers argument in the module block when non-default configurations are needed.
Common traps
- Thinking child modules have their own state files — they do not. State is always managed at the root level.
- Confusing "nested module" (a child module calling another child module) with a separate root module.
- Believing that running
terraform applyin a child module directory is the same as calling it from the root — it is a completely independent root invocation in that directory.
Unlock with a paid plan
11 more sections (about 2,603 words) continue below. Every paid plan unlocks all 004 study guides, the full question bank and mock exams, from $4.97/month.