Module Inputs and Outputs

Variables are a module's inputs; outputs are how it returns values to the caller.

Modules communicate through a clear contract: input variables flow in, outputs flow back out. Resources inside a module are private — the caller can only see declared outputs.

The pattern

  1. The module declares variable blocks (its inputs).
  2. The caller passes values in the module block.
  3. The module declares output blocks (its results).
  4. The caller reads them as module.NAME.OUTPUT.

This encapsulation keeps modules composable and easy to reason about.

Example

Example · hcl
# Inside modules/web-service/outputs.tf
output "url" {
  value       = "https://${aws_lb.this.dns_name}"
  description = "Public URL of the service"
}

# In the root module
module "web" {
  source        = "./modules/web-service"
  instance_type = "t3.small"
}

output "service_url" {
  value = module.web.url
}

When to use it

  • A VPC module outputs its vpc_id and subnet_ids so caller configurations can reference them when creating EC2 instances or load balancers.
  • A database module outputs the endpoint, port, and database name so an ECS task definition module can consume them as environment variables.
  • A caller uses module.network.vpc_id to feed the VPC module's output directly into a security group resource without storing the value in a variable.

More examples

Module outputs definition

Defines the outputs a VPC module exposes: the VPC ID and all private subnet IDs as a list.

Example · hcl
# modules/vpc/outputs.tf
output "vpc_id" {
  description = "ID of the created VPC"
  value       = aws_vpc.this.id
}

output "private_subnet_ids" {
  description = "List of private subnet IDs"
  value       = aws_subnet.private[*].id
}

Caller references module outputs

Shows the caller using module.name.output_name syntax to consume both the vpc_id and private_subnet_ids from the network module.

Example · hcl
module "network" {
  source     = "./modules/vpc"
  name       = "prod"
  cidr_block = "10.0.0.0/16"
}

resource "aws_security_group" "app" {
  vpc_id = module.network.vpc_id  # consume module output
  name   = "app-sg"
}

resource "aws_lb" "app" {
  subnets = module.network.private_subnet_ids
}

Pass module output to another module

Chains module outputs as inputs to another module, creating a dependency graph without any hard-coded resource IDs.

Example · hcl
module "network" {
  source = "./modules/vpc"
  name   = "prod"
}

module "database" {
  source            = "./modules/rds"
  vpc_id            = module.network.vpc_id
  subnet_ids        = module.network.private_subnet_ids
  allowed_sg_id     = module.app.security_group_id
}

Discussion

  • Be the first to comment on this lesson.