Chuyện gì đang xảy ra
Bạn chạy một playbook và Ansible in ra:
[WARNING]: Could not match supplied host pattern, ignoring: webservers
[WARNING]: No hosts matched, nothing to do
Playbook thoát ngay lập tức mà không chạy một task nào. Ansible tìm thấy file inventory của bạn — chỉ là nó không thể xác định được host group hay hostname được tham chiếu trong trường hosts: của playbook.
Hầu hết mọi trường hợp đều do tên không khớp: gõ sai, sai đường dẫn inventory, hoặc có vấn đề về cấu trúc trong file inventory. Thường chỉ mất 2 phút để sửa khi bạn biết chỗ cần tìm.
Quy trình debug
Bước 1 — Liệt kê những gì Ansible thực sự thấy trong inventory
Bắt đầu từ đây. Yêu cầu Ansible liệt kê mọi host và group mà nó có thể phân tích từ inventory của bạn:
# Dùng một file inventory cụ thể
ansible-inventory -i inventory.ini --list
# Hoặc nếu bạn dùng một thư mục
ansible-inventory -i inventories/production --list
Xem qua output JSON. Nếu webservers (hoặc bất kỳ group nào bạn tham chiếu) không có mặt, Ansible thực sự không tìm thấy nó. Hoặc bản thân file có vấn đề, hoặc bạn đang trỏ đến nhầm file.
Thích dạng hiển thị dễ đọc hơn? Dùng --graph:
ansible-inventory -i inventory.ini --graph
Một group hợp lệ trông như thế này:
@all:
|--@webservers:
| |--web01.example.com
| |--web02.example.com
|--@ungrouped:
Bước 2 — Kiểm tra những gì playbook của bạn tham chiếu
Mở playbook và tìm dòng hosts::
---
- name: Deploy web app
hosts: webservers
tasks:
...
Giá trị đó phải khớp chính xác với tên group hoặc hostname trong inventory. Phân biệt chữ hoa/thường. Không có khoảng trắng. Kiểm tra từng ký tự nếu cần — sai một chữ cũng sẽ gây ra lỗi này.
Bước 3 — Xác nhận bạn đang trỏ đúng file inventory
Nguyên nhân phổ biến nhất: chạy playbook mà không có -i, khiến Ansible âm thầm dùng /etc/ansible/hosts. File đó thường rỗng, hoặc không chứa các group của bạn.
# Sai — dùng /etc/ansible/hosts mặc định
ansible-playbook deploy.yml
# Đúng — chỉ định rõ ràng inventory của bạn
ansible-playbook -i inventory.ini deploy.yml
ansible-playbook -i inventories/production deploy.yml
Để tránh phải nhập lại -i mỗi lần, đặt đường dẫn một lần trong ansible.cfg:
[defaults]
inventory = ./inventory.ini
Giải pháp
Cách sửa 1 — Sửa cấu trúc file inventory
Một inventory INI hợp lệ với group [webservers] trông như thế này:
[webservers]
web01.example.com
web02.example.com ansible_user=ubuntu
[dbservers]
db01.example.com ansible_user=centos ansible_port=22
Bốn lỗi thường gặp âm thầm phá vỡ việc khớp group:
- Thêm khoảng trắng trong ngoặc:
[ webservers ]— Ansible xử lý đây là một chuỗi khác, không phải groupwebservers - Gõ sai:
[webserver]trong inventory nhưnghosts: webserverstrong playbook - Host được liệt kê trước header group của chúng — chúng sẽ nằm trong
[ungrouped]thay vì đúng group - Vô tình dùng cú pháp inventory YAML bên trong file
.ini(hoặc ngược lại)
Thích dùng inventory YAML? Cấu trúc tương đương:
all:
children:
webservers:
hosts:
web01.example.com:
web02.example.com:
ansible_user: ubuntu
dbservers:
hosts:
db01.example.com:
ansible_user: centos
Cách sửa 2 — Khớp chính xác pattern hosts
Cập nhật playbook để dùng pattern thực sự tồn tại trong inventory:
---
- name: Deploy web app
hosts: webservers # phải khớp chính xác
become: true
tasks:
- name: Install nginx
apt:
name: nginx
state: present
Ansible hỗ trợ nhiều dạng pattern để nhắm đến nhiều group cùng lúc:
hosts: all # mọi host trong inventory
hosts: webservers,dbservers # nhiều group
hosts: webservers:&staging # giao nhau (webservers VÀ staging)
hosts: webservers:!dbservers # webservers nhưng KHÔNG phải dbservers
Cách sửa 3 — Thêm đường dẫn inventory vào ansible.cfg
Đặt file ansible.cfg cấp dự án cạnh playbook và không cần lo về -i nữa:
[defaults]
inventory = ./inventory.ini
remote_user = ubuntu
host_key_checking = False
Ansible tự động đọc ansible.cfg từ thư mục hiện tại. Chạy ansible-playbook deploy.yml mà không có -i sẽ hoạt động đúng.
Kiểm tra
Ba lệnh nên chạy trước khi đụng vào bất kỳ server nào:
# Xác nhận group hiện đã xuất hiện
ansible-inventory -i inventory.ini --graph
# Chạy thử playbook (không áp dụng thay đổi)
ansible-playbook -i inventory.ini deploy.yml --check
# Liệt kê các host sẽ được nhắm đến
ansible-playbook -i inventory.ini deploy.yml --list-hosts
Kết quả --list-hosts thành công trông như thế này:
playbook: deploy.yml
play #1 (webservers): Deploy web app
pattern: ['webservers']
hosts (2):
web01.example.com
web02.example.com
Vẫn thấy 0 hosts hoặc cảnh báo? Quay lại Bước 1.
Mẹo hay
Các pattern phức tạp như webservers:&production:!disabled rất dễ viết sai, đặc biệt với inventory lớn hơn. Trước khi đưa pattern vào playbook, tôi thường xác minh logic bằng Regex Tester trên ToolCraft — dán danh sách host vào, kiểm tra xem pattern có khớp đúng như mong đợi không. Công cụ chạy hoàn toàn trên trình duyệt và không tải dữ liệu lên, điều quan trọng khi danh sách của bạn chứa tên server nội bộ.
Bài học rút ra
- Luôn truyền
-imột cách tường minh khi chạy từ ngoài thư mục dự án, hoặc cấu hìnhansible.cfgđể inventory luôn được giải quyết đúng. - Chạy
ansible-inventory --graphtrước mỗi khi playbook hoạt động bất thường — nó hiển thị chính xác những gì Ansible đã phân tích, không phải những gì bạn nghĩ bạn đã viết. - Header group trong INI nhạy cảm với khoảng trắng —
[webservers]và[ webservers ]là hai chuỗi khác nhau đối với Ansible. - Dùng
--list-hoststrước mỗi lần chạy quan trọng — một kiểm tra an toàn, chỉ đọc, xác nhận mục tiêu của bạn trước khi bất kỳ task nào chạm vào server thực.

