Module composition patterns in Terraform - Time & Space Complexity
When using modules in Terraform, it's important to understand how the number of modules affects the work Terraform does.
We want to know how the time to apply changes grows as we add more modules.
Analyze the time complexity of this Terraform module composition.
module "network" {
source = "./modules/network"
count = var.network_count
}
module "compute" {
source = "./modules/compute"
count = var.compute_count
}
module "storage" {
source = "./modules/storage"
count = var.storage_count
}
This code creates multiple instances of three different modules based on input counts.
Look at what repeats when Terraform runs this code.
- Primary operation: Creating each module instance involves API calls to provision resources inside that module.
- How many times: The total number of module instances is the sum of all counts (network_count + compute_count + storage_count).
As you increase the number of modules, the work grows in a simple way.
| Input Size (total modules) | Approx. API Calls/Operations |
|---|---|
| 10 | About 10 module creations |
| 100 | About 100 module creations |
| 1000 | About 1000 module creations |
Pattern observation: The number of operations grows directly with the number of modules added.
Time Complexity: O(n)
This means the time to apply grows in a straight line as you add more modules.
[X] Wrong: "Adding more modules won't affect apply time much because modules are just code."
[OK] Correct: Each module creates real resources, so more modules mean more API calls and longer apply times.
Understanding how module counts affect apply time helps you design scalable infrastructure and explain your choices clearly.
"What if modules were nested inside other modules? How would that change the time complexity?"
Practice
Solution
Step 1: Understand module composition
Module composition means connecting modules by using outputs from one as inputs to another.Step 2: Recognize benefits
This approach keeps infrastructure code organized, reusable, and easier to manage.Final Answer:
To combine multiple modules by passing outputs as inputs for better organization -> Option AQuick Check:
Module composition = combining modules with outputs as inputs [OK]
- Thinking modules should be combined by copying code
- Believing variables are avoided in module composition
- Assuming modules work independently without connections
Solution
Step 1: Recall Terraform module output reference syntax
Outputs from a module are accessed usingmodule.<module_name>.<output_name>.Step 2: Compare options
Only module.moduleA.output_name matches the correct syntax for accessing module outputs.Final Answer:
module.moduleA.output_name -> Option BQuick Check:
Module output reference = module.module_name.output_name [OK]
- Using var or resource instead of module to access outputs
- Confusing output blocks with module references
- Using incorrect keywords like output.moduleA
moduleB's input instance_id?
module "moduleA" {
source = "./moduleA"
}
module "moduleB" {
source = "./moduleB"
instance_id = module.moduleA.instance_id
}Solution
Step 1: Identify module output usage
The inputinstance_idfor moduleB is assigned frommodule.moduleA.instance_id, which means it uses the output namedinstance_idfrom moduleA.Step 2: Understand value passing
This passes the actual value of moduleA's output to moduleB's input, not a string or error.Final Answer:
The value of the output named instance_id from moduleA -> Option AQuick Check:
moduleB.instance_id = moduleA.instance_id output value [OK]
- Thinking it passes a string literal instead of value
- Assuming syntax error due to missing variable declaration
- Confusing inputs and outputs between modules
moduleA outputs vpc_id, and moduleB requires vpc_id as input. The following code causes an error:
module "moduleA" {
source = "./moduleA"
}
module "moduleB" {
source = "./moduleB"
vpc_id = var.vpc_id
}
What is the most likely cause of the error?Solution
Step 1: Check input assignment in moduleB
moduleB expectsvpc_idinput, but it is assigned fromvar.vpc_id, which is a variable, not the output from moduleA.Step 2: Identify correct way to pass output
The correct way is to assignvpc_id = module.moduleA.vpc_idto pass the output from moduleA.Final Answer:
moduleB is using var.vpc_id instead of module.moduleA.vpc_id as input -> Option CQuick Check:
Pass outputs via module.moduleA.output, not var [OK]
- Assuming var.vpc_id automatically links to moduleA output
- Ignoring the need to explicitly connect modules
- Thinking Terraform cannot pass outputs between modules
moduleC depends on outputs from both moduleA and moduleB. Which pattern correctly composes these modules to pass outputs as inputs to moduleC?
// Option A
module "moduleC" {
source = "./moduleC"
inputA = module.moduleA.outputA
inputB = module.moduleB.outputB
}
// Option B
module "moduleC" {
source = "./moduleC"
inputA = var.outputA
inputB = var.outputB
}
// Option C
module "moduleC" {
source = "./moduleC"
inputA = module.moduleB.outputB
inputB = module.moduleA.outputA
}
// Option D
module "moduleC" {
source = "./moduleC"
inputA = module.moduleA.outputB
inputB = module.moduleB.outputA
}Solution
Step 1: Match inputs to correct module outputs
Pass outputs correctly matching input names from moduleA and moduleB passesinputAfrommoduleA.outputAandinputBfrommoduleB.outputB, matching names correctly.Step 2: Evaluate other options
Use variables instead of module outputs for inputs uses variables instead of outputs, which breaks composition. Swap inputs but still use correct module outputs swaps the assignments, mismatching inputA (expects moduleA.outputA) with moduleB.outputB and inputB with moduleA.outputA. Mix outputs incorrectly between modules mixes outputs incorrectly, likely causing errors.Final Answer:
Pass outputs correctly matching input names from moduleA and moduleB -> Option DQuick Check:
Correct output-to-input mapping = Pass outputs correctly matching input names from moduleA and moduleB [OK]
- Swapping outputs between modules without checking input expectations
- Using variables instead of module outputs
- Mixing output names incorrectly causing runtime errors
Ready to prove it?
Pass the test and this pattern moves unknown
