Skip to main content
Fix Terraform Error: Invalid Reference to Module Output

Fix Terraform Error: Invalid Reference to Module Output

Key Takeaway

Fix terraform invalid reference to module output errors. Check module names, declare outputs, handle count/for_each modules, and debug with terraform console.

Table of Contents

Quick Answer

# 1. Check the module name matches
module "networking" { source = "./modules/vpc" }
# Use: module.networking.vpc_id (NOT module.vpc.vpc_id)

# 2. Check the output is declared in the module
# modules/vpc/outputs.tf must have:
output "vpc_id" { value = aws_vpc.main.id }

The Error

Error: Reference to undeclared module

  on main.tf line 20:
  20: vpc_id = module.vpc.vpc_id

No module call named "vpc" is declared in the root module.

Or:

Error: Unsupported attribute

  on main.tf line 20:
  20: vpc_id = module.networking.vpc_id

This object has no argument, nested block, or exported attribute named "vpc_id".

What Causes This

  1. Module name mismatch — calling it module "networking" but referencing module.vpc
  2. Output not declared — the module doesn’t have that output in outputs.tf
  3. Typo in output namevpc_id vs vpcId vs VPC_id
  4. Module not initialized — haven’t run terraform init
  5. count/for_each module — need module.vpc[0] or module.vpc["key"]

Solution 1: Match Module Name to Reference

# The module block name is what you reference
module "networking" {     # ← This is the name
  source = "./modules/vpc"
}

# Reference uses the block name, NOT the source directory
resource "aws_instance" "web" {
  subnet_id = module.networking.public_subnet_ids[0]  # ✅
  # NOT: module.vpc.public_subnet_ids[0]               ❌
}

Solution 2: Declare the Output in the Module

If the output doesn’t exist in the module, add it:

# modules/vpc/outputs.tf
output "vpc_id" {
  description = "ID of the VPC"
  value       = aws_vpc.main.id
}

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

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

Then re-init:

terraform init
terraform plan

Solution 3: Handle count/for_each Modules

module "vpc" {
  count  = var.create_vpc ? 1 : 0
  source = "./modules/vpc"
}

# Must use index
resource "aws_instance" "web" {
  subnet_id = module.vpc[0].public_subnet_ids[0]     # ✅ with count
  # NOT: module.vpc.public_subnet_ids[0]               ❌
}

# Safe access
locals {
  vpc_id = try(module.vpc[0].vpc_id, null)
}
module "vpc" {
  for_each = var.vpcs
  source   = "./modules/vpc"
  vpc_cidr = each.value.cidr
}

# Reference by key
resource "aws_instance" "web" {
  subnet_id = module.vpc["production"].public_subnet_ids[0]   # ✅ with for_each
}

Solution 4: Debug with terraform console

terraform console

# List all module outputs
> module.networking

# Check specific output
> module.networking.vpc_id

# List available outputs
> keys(module.networking)

Solution 5: Check Available Outputs

# List what the module exposes
grep -n "^output" modules/vpc/outputs.tf
3: output "vpc_id" {
8: output "vpc_cidr" {
13: output "public_subnet_ids" {
18: output "private_subnet_ids" {

If the output you need isn’t listed, add it.

Common Mistakes

# ❌ Using source path as module name
module "app" { source = "./modules/vpc" }
vpc_id = module.vpc.vpc_id     # Wrong — name is "app"

# ❌ Missing outputs.tf in module
# The module has resources but no output blocks

# ❌ Output references non-existent resource
output "vpc_id" {
  value = aws_vpc.this.id   # But resource is named aws_vpc.main
}

# ❌ Referencing module before init
# terraform plan without terraform init

Hands-On Courses

Conclusion

Module output errors come from three places: wrong module name in the reference (use the module "name" block name, not the source path), missing output declaration in the module’s outputs.tf, or missing index on count/for_each modules. Debug with terraform console to inspect available outputs.

🚀

Level Up Your Terraform Skills

Hands-on courses, books, and resources from Luca Berton

Luca Berton
Written by

Luca Berton

DevOps Engineer, AWS Partner, Terraform expert, and author. Creator of Ansible Pilot, Terraform Pilot, and CopyPasteLearn.