4
votes

I have 2 playbooks running on ansible, one after another. After playbook 1 finishes, I want to run the second one on only the hosts for which the first playbook fully succeeded. Looking through the ansible docs, I can't find any accessible info on which hosts failed a specific playbook. How could this be done?

FYI I need separate playbooks because the second one must be run with in serial, which is only available at the playbook level

3

3 Answers

3
votes

Where all hosts - successful hosts = failed hosts, you can use the following task to get the difference between the two special variables for all hosts in the play (including failed hosts) and all hosts that have not yet failed. Use of serial will affect the result.

    - name: Print play hosts that failed
      debug:
        msg: "The hosts that failed are {{ ansible_play_hosts_all| difference(ansible_play_batch) |join('\n') }}"

Source: https://docs.ansible.com/ansible/latest/reference_appendices/special_variables.html

1
votes

Honestly, the best way is to have some queryable state on each host. A simple method is to check for a file's existence, which is created after your first playbook succeeds. You can then have a task which checks for that state and notifies a notify task that it has been "updated", which will get what you want.

In an aside, I stopped using ansible because it wasn't configurable enough; I also had issues getting the parallelism controls I wanted. You my try hitting up the Ansible Project Google Group to put in a feature suggestion or describe your use case.

0
votes

There is a difference between a play and a playbook. The serial argument is available on the play level. A playbook may contain multiple plays.

---

- name: Play 1
  hosts: some_hosts
  tasks:
    - debug:

- name: Play 2
  hosts: some_hosts
  serial: 1
  tasks:
    - debug:

...

Hosts which failed in play 1 will not be processed in play 2.


If your really want to have separate playbooks, I see two options:

  1. Create a callback plugin. You can register a function which gets fired when a task or host fails. You can store this info then locally and use in the next playbook run.

  2. Activate Ansible logging. It will log pretty much the same stuff you see as raw output when running ansible-playbook.

Second option is bit ugly, but easier than creating a callback plugin.

It both cases you then need to create a dynamic inventory script which checks previously saved data and returns valid hosts. Or return all hosts but set a property to mark those hosts. You then can use group_by to create an ad-hoc group.