How to get a list of unreachable hosts

1,226 views
Skip to first unread message

omoeko

unread,
Jun 29, 2021, 3:42:21 PM6/29/21
to Ansible Project

Hi All.

I have the ansible role coded below.

    ---
      - name: Get host facts
        set_fact:
          serverdomain: "{{ansible_domain}}"
          server_ip: "{{ansible_ip_addresses[1]}}"
    
      - name: Host Ping Check
        failed_when: false
        win_ping:
        register: var_ping
    
      - name: Get Host name
        debug: msg="{{the_host_name}}"
      
      - name: Set Execution File and parameters
        set_fact:
          scriptfile: "{{ansible_user_dir}}\\scripts\\host_check.ps1"
          params: "-servername '{{the_host_name}}' -response var_ping.failed"
      
      - name: Execute script
        win_command: powershell.exe "{{scriptfile}}" "{{params}}"


It works the way it should do but of course unreachable hosts are not touched at all. I would like to generate a list or is there a variable which contains all the unreachable hosts. Is it possible to have this in a comma delimmeted list and stored in a variable ?

Lastly, to add the gather_facts: no. where do i add this in the ansible role ?

Vladimir Botka

unread,
Jun 30, 2021, 1:04:02 AM6/30/21
to omoeko, ansible...@googlegroups.com
On Tue, 29 Jun 2021 12:42:21 -0700 (PDT)
omoeko <atoloye...@gmail.com> wrote:

> Lastly, to add the gather_facts: no. where do i add this in the ansible
> role ?

See "Playbook Keywords". The directive gather_facts is available in a
play only.
https://docs.ansible.com/ansible/latest/reference_appendices/playbooks_keywords.html

> ... is there a variable which contains all the unreachable hosts. Is it possible to have this in a
> comma delimmeted list and stored in a variable ?

The following solution won't work if you set "gather_facts: no".

Yes, there are "Special Variables"
https://docs.ansible.com/ansible/latest/reference_appendices/special_variables.html

Quoting:

* ansible_play_hosts_all: List of all the hosts that were targeted by
the play.

* ansible_play_hosts: List of hosts in the current play run, not
limited by the serial. Failed/Unreachable hosts are excluded from
this list.

For example

- hosts: alpha,beta,charlie
gather_facts: true
tasks:
- block:
- debug:
var: ansible_play_hosts_all
- debug:
var: ansible_play_hosts
- set_fact:
down: "{{
ansible_play_hosts_all|difference(ansible_play_hosts) }}"
- debug:
var: down
run_once: true

gives when the host alpha is down

ansible_play_hosts_all:
- alpha
- beta
- charlie

ansible_play_hosts:
- beta
- charlie

down:
- alpha


--
Vladimir Botka

omoeko

unread,
Jun 30, 2021, 2:30:39 PM6/30/21
to Ansible Project
Thank you so much for this.

I have now been able to use thesame login in my ansible role, and it appears to work.


- name Unreachable servers
  set_fact:
    down: "{{ ansible_play_hosts_all | difference(ansible_play_hosts)}}"


  - name: Set Execution File and parameters
    set_fact:
      scriptfile: "{{ansible_user_dir}}\\scripts\\host_check.ps1"

      params: "-servername '{{the_host_name}}' -response var_ping.failed -unreachable_hosts {{ down }}"



  - name: Execute script
    win_command: powershell.exe "{{scriptfile}}" "{{params}}"

    when: inventory_hostname == {{ db_server_host }}


I do however have some questions. My playbook runs against hosts defined in my inventory, in this case what I want to achieve is a situation where the unreachable hosts is passed onto a powershell script right at the end and at once. So for example, 100 hosts, 10 were unreachable. The playbook should gather the 10 unreachable hosts, and pass the list of hosts in an array format to a powershell script or as a json data type.

All I want to do is be able to process the list of unreachable servers from my powershell script.

At the moment, I get

[ "server1", "server2" ]

MY script will work with a format like this "server1","server2"

Lastly.The process of logging the unreachable servers at the end, only needs to happen once to a specific server which does the logging to a database. I created a task to do this as seen above.

db_server_host is being passed as a extra variables from ansible tower. The reason i added the when is that I only want it to run on the DB server and not on every host. I get the error The conditional check inventory_hostname == {{ db_server_host }} failed. The error was error while evaluating conditional inventory_hostname == {{ db_server_host }} 'mydatabaseServerName' is undefined

Vladimir Botka

unread,
Jun 30, 2021, 3:09:54 PM6/30/21
to omoeko, ansible...@googlegroups.com
On Wed, 30 Jun 2021 11:30:39 -0700 (PDT)
omoeko <atoloye...@gmail.com> wrote:

> - name: Execute script
> win_command: powershell.exe "{{scriptfile}}" "{{params}}"
> when: inventory_hostname == {{ db_server_host }}
>
> [ "server1", "server2" ]
>
> MY script will work with a format like this "server1","server2"

Try

- name: Execute script
win_command: "powershell.exe {{ scriptfile }} {{ params }}"
delegate_to: db_server_host
run_once: true
vars:
params: "{{ down|join(',') }}"

1) Use the filter *join* to create the variable *params* given the
list "down=[server1, server2]"

2) Use *delegate_to* and *run_once* instead of the condition


3) The braces {{ }} in the condition is the reason of the syntax
error.



--
Vladimir Botka

omoeko

unread,
Jun 30, 2021, 6:40:44 PM6/30/21
to Ansible Project
Thanks so much for takig the time to explain, this has helped me a lot.

Implemented the changes, however its complaining about the vars definition below.

vars:
    params: "{{ down|join(',') }}"

I kept it in its own block, rather than placing it under the win_command block.

Is this the right approach or should it go under the vars>>main.yaml file ?

Vladimir Botka

unread,
Jun 30, 2021, 8:34:15 PM6/30/21
to omoeko, ansible...@googlegroups.com
On Wed, 30 Jun 2021 15:40:43 -0700 (PDT)
omoeko <atoloye...@gmail.com> wrote:

> ... its complaining about the vars definition below.
>
> vars:
> params: "{{ down|join(',') }}"
>
> I kept it in its own block, rather than placing it under the win_command
> block. Is this the right approach or should it go under the
> vars>>main.yaml file ?

The only difference is the scope of the variable. It's visible to the
task only if declared in the *vars* of the task. It should work also
if declared in the *vars* of a playbook. Post the "Minimal working
example".
https://en.wikipedia.org/wiki/Minimal_working_example


--
Vladimir Botka

omoeko

unread,
Jul 9, 2021, 10:36:26 AM7/9/21
to Ansible Project
thanks so much. I got it working.
Reply all
Reply to author
Forward
0 new messages