Terraform · Infrastructure as code
How do you compose multiple modules without creating a tangled architecture?
Short answer
Compose small modules with explicit inputs and outputs, and let the root module wire them together. Keep dependencies one-directional and avoid coupling modules through remote state or hidden globals.
Composition is the design of module boundaries and the data that crosses them. A healthy root module reads top to bottom: network, data, application, observability. Each child exposes only what the next layer needs, so a change in one module does not ripple through every caller.
module "network" {
source = "./modules/network"
cidr = "10.0.0.0/16"
}
module "app" {
source = "./modules/app"
subnet_id = module.network.private_subnet_ids[0]
}
module "observability" {
source = "./modules/observability"
app_arn = module.app.service_arn
}Rules that keep composition manageable
- Pass values through outputs rather than reading another stack's state
- Keep dependencies one-directional; avoid circular module references
- Use separate state per lifecycle and blast radius
- Prefer a few focused modules over one god module with flags
- Version shared modules and test their interfaces
Passing providers explicitly is sometimes necessary for multi-region modules, but it couples the child to a provider configuration. Do it deliberately and document it. Similarly, terraform_remote_state is convenient but creates a runtime coupling to another stack's state schema and access controls.
Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1How do you avoid circular dependencies between modules?
- 2When is terraform_remote_state the wrong integration?
- 3How do you pass a provider to a child module?
- 4What signals that a module has grown too large?
Say it in the interview
I compose modules by keeping them small and letting the root module wire outputs into inputs. Dependencies should flow in one direction, and children should not read each other's state. If a module needs a second provider, I pass it deliberately and document the coupling. The main failure mode I watch for is a god module that owns everything and turns every change into a high-risk plan.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Terraform mock interview and get scored feedback on depth, clarity and confidence.