Grouping hosts from the Ansible nmap dynamic inventory
I use the nmap inventory plugin to build an Ansible inventory of my homelab without maintaining a host list by hand. It scans a subnet and hands you every host it finds.
The part that took me a while was getting those hosts into useful groups. Out of the box everything lands in all and nothing else, which isn't much of an inventory.
First, the plugin needs to be enabled. In ansible.cfg:
[inventory]
enable_plugins = community.general.nmap, host_list, script, auto, yaml, ini
Then the inventory file itself, which must end in .nmap.yml or .nmap.yaml for the plugin to pick it up automatically:
# homelab.nmap.yml
plugin: community.general.nmap
address: 192.168.1.0/24
strict: false
ports: true
groups:
webservers: "ports | selectattr('service', 'equalto', 'http') | list | length > 0"
sshhosts: "ports | selectattr('service', 'equalto', 'ssh') | list | length > 0"
keyed_groups:
- key: ports | map(attribute='service') | list
prefix: svc
Two things that tripped me up:
ports: true is not the default. Without it the plugin never collects port data, so every expression in groups and keyed_groups silently evaluates against nothing and you get no groups at all, with no error to tell you why.
strict: false keeps a host that fails one of those expressions from blowing up the whole inventory run. Handy while you're still working out your conditions, worth flipping to true once they're right.
Check what you actually got with:
ansible-inventory -i homelab.nmap.yml --graph
You should see your hosts sorted into webservers, sshhosts and a svc_* group per detected service.
The Stack Overflow thread that pointed me in the right direction is worth a read if your conditions still aren't matching.