1
votes

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, how/where do i need to set gather_facts: no. I tried several places to no avail.

EDIT 1

- 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 }}

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

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

2

2 Answers

1
votes

Q: "Get a list of unreachable hosts in an Ansible playbook."

A: Use Special Variables. 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.

Given the inventory

shell> cat hosts
alpha
beta
charlie
delta

The playbook

- 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


  ansible_play_hosts_all:
  - alpha
  - beta
  - charlie

  ansible_play_hosts:
  - beta
  - charlie

  down:
  - alpha

Host alpha was unreachable

PLAY [alpha,beta,charlie] *************************************************

TASK [Gathering Facts] ****************************************************
fatal: [alpha]: UNREACHABLE! => changed=false 
  msg: 'Failed to connect to the host via ssh: ssh: connect to host test_14 port 22: No route to host'
  unreachable: true
ok: [charlie]
ok: [beta]

Note

The dictionary hostvars keeps all hosts from the inventory, e.g.

- hosts: alpha,beta,charlie
  gather_facts: true
  tasks:
    - debug:
        var: hostvars.keys()
      run_once: true

gives

  hostvars.keys():
  - alpha
  - beta
  - charlie
  - delta
0
votes
  tasks:
  - ping:
    register: ping_out
    # one can include any kind of timeout or other stall related config here

  - debug:
      msg: |
        {% for k in hostvars.keys() %}
        {{ k }}: {{ hostvars[k].ping_out.unreachable|default(False) }}
        {% endfor %}

yields (when an inventory consisting of only an alive alpha host):

    msg: |-
     alpha: False
     beta: True
     charlie: True

Lastly, how/where do i need to set gather_facts: no. I tried several places to no avail.

It only appears one time in the playbook keywords and thus it is a play keyword:

- hosts: all
  gather_facts: no
  tasks:
  - name: now run "setup" for those who you wish to gather_facts: yes
    setup:
    when: inventory_host is awesome