Copyright (c) 2026 MindMesh Academy. All rights reserved. This content is proprietary and may not be reproduced or distributed without permission.

5.2.1. Calling Modules and Variable Scope

💡 First Principle: Variables are scoped to the module that declares them, so passing vpc_cidr = "10.0.0.0/16" in a module block isn't "setting a global" — it's binding an argument to that child's var.vpc_cidr, invisible to every other module.

When you call a module, each argument in the module block maps to an input variable the child module declares. The child uses those values internally via var.<name>. Crucially, the child cannot see the parent's variables, locals, or resources — only what's passed in. This isolation is what makes modules safely reusable: a module behaves the same no matter who calls it.

# root module
module "web" {
  source        = "./modules/web"
  instance_type = var.web_size   # parent's var becomes child's argument
}
# inside ./modules/web, the child declares:  variable "instance_type" {}

⚠️ Exam Trap: Setting an argument in a module block requires the child to have declared a matching variable. Passing an argument the child doesn't declare is an error. And the parent's var.web_size and the child's var.instance_type are different variables in different scopes that happen to be connected by the call.

Reflection Question: Why is module variable isolation a feature rather than a limitation — what would break if child modules could read parent variables directly?

Alvin Varughese
Written byAlvin Varughese
Founder18 professional certifications