How to launch playbook only on the first host of each inventory group? ... I cannot "hardcode" the groups upfront ... the complete inventory which consist out of 150 or more host groups ...
From the question and description you've provided I understand that you like to dynamically limit the execution of a playbook to certain hosts and groups. As it is still not clear (for me) what exactly and where you try to achieve, I'll provide one possible approach with CLI tools. Within a playbook and for tasks there would be other options available.
An example inventory hosts
like
[tomcat]
tomcat1.example.com
tomcat2.example.com
tomcat3.example.com
[apache]
apache1.example.com
apache2.example.com
apache3.example.com
[sql]
sql1.example.com
sql2.example.com
sql3.example.com
ansible-inventory -i hosts --graph
@all:
|--@apache:
| |--apache1.example.com
| |--apache2.example.com
| |--apache3.example.com
|--@sql:
| |--sql1.example.com
| |--sql2.example.com
| |--sql3.example.com
|--@tomcat:
| |--tomcat1.example.com
| |--tomcat2.example.com
| |--tomcat3.example.com
|--@ungrouped:
with a group list
ansible-inventory -i hosts --list | jq --raw-output '.all.children[]'
apache
sql
tomcat
ungrouped
and example playbook groups.yml
like
---
- hosts: '*'
become: false
gather_facts: false
tasks:
- name: Show Facts
debug:
msg: "{{ item }}"
when: item == inventory_hostname
loop: "{{ ansible_play_hosts }}"
called via
LIMIT=$(ansible-inventory -i hosts --list | jq --raw-output '.all.children[]' | head -n -1 | sed s/$/[0]/ | tr '\n' ',' | rev | cut -c2- | rev)
echo ${LIMIT}
apache[0],sql[0],tomcat[0]
ansible-playbook -i hosts groups.yml --limit="${LIMIT}"
will result into an oputput of
TASK [Show Facts] ****************************************
ok: [apache1.example.com] => (item=apache1.example.com) =>
msg: apache1.example.com
ok: [tomcat1.example.com] => (item=tomcat1.example.com) =>
msg: tomcat1.example.com
ok: [sql1.example.com] => (item=sql1.example.com) =>
msg: sql1.example.com
As one can see it is executing on the first host of each inventory group only.
The approach is using
- an environment variable
LIMIT
to store the generated list for --limit
- the
ansible-iventory
to list all
group
- removes the default group
ungrouped
from the output
- defines one list element by adding
[0]
- creates an CSV from the output by exchanging line breaks
\n
with ,
- and deletes the last
,
Similar Q&A
Further Readings and used during research
Since there might be other or better solutions possible ...
Follow-Ups