Tình huống
Đã muộn. Bạn đang kết nối một module mới để truyền VPC ID hoặc ARN sang resource khác, chạy terraform plan, và nhận ngay thông báo lỗi này:
Error: Reference to undeclared output value
on main.tf line 14, in resource "aws_instance" "app":
14: subnet_id = module.network.subnet_id
An output value with the name "subnet_id" has not been declared in module.network.
Module có tồn tại. Resource cũng có. Vậy mà Terraform vẫn không chịu — nó không tìm thấy output bạn đang cố đọc.
Nguyên nhân
Terraform module là hộp đen. Giá trị duy nhất mà module có thể tiết lộ ra bên ngoài là những giá trị được khai báo tường minh trong block output bên trong module đó. Khi bạn tham chiếu module.network.subnet_id, Terraform sẽ tìm block output "subnet_id" trong thư mục module network. Không có block, không có giá trị — chỉ có lỗi này.
Một số nguyên nhân phổ biến:
- Bạn thêm tham chiếu ở calling module nhưng quên khai báo block
outputtrong child module. - Bạn đổi tên output block nhưng không cập nhật tất cả những nơi đang tham chiếu đến nó.
- Bạn sao chép module từ nơi khác và các output bạn kỳ vọng không tồn tại trong phiên bản này.
- Có sự không khớp tên tinh tế — ví dụ
subnet_ids(số nhiều) so vớisubnet_id(số ít). - Bạn đang đọc output giữa các workspace qua
terraform_remote_state, nhưng output đó chưa bao giờ được khai báo trong source stack.
Bước 1 — Xem Module Thực Sự Khai Báo Những Output Nào
Bắt đầu bằng cách tìm vị trí module. Với local module, thông báo lỗi đã chỉ rõ — module.network nghĩa là tìm trong modules/network/:
ls modules/network/
grep -r 'output' modules/network/
Với module lấy từ registry hoặc Git, kiểm tra trong bản tải về đã được cache:
find .terraform/modules -name '*.tf' | xargs grep '^output'
Bạn sẽ thấy tất cả block output mà module thực sự có. So sánh danh sách đó với những gì bạn đang tham chiếu — sự không khớp sẽ lộ ra ngay.
Thêm Block Output Còn Thiếu
Nếu bạn kiểm soát được module, cách sửa rất đơn giản. Thêm output vào trong thư mục module — thường là modules/network/outputs.tf:
output "subnet_id" {
description = "The ID of the primary subnet"
value = aws_subnet.main.id
}
Chạy lại terraform plan. Lỗi biến mất.
Cần expose nhiều subnet? Dùng list output thay thế:
output "subnet_ids" {
description = "List of all subnet IDs"
value = aws_subnet.main[*].id
}
Rồi truy cập theo index từ calling config:
subnet_id = module.network.subnet_ids[0]
Output Có Tồn Tại — Nhưng Dưới Tên Khác
Trước khi chỉnh sửa bất cứ thứ gì, hãy kiểm tra xem module thực sự expose những gì. Terraform console rất hữu ích ở đây:
terraform console
> module.network
Lệnh này in ra tất cả output có sẵn từ module. Chín phần mười bạn sẽ nhận ra ngay sự không khớp tên — sau đó chỉ cần cập nhật tham chiếu:
# Sai
subnet_id = module.network.subnet_id
# Đúng — output block được đặt tên là "private_subnet_id"
subnet_id = module.network.private_subnet_id
Remote State: Output Bị Thiếu Trong Source Stack
Đang dùng terraform_remote_state để đọc output từ workspace khác? Output phải được khai báo — và đã apply — trong source stack trước.
data "terraform_remote_state" "vpc" {
backend = "s3"
config = {
bucket = "my-tf-state"
key = "vpc/terraform.tfstate"
region = "us-east-1"
}
}
resource "aws_instance" "app" {
subnet_id = data.terraform_remote_state.vpc.outputs.subnet_id
}
VPC stack cần có phần này trong outputs.tf:
output "subnet_id" {
value = aws_subnet.main.id
}
Deploy VPC stack trước. Terraform đọc từ state file — nếu output chưa bao giờ được apply, nó sẽ không có ở đó. Chỉ có trong file .tf là chưa đủ.
Module Từ Public Registry: Phiên Bản Đó Chưa Có Output
Đang ghim vào phiên bản module cũ hơn? Output có thể chưa tồn tại. Điều này thường gặp với terraform-aws-modules — phiên bản 3.x và 5.x expose các output khác nhau.
module "network" {
source = "terraform-aws-modules/vpc/aws"
version = "3.0.0" # thiếu output bạn cần
}
Kiểm tra changelog của module hoặc xem outputs.tf trên GitHub cho tag cụ thể đó. Nếu phiên bản mới hơn có những gì bạn cần, hãy nâng cấp:
module "network" {
source = "terraform-aws-modules/vpc/aws"
version = "5.1.0"
}
Sau đó tải bản cập nhật:
terraform init -upgrade
Xác Minh Sau Khi Sửa
Chạy ba lệnh này theo thứ tự:
# Kiểm tra lỗi cú pháp trước
terraform validate
# Nên hoàn thành mà không có lỗi
terraform plan
# Xem tất cả root-level output sau khi apply
terraform output
Muốn xác nhận một module reference cụ thể trước khi apply? Dùng console:
terraform console
> module.network.subnet_id
Nếu trả về một giá trị (hoặc placeholder đã biết), tham chiếu đã được kết nối đúng cách.
Tham Khảo Nhanh
- Output được khai báo trong file sai — Không quan trọng file
.tfnào bên trong module chứa blockoutput, miễn là nó nằm đâu đó trong thư mục module. - Sensitive outputs — Đánh dấu output là
sensitive = truekhông làm hỏng các tham chiếu. Terraform chỉ ẩn giá trị đi trong plan output. - Module dùng count hoặc for_each — Hình dạng output thay đổi. Tham chiếu theo dạng
module.network[0].subnet_idthay vìmodule.network.subnet_id.

