1

After executing an ansible playbook, I need the node names that were not reached. I thought about using AnsibleRunner for running the ansible-playbook and I know of the special variables ansible_play_hosts and ansible_play_hosts_all which you can diff to get the unreachable nodes. But those special variables only exist in the context of ansible.

So how do I get the unreachable nodes from AnsibleRunner (or a similar utility), without parsing ansible's output.

On Runner Objects

Currently I am creating a runner object and evaluating its variables after execution. I see that in the events I can theoretically look for unreachable nodes, but that seems to be quite sketchy.

One might also be able to write an event handler that specifically catches those events that indicate that a node is unreachable that handles those cases differently.

I also wrote a small fact registration that registers which nodes are unreachable which will be executed as a last task, but I couldn't access it yet:

- set_fact:
    unreachable: "{{ ansible_play_hosts_all|difference(ansible_play_hosts) }}"

On ansible API

The ansible API has in its example a dictionary called host_unreachable. While that sounds very promising I have two issues with it: I) I couldn't run the example II) The API will not be downwards compatible and therefore shouldn't be used externally.

Natan
  • 728
  • 1
  • 7
  • 23
  • The first idea that came to my mind was: have ansible write that info somewhere (a file, a memory cache, a database, a topic/queue....) before it exists and read the info from there. Then I overlooked the [documentation](https://ansible-runner.readthedocs.io/en/stable/) and I'm quite sure the way to go is parsing the [runner events](https://ansible-runner.readthedocs.io/en/stable/python_interface/#runner-events) – Zeitounator Sep 30 '22 at 12:03
  • See [Example 3: Handle custom status of playbook](https://ansible-runner-role.readthedocs.io/en/latest/example3-status.html). – Vladimir Botka Sep 30 '22 at 12:07
  • If someone would elaborate a little on their suggested solution I would be glad. I will be updating the question with what I have learned – Natan Sep 30 '22 at 15:19

1 Answers1

2

What you are looking for is actually available out of the box in the Runner.stats property once your playbook has run.

Example implementation

Given:

  1. the inv.yml inventory
 ---
 local_test:
   vars:
     ansible_connection: local
     failling_hosts:
       - test2
       - test3
   hosts:
     test1:
     test2:
     test3:
     test4:
 
 unreachable:
   hosts:
     test5:
  1. the test.yml playbook
---
- hosts: all

  tasks:
    - name: dummy task for all
      debug:
        msg: task1 for all hosts

    - name: blindly fail some hosts for test
      assert:
        that: inventory_hostname not in (failling_hosts | d([]))

    - name: dummy task for survivors
      debug:
        msg: task2 for survivors
  1. the test.py python script
import ansible_runner

runner = ansible_runner.run(
    private_data_dir='.',
    inventory='inv.yml',
    playbook='test.yml',
    quiet=False if len(sys.argv) > 1 and sys.argv[1] == '-v' else True
)

overall_failed = {
    'unreachable': runner.stats['dark'].keys(),
    'failed': runner.stats['failures'].keys()
}

for elem_type, elements in overall_failed.items():
    for i, host in enumerate(elements):
        if i == 0:
            print(f'\nList of {elem_type} hosts:')
        print(f'\t{host}')

We get (run with -v if you want the playbook output too):

$ python test.py

List of unreachable hosts:
    test5

List of failed hosts:
    test2
    test3
Zeitounator
  • 38,476
  • 7
  • 53
  • 66
  • I will test and confirm this on Monday. This sounds very promising. – Natan Oct 01 '22 at 19:53
  • This works like a charm. Given that stats["dark] returns a dictionary with the nodes as key and 1 as the value: What meaning does the '1' carry? I couldn't find it in the documentation. – Natan Oct 04 '22 at 07:02
  • 1
    It's the number of "events". It does have much sense for unreachable as it should only be one anyway. Nuber of changes of ok task is probably more meaningful. – Zeitounator Oct 04 '22 at 09:06