Search code examples
ansibleansible-inventory

Adding a task to a playbook which must run even when other roles failed


I have the following playbook:

---
- hosts: "{{ target }}"
  gather_facts: no

  roles:
   - role1
   - role2

  tasks:
    - block:
        - name: Role3
          ansible.builtin.include_role:
            name: role3
      rescue:
        - meta: clear_host_errors

    - ansible.builtin.include_role:
        name: final-role

I was expecting to achieve the following here:

  • If role1 or role2 fails, there is no need to run final-role.
  • If role 3 fails, I want to run final-role (mandatory).
  • If role 3 fails, when finishing executing the playbook (this is, after running final-role), it should return FAILED status (as it would do if role3 failed and if it was not running inside the block).

The first 2 I achieved them already. However what would be the best way to cause the play to FAIL after running-final role, if role3 failed before?


Solution

  • I did not really get if you want to run final_role only if role3 failed or always so here are the two options:

    Notes:

    • although dash (-) is not strictly forbidden for role names, it will trigger errors in tools like ansible-lint and will be unconditionnaly transformed to _ when uploading to galaxy. So I renamed final-role to final_role in the below examples as a good practice
    • I'm not really sure why you use clear_host_errors in your playbook and left it untouched. But it is not mandatory/useful for the current issue

    final_role only on failure:

        - block:
            - name: Run role3
              ansible.builtin.include_role:
                name: role3
    
          rescue:
            - meta: clear_host_errors
    
            - name: Run final role as we failed
              ansible.builtin.include_role:
                name: final_role
           
            - name: Report failure after rollback and remedy
              ansible.builtin.fail:
                msg: role3 failed
    

    final_role always and final failure if role3 failed:

        - block:
            - name: Run role3
              ansible.builtin.include_role:
                name: role3
    
          rescue:
            - meta: clear_host_errors
    
            - name: Register failure
              ansible.builtin.set_fact:
                role3_failed: true
    
          always:
            - name: Run final role
              ansible.builtin.include_role:
                name: final_role
           
            - name: Report failure if needed
              ansible.builtin.fail:
                msg: role3 failed
              when: role3_failed | d(false) | bool