0
0
Terraformcloud~15 mins

Creating a child module in Terraform - Mechanics & Internals

Choose your learning style9 modes available
Overview - Creating a child module
What is it?
Creating a child module in Terraform means making a reusable set of infrastructure code that can be called from another Terraform configuration. It helps organize and share common infrastructure patterns by grouping resources, variables, and outputs together. This way, you can use the same module multiple times without rewriting code. Child modules are like building blocks that simplify managing complex infrastructure.
Why it matters
Without child modules, Terraform configurations become long, repetitive, and hard to manage. Changes would need to be copied everywhere, increasing errors and slowing down updates. Child modules solve this by letting you write code once and reuse it safely, saving time and reducing mistakes. This makes infrastructure more reliable and easier to understand, especially as projects grow.
Where it fits
Before learning child modules, you should understand basic Terraform concepts like resources, variables, and outputs. After mastering child modules, you can explore advanced topics like module composition, versioning, and publishing modules for teams. Child modules are a key step from simple scripts to scalable infrastructure as code.
Mental Model
Core Idea
A child module is a self-contained package of Terraform code that you can plug into other configurations to reuse and organize infrastructure efficiently.
Think of it like...
Think of a child module like a recipe card in a cookbook. Instead of writing the full recipe every time you want to cook a dish, you just refer to the card. This keeps your cooking organized and consistent, just like modules keep your infrastructure code neat and reusable.
Root Configuration
└── calls ──> Child Module
      ├── variables
      ├── resources
      └── outputs
Build-Up - 7 Steps
1
FoundationUnderstanding Terraform Modules Basics
🤔
Concept: Modules group Terraform resources and configurations into reusable units.
Terraform modules are folders with Terraform files that define resources, variables, and outputs. The root module is the main folder where you run Terraform commands. Child modules are separate folders you can call from the root module using the 'module' block.
Result
You know that modules are just folders with Terraform code that can be reused.
Understanding that modules are just code folders helps you see how Terraform organizes infrastructure logically.
2
FoundationCreating a Simple Child Module Folder
🤔
Concept: A child module is created by making a folder with Terraform files defining resources and variables.
Create a folder named 'child_module'. Inside, add main.tf with resource definitions, variables.tf for inputs, and outputs.tf for outputs. This folder is your child module.
Result
You have a child module folder ready to be called from another configuration.
Knowing the folder structure and files needed is the first step to building reusable modules.
3
IntermediateCalling a Child Module from Root Module
🤔Before reading on: Do you think you must copy child module code into root to use it, or can you reference it directly? Commit to your answer.
Concept: You use the 'module' block in the root module to reference and use a child module by its folder path.
In the root module's main.tf, add: module "example" { source = "./child_module" variable_name = "value" } This tells Terraform to use the child module code from the folder and pass variables.
Result
Terraform knows to include the child module's resources when applying infrastructure.
Referencing modules by path avoids code duplication and enables clean reuse.
4
IntermediatePassing Variables to Child Modules
🤔Before reading on: Do you think child modules can access root variables automatically, or must variables be passed explicitly? Commit to your answer.
Concept: Variables must be explicitly passed from the root module to the child module through the module block.
Define variables in child module's variables.tf. Then, in root module's module block, assign values: module "example" { source = "./child_module" var1 = "value1" var2 = "value2" } This passes inputs to the child module.
Result
Child module receives the values it needs to create resources correctly.
Explicit variable passing keeps modules independent and predictable.
5
IntermediateUsing Outputs from Child Modules
🤔
Concept: Child modules can expose outputs that the root module can use after applying infrastructure.
In child module's outputs.tf, define outputs: output "resource_id" { value = aws_instance.example.id } In root module, access with: module.example.resource_id This lets root module use child module results.
Result
You can connect resources and data between modules cleanly.
Outputs create clear interfaces between modules, enabling modular design.
6
AdvancedOrganizing Complex Infrastructure with Nested Modules
🤔Before reading on: Can child modules call other child modules, or is nesting not allowed? Commit to your answer.
Concept: Modules can call other modules, allowing deep nesting and complex infrastructure organization.
Inside a child module, you can add module blocks to call other modules. This creates layers of modules, each handling parts of infrastructure. For example, a network module can call a subnet module.
Result
You can build scalable, maintainable infrastructure by composing modules.
Nesting modules enables breaking down complex systems into manageable pieces.
7
ExpertVersioning and Publishing Child Modules
🤔Before reading on: Do you think child modules must always be local folders, or can they be shared remotely? Commit to your answer.
Concept: Modules can be versioned and published to registries or repositories for team sharing and reuse.
Instead of local paths, use module sources like Git URLs or Terraform Registry: module "example" { source = "git::https://github.com/org/module.git?ref=v1.0.0" } This allows teams to share stable module versions.
Result
Modules become reusable components across projects and teams with controlled versions.
Versioning modules prevents unexpected changes and supports collaboration.
Under the Hood
Terraform treats modules as isolated folders containing configuration files. When you run Terraform, it reads the root module and recursively loads child modules by their source paths. Variables are passed as inputs, and outputs are collected as results. Terraform builds a dependency graph including all modules, then plans and applies resources in order. Modules help Terraform organize and reuse code without duplicating resource definitions.
Why designed this way?
Modules were designed to solve the problem of repetitive infrastructure code and to encourage reuse. By isolating code in folders with clear input/output interfaces, Terraform allows teams to build composable infrastructure. Alternatives like copy-pasting code were error-prone and hard to maintain. The module system balances simplicity with flexibility, enabling both local and remote reuse.
Root Module
┌─────────────────────┐
│ main.tf             │
│ module "child"     │───┐
└─────────────────────┘   │
                          ▼
                   Child Module
                 ┌───────────────┐
                 │ variables.tf  │
                 │ main.tf       │
                 │ outputs.tf    │
                 └───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Do you think child modules automatically share variables with the root module? Commit to yes or no.
Common Belief:Child modules can access root module variables without passing them explicitly.
Tap to reveal reality
Reality:Variables must be explicitly passed from the root module to child modules; there is no automatic sharing.
Why it matters:Assuming automatic sharing causes modules to fail or behave unpredictably, leading to wasted debugging time.
Quick: Do you think modules are only for large projects? Commit to yes or no.
Common Belief:Modules are only useful for big infrastructure setups and add unnecessary complexity for small projects.
Tap to reveal reality
Reality:Modules are beneficial even for small projects by improving organization and enabling future growth.
Why it matters:Avoiding modules early can lead to messy code and harder scaling later.
Quick: Do you think you can modify a module's code directly after calling it remotely? Commit to yes or no.
Common Belief:Once you use a remote module, you can edit its code directly in your project folder.
Tap to reveal reality
Reality:Remote modules are read-only; to change them, you must update the source repository or override with local modules.
Why it matters:Trying to edit remote modules locally causes confusion and breaks version control.
Quick: Do you think nesting modules infinitely is always good? Commit to yes or no.
Common Belief:You can nest modules as deep as you want without any downsides.
Tap to reveal reality
Reality:Excessive nesting adds complexity and can slow down Terraform operations and understanding.
Why it matters:Over-nesting makes debugging and maintenance harder, reducing productivity.
Expert Zone
1
Modules should have clear, minimal interfaces; exposing too many variables or outputs makes them hard to use and maintain.
2
Using locals inside modules can simplify complex expressions and avoid repeating logic, improving readability.
3
Careful version pinning of remote modules prevents unexpected breaking changes during Terraform runs.
When NOT to use
Avoid modules when you need very simple, one-off resources that won't be reused, as modules add overhead. For dynamic or highly customized infrastructure, consider using Terraform's dynamic blocks or external tools instead of forcing everything into modules.
Production Patterns
In production, teams publish shared modules to private registries with strict versioning. They use nested modules to separate concerns like networking, compute, and security. Continuous integration pipelines validate module changes before deployment to ensure stability.
Connections
Software Functions
Modules are like functions that take inputs and return outputs, encapsulating logic.
Understanding modules as functions helps grasp their purpose: reuse, abstraction, and clear interfaces.
Object-Oriented Programming (OOP)
Modules resemble classes or objects that bundle data and behavior for reuse.
Seeing modules as objects clarifies why encapsulation and interfaces matter in infrastructure code.
Manufacturing Assembly Lines
Modules are like standardized parts in an assembly line, combined to build complex products efficiently.
This cross-domain view shows how modular design improves scalability and quality control.
Common Pitfalls
#1Not passing required variables to child modules causes errors.
Wrong approach:module "example" { source = "./child_module" # missing required variables }
Correct approach:module "example" { source = "./child_module" var1 = "value1" var2 = "value2" }
Root cause:Misunderstanding that child modules need explicit inputs leads to missing variable errors.
#2Editing remote module code locally expecting changes to apply.
Wrong approach:# Edit files inside .terraform/modules/remote_module # expecting Terraform to use these changes
Correct approach:# Fork the remote module repository # Make changes there # Update module source to your fork with version
Root cause:Not realizing remote modules are cached and read-only causes confusion and wasted effort.
#3Over-nesting modules making configuration hard to follow.
Wrong approach:module "a" { source = "./module_b" } module "b" { source = "./module_c" } module "c" { source = "./module_d" }
Correct approach:Flatten module calls to reasonable depth, grouping related resources logically without deep nesting.
Root cause:Believing more nesting always improves organization leads to complexity and maintenance issues.
Key Takeaways
Child modules in Terraform are reusable folders of infrastructure code that help organize and simplify configurations.
You must explicitly pass variables to child modules and use outputs to get results back, ensuring clear interfaces.
Modules can be nested and versioned, enabling scalable and maintainable infrastructure across teams.
Misunderstanding variable passing or remote module immutability causes common errors and confusion.
Expert use involves minimal interfaces, version control, and balanced nesting to keep infrastructure clean and reliable.