Sửa lỗi Terraform 'templatefile': No Such File or Directory

beginner🏗️ Terraform2026-06-28| Terraform (mọi phiên bản), Linux, macOS, Windows, CI/CD Pipelines (GitHub Actions, GitLab CI)

Error Message

Error: Error in function call Call to function "templatefile" failed: open ./templates/user_data.tpl: no such file or directory.
#terraform#devops#iac#khắc-phục-sự-cố

Vấn đề: Mọi thứ trông có vẻ đúng, nhưng vẫn lỗi

Bạn vừa hoàn thành một module Terraform phức tạp để triển khai một cụm 3 instance EC2. Bạn đang sử dụng hàm templatefile() để chèn các biến môi trường động vào một shell script. Trong IDE của bạn, mọi thứ trông rất hoàn hảo. File user_data.tpl nằm ngay trong thư mục templates đúng như dự kiến.

Bạn chạy terraform plan và gặp lỗi:

Error: Error in function call

Call to function "templatefile" failed: open ./templates/user_data.tpl: no such file or directory.

Thậm chí bạn có thể chạy ls ./templates/user_data.tpl từ terminal và thấy file hiện ra. Vậy tại sao Terraform lại từ chối nhận diện nó? Vấn đề không phải là file bị thiếu. Vấn đề là Terraform đang tìm kiếm sai chỗ.

Tại sao các đường dẫn của bạn bị lỗi

Terraform giải quyết các đường dẫn tương đối như ./templates/user_data.tpl dựa trên thư mục làm việc hiện tại (current working directory). Đây là thư mục nơi bạn thực thi lệnh terraform, chứ không phải thư mục chứa mã nguồn .tf của bạn.

Hãy tưởng tượng cấu trúc dự án của bạn như sau:

.
├── main.tf (Cấu hình gốc)
└── modules/
    └── web_server/
        ├── main.tf (Mã nguồn module)
        └── templates/
            └── user_data.tpl

Nếu bạn gọi templatefile("./templates/user_data.tpl", {}) bên trong modules/web_server/main.tf, Terraform sẽ tìm kiếm file đó bắt đầu từ thư mục gốc. Vì file nằm sâu trong thư mục module, việc tìm kiếm sẽ thất bại. Sự thay đổi ngữ cảnh này là nguyên nhân số 1 gây ra lỗi đường dẫn trong các pipeline CI/CD như GitHub Actions hoặc Jenkins.

Các bước kiểm tra đầu tiên

Trước khi thay đổi mã nguồn, hãy loại trừ các lỗi đơn giản mà ngay cả những kỹ sư dày dạn kinh nghiệm cũng có thể mắc phải:

  • Phân biệt chữ hoa chữ thường: Trên các CI runner chạy Linux, Templates/templates/ là hai thư mục khác nhau.
  • Phần mở rộng bị ẩn: Đảm bảo file của bạn không thực sự có tên là user_data.tpl.txt.
  • Ngữ cảnh thực thi: Bạn có đang chạy Terraform từ một thư mục con bằng cờ -chdir không? Điều này làm thay đổi nơi Terraform tìm kiếm các đường dẫn tương đối.

Giải pháp đáng tin cậy: Sử dụng path.module

Để mã nguồn của bạn có thể di động (portable), bạn cần yêu cầu Terraform tìm kiếm file tương đối với chính module đó. Terraform cung cấp một biến tích hợp sẵn gọi là path.module cho chính mục đích này. Biến này luôn trỏ đến đường dẫn hệ thống của thư mục chứa file .tf nơi nó được sử dụng.

Cập nhật block resource của bạn như sau:

# Cách tiếp cận đáng tin cậy
resource "aws_instance" "web" {
  count = 3
  # ...
  user_data = templatefile("${path.module}/templates/user_data.tpl", {
    admin_email = var.admin_email
    server_id   = count.index
  })
}

Khi bạn sử dụng ${path.module}, Terraform sẽ tạo ra một đường dẫn tuyệt đối. Việc bạn chạy lệnh plan từ thư mục gốc, thư mục con hay từ một build agent từ xa sẽ không còn quan trọng nữa. Đường dẫn sẽ luôn chính xác.

Các biến đường dẫn hữu ích khác

  • path.root: Trỏ đến thư mục nơi bạn bắt đầu thực thi lệnh Terraform.
  • path.cwd: Trỏ đến thư mục terminal hiện tại của bạn.

Đối với các lệnh gọi templatefile bên trong module, path.module hầu như luôn là công cụ phù hợp nhất.

Debug nhanh hơn với Terraform Console

Đừng đợi 60 giây để chạy một lệnh terraform plan đầy đủ chỉ để kiểm tra một đường dẫn. Bạn có thể xác minh logic của mình ngay lập tức bằng cách sử dụng terraform console. Đây là cách nhanh nhất để debug các vấn đề về đường dẫn mà không cần thực sự triển khai bất cứ thứ gì.

  • Mở terminal tại thư mục gốc của dự án.
  • Chạy lệnh terraform console.
  • Kiểm tra đường dẫn tuyệt đối bằng cách nhập: abspath("${path.module}/modules/web_server/templates/user_data.tpl")
  • Thử đọc trực tiếp nội dung file: file("${path.module}/modules/web_server/templates/user_data.tpl")

Nếu hàm file() trả về nội dung script của bạn mà không có lỗi, đường dẫn của bạn đã được sửa xong. Nhấn Ctrl+C để thoát và tiếp tục triển khai.

Tổng kết

Lỗi "no such file or directory" hiếm khi là do thiếu file. Nó hầu như luôn là do sự hiểu nhầm về cách Terraform xử lý ngữ cảnh thực thi. Bằng cách loại bỏ các đường dẫn tương đối được viết cứng (hardcoded) và sử dụng ${path.module}, bạn sẽ giúp mã nguồn hạ tầng của mình trở nên linh hoạt, dễ di động và dễ debug hơn nhiều.

Related Error Notes