Vấn đề
Chia tách logic thành nhiều tệp giúp các Ansible role của bạn luôn sạch sẽ và dễ quản lý. Bạn có thể sử dụng include_tasks hoặc import_tasks để đưa các đoạn mã này vào tệp main.yml. Tuy nhiên, ngay cả khi tệp đã nằm rõ ràng trong thư mục, Ansible đôi khi vẫn báo lỗi 'Could not find or access' khiến quá trình tự động hóa của bạn bị dừng lại.
Lỗi thường có dạng như sau:
ERROR! Could not find or access '/path/to/tasks/setup.yml' on the Ansible Controller.
If we are using a role, the lookup is relative to the role's tasks/ directory.
Make sure the file exists and is readable.
Tại sao điều này xảy ra
Ansible tuân theo một phân cấp tìm kiếm nghiêm ngặt. Khi thực thi bên trong một role, engine sẽ tự động tìm kiếm các tệp task trong thư mục con tasks/ của role đó. Hầu hết các lỗi bắt nguồn từ bốn sai sót cụ thể:
- Đường dẫn dư thừa: Thêm "tasks/" vào đường dẫn một cách thủ công trong khi Ansible đã đang tìm kiếm ở đó.
- Ngữ cảnh thực thi: Chạy một playbook từ thư mục gốc làm hỏng việc tra cứu đường dẫn tương đối.
- Phân biệt chữ hoa chữ thường: Linux coi
Setup.ymlvàsetup.ymllà hai tệp khác nhau. - Symlink bị hỏng: Sử dụng các liên kết trỏ đến các mục tiêu không tồn tại trên controller.
Các bước khắc phục từng bước
1. Loại bỏ các tiền tố thư mục dư thừa
Giả sử cấu trúc tệp của bạn trông như thế này:
roles/
my_app/
tasks/
main.yml
setup.yml
Bên trong main.yml, bạn có thể viết sai như sau:
# SAI - Điều này dẫn đến việc tìm kiếm tasks/tasks/setup.yml
- name: Include setup tasks
include_tasks: tasks/setup.yml
Vì Ansible đã nhắm mục tiêu vào thư mục tasks/, việc thêm nó một lần nữa sẽ tạo ra một đường dẫn không tồn tại. Hãy khắc phục điều này bằng cách chỉ sử dụng tên tệp:
# ĐÚNG
- name: Include setup tasks
include_tasks: setup.yml
2. Sử dụng biến Magic {{ role_path }}
Việc mã hóa cứng (hardcoding) đường dẫn rất rủi ro trong các dự án phức tạp. Nếu bạn đang gọi các task từ một role khác hoặc xử lý các include lồng nhau, hãy sử dụng biến role_path. Điều này bắt buộc sử dụng đường dẫn tuyệt đối trên controller, không để lại sai sót.
- name: Include setup from current role safely
include_tasks: "{{ role_path }}/tasks/setup.yml"
Cách tiếp cận này rất chắc chắn khi các playbook của bạn nằm trong các cấu trúc thư mục không tiêu chuẩn.
3. Xác minh phần mở rộng và lỗi chính tả
Ansible sẽ không đoán phần mở rộng tệp của bạn. Nếu tệp của bạn là setup.yaml nhưng mã của bạn tham chiếu đến setup.yml, task sẽ thất bại ngay lập tức. Hãy kiểm tra nhanh để xem chính xác những gì đang có trên đĩa:
ls roles/my_app/tasks/
Hãy tiêu chuẩn hóa dự án của bạn trên một phần mở rộng—hoặc .yml hoặc .yaml—để ngăn chặn các buổi gỡ lỗi lúc 3 giờ sáng này.
4. Kiểm tra quyền của hệ thống tệp
Đôi khi tệp tồn tại, nhưng Ansible thiếu phần 'access' (truy cập) trong thông báo lỗi. Người dùng chạy ansible-playbook phải có quyền đọc cho tệp và quyền thực thi cho mọi thư mục cha. Khắc phục quyền hạn bằng các lệnh sau:
# Thiết lập quyền đọc tiêu chuẩn (644) và quyền truy cập thư mục (755)
chmod 644 roles/my_app/tasks/setup.yml
chmod 755 roles/my_app/tasks/
5. Nạp Task Tĩnh và Động
Mặc dù import_tasks và include_tasks trông có vẻ giống nhau, chúng hoạt động khác nhau. import_tasks là tĩnh; nó được xử lý khi playbook được phân tích cú pháp lần đầu tiên. include_tasks là động và được đánh giá tại thời điểm thực thi (runtime). Nếu đường dẫn của bạn sử dụng một biến không được xác định cho đến khi play bắt đầu, import_tasks sẽ thất bại.
# Cách này hoạt động vì nó được đánh giá trong quá trình thực thi
- name: Dynamic include
include_tasks: "{{ os_family }}_tasks.yml"
# Cách này thường thất bại nếu os_family là một fact được thu thập
- name: Static import
import_tasks: "{{ os_family }}_tasks.yml"
Xác minh
Để xem chính xác Ansible đang tìm kiếm ở đâu, hãy chạy playbook của bạn với mức độ chi tiết tối đa (triple verbosity). Điều này tiết lộ logic đường dẫn tìm kiếm trong thời gian thực:
ansible-playbook site.yml -vvv
Tìm kiếm trong đầu ra các dòng bắt đầu bằng searching for.... Nếu bạn thấy một đường dẫn như .../tasks/tasks/setup.yml, bạn đã tìm thấy lỗi dư thừa thư mục của mình.
Mẹo chuyên nghiệp
- Tránh lồng nhau quá sâu: Nếu một role yêu cầu nhiều hơn 5 hoặc 6 tệp task, nó có thể đang xử lý quá nhiều việc. Hãy cân nhắc chia nó thành hai role nhỏ hơn, chuyên biệt hơn.
- Hãy để linter giúp bạn: Sử dụng
ansible-lint. Nó sẽ phát hiện các vấn đề về đường dẫn và cú pháp lỗi thời trước khi bạn chạy mã. - Kiểm tra trong 1 giây: Luôn xác minh rằng
main.ymlvà các task con của bạn nằm trong cùng một thư mụctasks/. 90% các lỗi này là do nhầm lẫn vị trí đơn giản.

