
When you reference a remote module (for example, from the Terraform Registry), running
terraform init in your working directory downloads the module into the local .terraform directory so Terraform can use it.Where modules come from
Parent (root/calling) module: module block
Amodule block in the root module tells Terraform to invoke a child module. The block has:
- A local name (for example,
module "vpc"). - A
sourcethat points to the child module location. - Additional arguments corresponding to the child module’s input variables.
- The module block name (
vpc) is a local identifier; choose a name that fits your codebase (for exampleprod_vpc,dev_vpc). - Keys inside the block (such as
name,cidr,azs) must match the variable names expected by the child module. - Values can be literals, parent variables (
var.*), outputs from data resources, or expressions.
Child module: variables, resources, and outputs
A child module is a regular Terraform configuration composed of:variableblocks to declare inputs,resourceblocks to create infrastructure,outputblocks to export values.
name and cidr and creates an AWS VPC resource:
- Resource blocks live in the child module; the parent normally does not contain resource blocks that the child creates.
- Variables are the module’s configuration surface and make the module reusable.
- Outputs expose values (for example, the VPC ID) so the parent or other modules can reference them.
Passing values and retrieving outputs
When the root (parent) module calls a child module, it passes input variables. The child uses those inputs to create resources, then exposes outputs that the parent can reference. Example flow showing a parent declaring a variable, calling a child module, and exporting the child’s output: Root module (calling the child module):modules/vpc or remote source) — simplified:
- The root module sets
cidr_blockand callsmodule "prod_vpc", passingcidr = var.cidr_blockandname = "my-vpc". - Terraform initializes and, if the module source is remote, downloads the module during
terraform init. - The child module receives inputs, creates resources (for example, an AWS VPC), and exposes outputs such as
vpc_id. - The parent references child outputs using
module.<MODULE_NAME>.<OUTPUT_NAME>, e.g.module.prod_vpc.vpc_id.
vpc_id as input where that value originates from module.prod_vpc.vpc_id. Chaining enables clear separation of responsibilities and reusability.
Ensure the input attribute names you provide in the parent module match the variable names declared in the child module. For example, if the child declares
variable "cidr", then the parent must pass cidr = ..., not vpc_cidr = ..., unless the child expects vpc_cidr.Quick comparison: Parent vs Child
Best practices
- Keep child modules focused on a single responsibility (for example: VPC, database, or IAM).
- Make modules configurable via variables; avoid hard-coded values.
- Export only necessary outputs to minimize coupling between modules.
- Version remote modules and pin versions to avoid unexpected changes.
- Document input variables and outputs inside module README files.