Reputation: 49
I have a system with several hosts for availability. I only need to run my Ansible playbook on one host. However some of these hosts may not be reachable. Let's say I have host1, host2, host3 ... If host1 is not reachable, I want Ansible to try host2. If host2 is reachable and Ansible runs some bash scripts successfully, I want Ansible to skip the rest of hosts. Any suggestions?
Upvotes: 3
Views: 7317
Reputation: 483
This is probably not the optimal solution, but I couldn't find a better one.
gather_facts
to False
, to entirely skip the hosts that need to be skipped (if you don't need to gather the host facts).serial
to 1, so the playbook is played entirely on one host at a time instead of the default 5 hosts in parallel.set_fact
to set a host fact (named done
in example) to True
at the end of a play, or use register
if you need a more specific condition (a command output).end_play
meta
at the start of the play that would execute when the variable is set to True
(or has the expected value, if you used register
) for any host. I used the Jinja2 template language to extract the value this way:
for
to loop over all the hostvars
(Python dict containing all the variables set for all hosts in the inventory).if
to check whether a host has done
variable set to True
and return a string True
if it is.default
filter to set the default value if done
is not defined for a host (that would cause an error 'dict object' has no attribute 'done'
).For example:
- hosts: all
serial: 1
gather_facts: False
tasks:
- meta: end_play
when: "{% for item in hostvars.values() %}{% if item.done|default(False) %}True{% endif %}{% endfor %}"
# The rest of the play goes here
- set_fact:
done: True
Upvotes: 3
Reputation: 118
Ansible doesn't consider those hosts which are not reachable, in setup phase unreachable hosts list will be dropped.
On remaining list of hosts use 'run_once: yes' for that specific task of that bash script. It will pick first matching host from available hosts.
Upvotes: -1