Terraform Tutorial — Module Inputs and Outputs

1 minute read

Modules communicate through inputs (variables) and outputs. Inputs flow in, outputs flow out.


Inputs: Passing Variables to a Module

The module’s variables.tf defines what it accepts:

# modules/ec2/variables.tf
variable "instance_type" {
  type    = string
  default = "t3.micro"
}

variable "ami_id" {
  type = string
}

variable "subnet_id" {
  type = string
}

The caller passes values:

# main.tf (root)
module "web_server" {
  source = "./modules/ec2"

  ami_id        = data.aws_ami.amazon_linux.id
  instance_type = "t3.small"
  subnet_id     = module.vpc.public_subnet_ids[0]
}

Outputs: Receiving Values from a Module

The module’s outputs.tf exposes values:

# modules/ec2/outputs.tf
output "instance_id" {
  value = aws_instance.this.id
}

output "public_ip" {
  value = aws_instance.this.public_ip
}

The caller accesses them:

# main.tf (root)
output "web_server_ip" {
  value = module.web_server.public_ip
}

resource "aws_route53_record" "web" {
  zone_id = data.aws_route53_zone.main.zone_id
  name    = "web.example.com"
  type    = "A"
  ttl     = 300
  records = [module.web_server.public_ip]
}

Chaining Modules

Output from one module → Input to another:

module "vpc" {
  source     = "./modules/vpc"
  cidr_block = "10.0.0.0/16"
}

module "web" {
  source    = "./modules/ec2"
  subnet_id = module.vpc.public_subnet_ids[0]   # ← VPC output → EC2 input
  ami_id    = data.aws_ami.amazon_linux.id
}

module "database" {
  source    = "./modules/rds"
  vpc_id    = module.vpc.vpc_id                  # ← VPC output → RDS input
  subnet_ids = module.vpc.private_subnet_ids
}

Required vs Optional Inputs

Variable has default? Required at call site?
No default ✅ Must be provided
Has default ❌ Optional (uses default if omitted)
# Module declares:
variable "instance_type" {
  default = "t3.micro"  # optional
}
variable "ami_id" {
  # no default            # required
}

# Caller:
module "web" {
  source = "./modules/ec2"
  ami_id = "ami-123"
  # instance_type not provided → uses default "t3.micro"
}

What’s Next?

Let’s explore the Terraform Registry — a library of pre-built, community-maintained modules.


← Calling a Module Terraform Registry Modules →