I am trying to match hosts using a regex pattern with ansible but it is not working as expected. My inventory is as seen below:
[group1]
hello1
world1
hello2
world2
[group2]
hello3
And my task is:
- debug:
msg: "{{ item }}"
with_inventory_hostnames:
- ~hello*
From their documentation:
Using regexes in patterns
You can specify a pattern as a regular expression by starting the pattern with ~:
~(web|db).*\.example\.com
When I execute the task there is no output. I am a n00b with regex so could it be possible my regex is wrong?
Q: "Could it be possible my regex is wrong?"
A: It's a bug. See inventory_hostnames lookup doesn't support wildcards in patterns #17268. It will be probably fixed in 2.10. But your pattern wouldn't work, I think, because the doc says: "You can use wildcard patterns with FQDNs or IP addresses, as long as the hosts are named in your inventory by FQDN or IP address". The hosts in your inventory are neither FQDN nor IP.
Q: "Is there a way to use a regular expression to match hosts in ansible?"
A: Yes. It is. A very convenient way is to create dynamic groups with the module add_host. For example the playbook below
- hosts: localhost
tasks:
- add_host:
name: "{{ item }}"
groups: my_dynamic_group
loop: "{{ groups.all|select('match', my_pattern)|list }}"
vars:
my_pattern: '^hello\d+$'
- hosts: my_dynamic_group
tasks:
- debug:
var: inventory_hostname
gives (abridged)
"inventory_hostname": "hello2"
"inventory_hostname": "hello1"
"inventory_hostname": "hello3"
Update
The next option is the inventory plugin constructed. See
shall> ansible-doc -t inventory ansible.builtin.constructed
shell> tree inventory/
inventory/
├── 01-hosts
└── 02-constructed.yml
0 directories, 2 files
shell> cat inventory/01-hosts
[group1]
hello1
world1
hello2
world2
[group2]
hello3
shell> cat inventory/02-constructed.yml
plugin: ansible.builtin.constructed
groups:
hello_group: inventory_hostname.startswith('hello')
world_group: inventory_hostname.startswith('world')
shell> ansible-inventory -i inventory --graph
@all:
|--@group1:
| |--hello1
| |--hello2
| |--world1
| |--world2
|--@group2:
| |--hello3
|--@hello_group:
| |--hello1
| |--hello2
| |--hello3
|--@ungrouped:
|--@world_group:
| |--world1
| |--world2
You can see that the plugin created two groups: world_group and hello_group.
shell> cat pb.yml
- hosts: hello_group
tasks:
- debug:
var: ansible_play_hosts_all
run_once: true
- hosts: world_group
tasks:
- debug:
var: ansible_play_hosts_all
run_once: true
gives
shell> ansible-playbook -i inventory pb.yml
PLAY [hello_group] ***************************************************************************
TASK [debug] *********************************************************************************
ok: [hello1] =>
ansible_play_hosts_all:
- hello1
- hello2
- hello3
PLAY [world_group] ***************************************************************************
TASK [debug] *********************************************************************************
ok: [world1] =>
ansible_play_hosts_all:
- world1
- world2
PLAY RECAP ***********************************************************************************
hello1: ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
world1: ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With