Block and Rescue behavior question

Is a “rescue” in a “block” supposed to run at the very end of a play?

The documentation and examples would lead you to believe that a rescue is supposed to happen immediately following a block failure. I am not seeing that behavior though.

Example:

  • task_module_1:

  • block:

  • task_module_2:
    loop: items

rescue:

  • task_module_3:

  • task_module_4:

The output is the following:

task_module_1
task_module_2 - fails

task_module_4
task_module_3

Thanks,
Michael

Is a "rescue" in a "block" supposed to run at the very end of a play?

No.

The documentation and examples would lead you to believe that a rescue is
supposed to happen immediately following a block failure.

That's correct.

I am not seeing that behavior though.

I'm do.

playbook:
- hosts: localhost
  tasks:
    - debug: msg="first"
    - block:
        - debug: msg="second"
        - fail:
      rescue:
        - debug: msg="third"
    - debug: msg="fourth"

Output:

localhost | SUCCESS => {
    "msg": "first"
}
localhost | SUCCESS => {
    "msg": "second"
}
localhost | FAILED! => {
    "changed": false,
    "msg": "Failed as requested from task"
}
localhost | SUCCESS => {
    "msg": "third"
}
localhost | SUCCESS => {
    "msg": "fourth"
}

Michael,

That is correct: rescue tasks run immediately after the task that fails. I'm unable to duplicate the behavior you're seeing.

I’ve been able to reproduce it with a small test case. The issue is with multiple hosts using a real inventory (localhost is fine) and the block/rescue must be inside a role.

inventory:
[test_inv]
hostA
hostB

playbook:

  • hosts: test_inv
    gather_facts: false
    vars:
    test_list:
  • echoa
  • hecob
  • echoc
  • echod
    tasks:
  • import_role:
    name: test

role test:

  • shell: echo second

  • block:

  • when:

  • not ansible_check_mode

  • item != ‘echoc’

  • inventory_hostname != ‘hostA’
    shell: “{{ item }}”
    changed_when: false
    register: block_var
    loop: “{{ test_list }}”
    rescue:

  • when:

  • block_var.skipped is not defined

  • block_var.failed
    shell: echo fourth
    changed_when: false

  • when:

  • item != ‘echoc’

  • inventory_hostname != ‘hostA’
    shell: “{{ item }}”
    loop: “{{ test_list }}”

  • shell: echo sixth

The ‘echo sixth’ task is not the last task that is run. Is this expected when run inside a role?

It's a bug with import_role and include_role.
I made test code that only run against localhost and somewhat easier to follow.

inventory

Thanks. I stole your test case and opened a bug report.

https://github.com/ansible/ansible/issues/64999