How to select all hosts except the inventory_hostname from a group?
Solution 1:
An option would be to use the difference filter. Below is an example of how to use the filter
shell> cat test-difference-01.yml
- hosts: localhost
gather_facts: no
vars:
web_servers:
- web-server-01
- web-server-02
- web-server-09
inventory_hostname:
- web-server-02
tasks:
- set_fact:
delegate_to_hosts: "{{ web_servers|difference(inventory_hostname) }}"
- debug:
msg : "{{ delegate_to_hosts }}"
shell> ansible-playbook test-difference-01.yml | grep -A 3 msg
"msg": [
"web-server-01",
"web-server-09"
]
Q: "group of two hosts ... delegate a task to the one that is not the current host"
Given the inventory
shell> cat hosts
[webservers]
web-server-01
web-server-02
The playbook
- hosts: webservers
tasks:
- debug:
msg: "{{ inventory_hostname }} {{ item }}"
loop: "{{ groups.webservers|difference([inventory_hostname]) }}"
delegate_to: "{{ item }}"
gives (abridged)
ok: [web-server-01 -> web-server-02] => (item=web-server-02) =>
msg: web-server-01 web-server-02
ok: [web-server-02 -> web-server-01] => (item=web-server-01) =>
msg: web-server-02 web-server-01
The code can be generalized by running on all hosts listed in ansible_play_hosts_all
- hosts: all
tasks:
- debug:
msg: "{{ inventory_hostname }} {{ item }}"
loop: "{{ ansible_play_hosts_all|difference([inventory_hostname]) }}"
delegate_to: "{{ item }}"
Solution 2:
You don't need to specify a regex with negative lookahead. Instead, use the reject
filter.
Also, with equalto
test, you don't need to enclose the string in ^
and $
:
- debug:
msg: "{{ groups['web-servers'] | reject('equalto', inventory_hostname) | list }}"