Kịch bản: Khi một tham chiếu đơn giản làm gián đoạn quy trình làm việc
Bạn đang thực hiện dở dang một bản cập nhật cơ sở hạ tầng lớn. Có lẽ bạn đang di chuyển một dự án từ AWS provider v4.0 sang v5.0. Bạn thực thi terraform plan, hy vọng thấy một danh sách các thay đổi sạch sẽ. Thay vào đó, terminal của bạn trả về một bức tường văn bản màu đỏ.
Error: Unsupported attribute
on main.tf line 42, in resource "aws_instance" "web":
42: subnet_id = data.aws_subnet.selected.id_name
This object does not have an attribute named "id_name".
Lỗi này xảy ra khi bạn tham chiếu đến một thuộc tính không tồn tại trong schema của nhà cung cấp. Nó thường xảy ra với các block lồng nhau. Mặc dù thông báo có vẻ rõ ràng, việc truy tìm liên kết bị thiếu chính xác trong một module phức tạp có thể cảm giác như mò kim đáy bể.
Tại sao Terraform đưa ra lỗi này
Infrastructure as Code rất nghiêm ngặt. Dưới đây là lý do tại sao các tham chiếu của bạn thường thất bại:
- Lỗi đánh máy đơn giản: Bạn viết
dns_namenhưng nhà cung cấp yêu cầupublic_dns. - Thay đổi gây hỏng (Breaking Changes) của nhà cung cấp: Các bản cập nhật lớn thường đổi tên thuộc tính. Ví dụ, AzureRM provider có thể thay đổi trường
namethànhresource_idgiữa các phiên bản. - Bẫy bộ sưu tập (The Collection Trap): Đây là nguyên nhân phổ biến nhất. Nếu bạn sử dụng
counthoặcfor_each, Terraform coi tài nguyên là một danh sách hoặc bản đồ, không phải là một đối tượng đơn lẻ. - Output Module bị ẩn: Bạn đang cố gắng đọc
module.vpc.vpc_id, nhưng VPC module chưa bao giờ xuất (export) giá trị đó trongoutputs.tfcủa nó.
Cách sửa trong 60 giây: Terraform Console
Đừng đoán nữa. Hãy sử dụng terraform console để xem chính xác những gì state engine thấy. Đây là cách hiệu quả nhất để gỡ lỗi một plan đang thất bại.
- Di chuyển đến thư mục gốc của dự án trong terminal.
- Khởi chạy môi trường bằng cách nhập
terraform console. - Nhập địa chỉ tài nguyên, chẳng hạn như
data.aws_subnet.selected, và nhấn Enter.
Console sẽ xuất cấu trúc giống JSON đầy đủ của đối tượng. Thông thường, bạn sẽ phát hiện ra thuộc tính được đặt tên khác hoặc nằm sâu bên trong một block lồng nhau mà bạn quên truy cập.
Giải pháp từng bước
1. Sửa lỗi không khớp Schema
Kiểm tra tên thuộc tính của bạn so với Terraform Registry. Nếu bạn vừa cập nhật .terraform.lock.hcl, thay đổi từ nhà cung cấp có thể là lý do khiến mã của bạn bị lỗi.
# SAI
output "instance_ip" {
value = aws_instance.web.ip_address
}
# ĐÚNG
output "instance_ip" {
value = aws_instance.web.public_ip
}
2. Giải quyết vấn đề lập chỉ mục (Count và For_Each)
Khi bạn định nghĩa một tài nguyên với count = 1, nó vẫn trở thành một danh sách. Bạn không thể truy cập aws_instance.web.id trực tiếp vì Terraform mong đợi một chỉ mục. Sử dụng toán tử splat ([*]) để lấy tất cả các ID hoặc một chỉ mục cụ thể cho một instance.
# SAI: Lỗi vì 'server' là một danh sách gồm 2 mục
resource "aws_instance" "server" {
count = 2
}
output "ids" {
value = aws_instance.server.id
}
# ĐÚNG: Sử dụng cú pháp splat cho toàn bộ danh sách
output "all_ids" {
value = aws_instance.server[*].id
}
# ĐÚNG: Nhắm vào instance đầu tiên cụ thể
output "first_id" {
value = aws_instance.server[0].id
}
3. Xuất các biến Module
Các module mặc định là hộp đen. Nếu cấu hình cha của bạn không thể thấy module.network.vpc_id, hãy kiểm tra tệp outputs.tf bên trong thư mục module đó. Bạn phải hiển thị giá trị một cách rõ ràng.
# bên trong /modules/network/outputs.tf
output "vpc_id" {
description = "ID của VPC"
value = aws_vpc.main.id
}
Mẹo chuyên nghiệp: Sử dụng try() cho các trường tùy chọn
Đôi khi các thuộc tính chỉ tồn tại trong các môi trường cụ thể, như một bản đồ tags có thể trống. Sử dụng hàm try() để định nghĩa một giá trị dự phòng và ngăn plan của bạn bị dừng đột ngột.
# Cung cấp giá trị mặc định nếu thiếu tag 'Name'
locals {
instance_name = try(aws_instance.web.tags["Name"], "unnamed-resource")
}
Cách xác minh việc sửa lỗi
Thực hiện ba bước sau để đảm bảo lỗi đã được khắc phục hoàn toàn:
- Chạy
terraform validate. Lệnh này bắt lỗi cú pháp và thuộc tính mà không cần kết nối với đám mây. - Chạy
terraform plan. Một plan thành công không có văn bản màu đỏ xác nhận việc ánh xạ của bạn là chính xác. - Kiểm tra lại trong
terraform console. Đánh giá biểu thức bị lỗi cụ thể để xác nhận rằng nó hiện trả về chuỗi hoặc số mong đợi.

