Search code examples
ansible

Clarification around ansible rescue and how it continues the execution of tasks


I think i have a decent understanding of how rescue works in ansible, appears very similar to try/catch/finaly in other languages, but there is one specific detail from the documentation i don't get.

copied from: https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_blocks.html

If an error occurs in the block and the rescue task succeeds, Ansible reverts the failed status of the original task for the run and continues to run the play as if the original task had succeeded. The rescued task is considered successful and does not trigger max_fail_percentage or any_errors_fatal configurations. However, Ansible still reports a failure in the playbook statistics.

My question is the behavior of a rescue setion when it succeeds or fails.

Lets say i have a block of tasks with a rescue section, first task fails and activates the rescue tasks, the rescue tasks succeeds. based on above quote i understand that the execution will then continue with the task after the one that failed, as if the failing tasks succeeded. Is this correct?

Reason for asking is that that is not what happens when i test it and i think the documentation is confusing. Understanding what happens on rescue success/fail is important because in my case i don't want rescue to cause the rest of the tasks to execute.


Solution

  • The confusing part is what a task is in the context of documentation. Look at the example, provided in docs

     tasks:
       - name: Handle the error
         block:
           - name: Print a message
             ansible.builtin.debug:
               msg: 'I execute normally'
    
           - name: Force a failure
             ansible.builtin.command: /bin/false
    
           - name: Never print this
             ansible.builtin.debug:
               msg: 'I never execute, due to the above task failing, :-('
         rescue:
           - name: Print when errors
             ansible.builtin.debug:
               msg: 'I caught an error, can do stuff here to fix it, :-)'
    

    Here, at playbook level, we have a single task, called "Handle the error". If rescue block will return successfully, any potential tasks after "Handle the error" will continue to be executed, but everything inside block after error will be skipped. This is how usually try/except blocks work in programming languages,for example python docs specify that (emphasis is mine):

    • First, the try clause (the statement(s) between the try and except keywords) is executed.

    • If no exception occurs, the except clause is skipped and execution of the try statement is finished.

    • If an exception occurs during execution of the try clause, the rest of the clause is skipped. Then, if its type matches the exception named after the except keyword, the except clause is executed, and then execution continues after the try/except block.

    This is even implied with "Never print this" subtask inside block in ansible documentation.