The Warning

[WARNING]: Could not match supplied host pattern, ignoring: webservers
skipping: no hosts matched

Your playbook runs but does absolutely nothing. Here's why and how to fix it.

Cause 1: Typo in hosts or Group Name

# playbook.yml
- hosts: websevers  # ← typo! should be "webservers"
  tasks:
    - name: Ping
      ansible.builtin.ping:
# inventory
[webservers]  # ← correct spelling
web1 ansible_host=192.168.1.10

Fix: Double-check spelling in both playbook hosts: and inventory group names.

Cause 2: Wrong Inventory File

# Using default /etc/ansible/hosts but your hosts are elsewhere
ansible-playbook playbook.yml

# Fix: specify inventory
ansible-playbook -i inventory/production playbook.yml

Or set it in ansible.cfg:

[defaults]
inventory = ./inventory/hosts

Cause 3: Host Pattern Mismatch

# This only matches hosts IN the group "webservers"
- hosts: webservers

# This matches the literal hostname "webservers"
- hosts: webservers

Verify your inventory:

# List all hosts in a group
ansible webservers --list-hosts -i inventory

# List all groups
ansible-inventory -i inventory --graph

Cause 4: Limit Flag Filtering Everything Out

# This limits to only "db1" — webservers won't run
ansible-playbook playbook.yml --limit db1

Cause 5: Dynamic Inventory Returns Empty

# Test your dynamic inventory script
./inventory.py --list | python3 -m json.tool

Quick Fix Checklist

  1. ansible-inventory --graph — see what Ansible actually knows about
  2. Check hosts: in playbook matches a group or host name exactly
  3. Verify inventory file path with -i
  4. Remove --limit flags temporarily
  5. Check for YAML indentation issues in inventory

Conclusion

"No hosts matched" almost always means Ansible can't find the hosts you specified. Verify your inventory path, check for typos, and use ansible-inventory --graph to see what's actually loaded.