Ravindra BagaleCourses & study guides मराठी Track your progress

Guides

Terraform Modules Explained: Reuse VPC and EC2 Code

Put VPC and EC2 in module folders with variables and outputs, call them from root, wire outputs to inputs, init, validate, and pin versions.

Friends, a module is a function for infrastructure. Chala mitrano — call it with different variables for Mumbai and Frankfurt, do not copy folders.

Quick answer

Hold this vertical picture:

  1. Create modules/vpc and modules/ec2.
  2. Add variables and outputs.
  3. Call from root main.tf.
  4. Wire vpc output to ec2.
  5. init, validate, plan; pin refs.

Language: English · मराठी · हिंदी

modules/vpcInputs + outputs modules/ec2Needs subnet root main.tfCalls both terraform initLoad modules plan/applySame code, new vars
Module reuse

Why modules

Stop copy-paste drift across envs.

Why: Two edited copies diverge every week. What: Folder modules with inputs/outputs. How: Root calls with different vars.

Example 1: Module folder layout

Type this:

mkdir -p /tmp/tfmod/modules/vpc && printf '%s\n' 'variable "cidr" { type = string }' 'output "vpc_id" { value = "vpc-demo" }' > /tmp/tfmod/modules/vpc/main.tf && ls /tmp/tfmod/modules/vpc

You will see:

main.tf

What it means: A module is a folder with variables, resources, outputs.

Example 2: Root calls the module

Type this:

printf '%s\n' 'module "vpc" {' '  source = "./modules/vpc"' '  cidr   = "10.0.0.0/16"' '}' > /tmp/tfmod/main.tf && cat /tmp/tfmod/main.tf

You will see:

module "vpc" {

What it means: source points at the folder; inputs are arguments.

Example 10: Do not copy-paste stacks

Type this:

printf '%s\n' 'ok: one vpc module called from dev and prod with different cidr'

You will see:

ok: one vpc module called from dev and prod with different cidr

What it means: Copy-paste drifts — modules stop that.

Concept 1: Wire modules

Outputs feed the next module.

Why: Hard-coded subnet ids break reuse. What: module.vpc outputs → module.web inputs. How: Root outputs for CI.

Example 3: EC2 module sketch

Type this:

mkdir -p /tmp/tfmod/modules/ec2 && printf '%s\n' 'variable "instance_type" { type = string }' 'variable "subnet_id" { type = string }' 'output "instance_id" { value = "i-demo" }' > /tmp/tfmod/modules/ec2/main.tf && cat /tmp/tfmod/modules/ec2/main.tf

You will see:

variable "instance_type" { type = string }

What it means: EC2 module takes subnet from VPC output later.

Example 4: Wire VPC output to EC2

Type this:

printf '%s\n' 'module "web" {' '  source        = "./modules/ec2"' '  instance_type = "t3.micro"' '  subnet_id     = module.vpc.vpc_id' '}' >> /tmp/tfmod/main.tf && tail -6 /tmp/tfmod/main.tf

You will see:

subnet_id     = module.vpc.vpc_id

What it means: Outputs become inputs — Flipkart-style reuse.

Example 9: Output from root

Type this:

printf '%s\n' 'output "web_id" { value = module.web.instance_id }' > /tmp/tfmod/outputs.tf && cat /tmp/tfmod/outputs.tf

You will see:

output "web_id" { value = module.web.instance_id }

What it means: Root outputs expose what CI needs.

Concept 2: Init and plan

Terraform loads module source.

Why: Skipping init leaves empty module cache. What: init; validate; plan. How: Addresses use module. prefix.

Example 5: terraform init for modules

Type this:

printf '%s\n' 'terraform init'

You will see:

terraform init

What it means: Downloads/copies module source into .terraform.

Example 6: Plan shows module addresses

Type this:

printf '%s\n' 'terraform plan  # addresses look like module.vpc.aws_vpc.this'

You will see:

terraform plan  # addresses look like module.vpc.aws_vpc.this

What it means: Module prefix keeps state tidy.

Example 11: Validate

Type this:

printf '%s\n' 'terraform validate'

You will see:

terraform validate

What it means: Catches type mistakes before plan.

Concept 3: Pin and contract

Version pins; clear inputs/outputs.

Why: Floating main tags surprise prod. What: ref=vX.Y.Z; document variables. How: Resources stay inside the module.

Example 7: Version pin for remote modules

Type this:

printf '%s\n' 'source = "git::ssh://git.example.internal/tf/vpc.git?ref=v1.2.0"'

You will see:

source = "git::ssh://git.example.internal/tf/vpc.git?ref=v1.2.0"

What it means: Pin ref= — never float on main for prod.

Example 8: Locals for defaults

Type this:

printf '%s\n' 'locals { name_prefix = "pay-dev" }'

You will see:

locals { name_prefix = "pay-dev" }

What it means: Locals keep repeated tags DRY.

Example 12: Module contract

Type this:

printf '%s\n' 'Inputs = variables; outputs = return values; resources stay private inside'

You will see:

Inputs = variables; outputs = return values; resources stay private inside

What it means: Interview one-liner at Cognizant.

Modules card

1 Create module folder 2 variables + outputs 3 module block in root 4 wire outputs→inputs 5 init/validate/plan 6 pin versions

Suppose: unknown variable

Declare variable in the module; pass it from root.

Suppose: wrong source path

Check relative path or git ref.

Ravindra Bagale's Tip

At Accenture reviews, unpinned module sources on main are a finding. Always ref=vX.Y.Z for shared modules.

Check yourself (quiz)

Q1. What is a module?

Reusable Terraform folder

Q2. How does root use it?

module block + source

Q3. Wire pattern?

output → input

Q4. Why pin ref?

Reproducible prod

Q5. validate?

Catch type errors early

Q6. Copy-paste stacks?

No — call the module

Reading tracking

Mark this guide when you finish. Your browser remembers it on this device.

module folder → call → wire → init → plan. Did you understand? Let us try it once more.

Frequently asked questions

Module vs resource?

Module groups resources with a contract.

Local vs remote source?

Local for learning; remote pinned for teams.

Can modules nest?

Yes — keep depth small.

Where do providers go?

Usually root; pass aliases carefully.

Count/for_each on modules?

Supported — advanced.

Why outputs?

Hide internals; expose only what callers need.