Sửa lỗi Ansible 'could not find src' trong Module Copy

beginner🔧 Ansible2026-06-30| Ansible (mọi phiên bản), Linux/macOS Control Node, Remote Target (Ubuntu/CentOS/Debian)

Error Message

fatal: [host]: FAILED! => {"changed": false, "msg": "could not find src=/path/to/local/file.conf"}
#ansible#devops#khắc phục lỗi#tự động hóa#linux

Tình huống vấn đề

Bạn đang triển khai một tệp cấu hình đến hàng chục máy chủ web. Bạn kích hoạt playbook của mình, mong đợi một hàng trạng thái 'changed' màu xanh mượt mà. Thay vào đó, quá trình dừng lại đột ngột với một thông báo lỗi màu đỏ thô kệch:

fatal: [web_server]: FAILED! => {"changed": false, "msg": "could not find src=/etc/configs/nginx.conf"}

Sự bối rối bắt đầu khi bạn chạy lệnh ls -l /etc/configs/nginx.conf trên máy của mình và thấy tệp tin nằm ngay đó. Lỗi này hiếm khi có nghĩa là tệp tin bị thiếu trên ổ đĩa của bạn. Thông thường, nó có nghĩa là Ansible đang tìm kiếm ở một vị trí khác với ý định của bạn do cách nó giải quyết các đường dẫn tương đối.

Tại sao lỗi này xảy ra

Module copy chuyển các tệp từ control node của bạn (máy tính xách tay hoặc CI/CD runner nơi bạn nhập lệnh) đến remote host. Nếu tiến trình Ansible không thể tìm thấy tệp cục bộ, nó không thể tải tệp đó lên. Lỗi này thường xuất phát từ một trong bốn vấn đề sau:

  • Sai lệch đường dẫn: Bạn đã thực thi ansible-playbook từ thư mục ~/projects/, nhưng đường dẫn nguồn của bạn lại tương đối so với ~/projects/ansible/playbooks/.
  • Vi phạm cấu trúc Role: Bạn đã đặt một tệp trong thư mục tên là config/ thay vì thư mục files/ tiêu chuẩn bên trong một Ansible role.
  • Lỗi biến: Một biến như {{ config_path }} chưa được định nghĩa hoặc chứa lỗi đánh máy, dẫn đến đường dẫn bị trống hoặc bị hỏng.
  • Rào cản quyền truy cập: Người dùng cục bộ thực thi Ansible thiếu quyền đọc tệp nguồn, khiến tệp đó trở nên "vô hình" đối với module.

Các giải pháp khắc phục nhanh

1. Kiểm tra với đường dẫn tuyệt đối

Sử dụng đường dẫn tuyệt đối như một bước chẩn đoán. Nếu tác vụ thành công với đường dẫn đầy đủ, bạn đã xác nhận được vấn đề nằm ở đường dẫn tương đối. Ví dụ: thay đổi src thành /home/dev/deploy/configs/app.conf. Nếu cách này hoạt động, bạn biết rằng tệp có thể truy cập được; chỉ là việc ánh xạ của bạn bị sai.

- name: Diagnostic copy using absolute path
  ansible.builtin.copy:
    src: /home/user/project/configs/app.conf
    dest: /etc/app/app.conf

2. Căn chỉnh với thư mục Playbook

Theo mặc định, Ansible tìm kiếm các tệp tương đối so với tệp .yml mà bạn đang chạy. Nếu cấu trúc thư mục của bạn trông giống như ví dụ bên dưới, src của bạn chỉ cần trỏ đến thư mục nằm cạnh playbook của bạn.

# Cấu trúc thư mục:
# ├── site.yml
# └── files/
#     └── app.conf

- name: Copy app configuration
  ansible.builtin.copy:
    src: files/app.conf
    dest: /etc/app/app.conf

Giải pháp lâu dài và Thực hành tốt nhất

Tận dụng cấu trúc thư mục Role

Role cung cấp logic tìm kiếm tích hợp giúp đơn giản hóa các tác vụ của bạn. Khi một tác vụ nằm trong roles/webserver/tasks/main.yml, Ansible sẽ tự động quét thư mục roles/webserver/files/ để tìm bất kỳ tệp nguồn nào. Bạn có thể bỏ qua hoàn toàn phần đường dẫn.

Cấu trúc Role tiêu chuẩn:

roles/
  common/
    tasks/main.yml
    files/ntp.conf

Tác vụ trong main.yml:

- name: Deploy NTP config
  ansible.builtin.copy:
    src: ntp.conf  # Ansible tự động tìm thấy tệp này trong ../files/
    dest: /etc/ntp.conf

Cố định đường dẫn với playbook_dir

Các dự án phức tạp thường liên quan đến việc chạy playbook từ các thư mục con khác nhau. Để giữ cho các đường dẫn của bạn có tính di động, hãy sử dụng biến magic playbook_dir. Điều này đảm bảo đường dẫn luôn được tính toán từ thư mục gốc của playbook, bất kể bạn bắt đầu lệnh từ đâu.

- name: Copy script from project root
  ansible.builtin.copy:
    src: "{{ playbook_dir }}/scripts/setup.sh"
    dest: /usr/local/bin/setup.sh
    mode: '0755'

Kiểm tra lỗi (Debug) trên bộ điều khiển cục bộ

Nếu lỗi vẫn còn, hãy buộc Ansible báo cáo những gì nó thấy trên máy cục bộ của bạn. Sử dụng module statdelegate_to: localhost để xác minh sự tồn tại của tệp trước khi thực hiện nỗ lực sao chép. Đây là cách nhanh nhất để phát hiện các vấn đề về quyền truy cập hoặc các biến bị trống.

- name: Verify local file existence
  ansible.builtin.stat:
    path: "{{ playbook_dir }}/files/my-config.conf"
  register: local_file
  delegate_to: localhost

- name: Fail if file is missing
  ansible.builtin.fail:
    msg: "The file was not found on the control node!"
  when: not local_file.stat.exists

Các bước xác minh

Sau khi áp dụng bản sửa lỗi, hãy xác minh giải pháp bằng ba bước sau:

  • Tăng mức độ chi tiết (Verbosity): Chạy ansible-playbook -vv. Đầu ra sẽ tiết lộ chính xác đường dẫn tuyệt đối mà Ansible đang cố gắng mở trên ổ đĩa cục bộ của bạn.
  • Chạy thử (Dry Run): Thực thi với --check. Nếu lỗi 'could not find src' biến mất, Ansible đã ánh xạ thành công tệp cục bộ và sẵn sàng để đẩy tệp đi.
  • Xác nhận quyền truy cập: Đảm bảo tệp cục bộ có ít nhất quyền 644 (-rw-r--r--) để người dùng Ansible có thể đọc được.

Việc sử dụng cấu trúc role tiêu chuẩn hoặc cố định đường dẫn với {{ playbook_dir }} sẽ loại bỏ 90% các lỗi này. Những thói quen này giúp việc tự động hóa của bạn trở nên dễ dự đoán và có tính di động cao hơn giữa các môi trường làm việc nhóm khác nhau.

Related Error Notes