Introduction
Ansible is an automated configuration management tool used to manage multiple servers. Ansible has a core component known as Playback that contains all the required scripts or plays essential for Ansible to execute various commands. You can think of Playback as a To-do list that needs to be done by the Ansible in order. Playback is written in YAML, which stands for Yet Another Markup Language.
This article will help you to understand the error handling in ansible playbook. You know how important it is to know about error handling because sometimes you encounter an error that you might not know about it. That is why it is crucial to learn error handling in ansible playbook because it consists of scripts for automation and also scripts for error handling.
Error Handling
In Ansible, when a particular command or module returns a zero code, the command is successfully executed without any failure. If there is a non-zero code, which means this is a command failure, it will stop the execution on that particular host and continue on the other host.

This is not always the case that a non-zero return means command or module failure, and sometimes, if you encounter a failure and want to stop the execution for all the active hosts. To take care of these things, Ansible has settings or statements we can apply to implement the error handling in ansible playbook.
Ignore Failed Commands
With the help of ignore_errors, you can selectively ignore the failure that is not important for your execution, but it does not work with defined errors like syntax errors or package missing. Please keep that in mind. An important command for error handling in ansible playbook.
name: not a failure
ansible.builtin.command: /bin/false
ignore_errors: yes
Unreachable Host Errors
In error handling in ansible playbook With the help of ignore_unreachable, you can ignore the task failure if the host is not in reach.
Example at playbook level:
hosts: all
ignore_unreachable: yes
tasks:
- name: failure is ignored
ansible.builtin.command: /bin/true
- name: abort play for the host
ansible.builtin.command: /bin/true
ignore_unreachable: no
Reactive Unreachable hosts
If a particular host cannot connect in the ansible, that makes the host ‘UNREACHABLE’ and removed from the active host list, but you can make a host reactive with meta: clear_host_errors, command.
Failure and Handlers
When a specific task is completed, Ansible launches a handler. Ansible employs a handler, similar to notice, to manage situations where, for instance, you might wish to restart a service if its configuration has changed.
If a task fails later and the configuration is modified, but the service is not restarted, you can use the command-line option --force-handlers and set force-handler: true to force all handlers to run on the hosts where the job failed.
Failure in Ansible⚠️
You can define a failure using the command failed_when. failed_when in error handling in ansible playbook this works as a conditional statement, meaning that a task will only fail if it satisfies the conditions mentioned in the failed_when command. You can add multiple conditions using and, or, > operator for error handling in ansible playbook..
Examples:
- name: task fails when command error is FAILED
ansible.builtin.command: /usr/bin/example-command a-b-c
register: command_result
failed_when: "'FAILED' in command_result.stderr"
Using or
- name: task fails when files are same
ansible.builtin.raw: diff foo/file1 bar/file2
register: diff_cmd
failed_when: diff_cmd.rc == 0 or diff_cmd.rc >= 2
Changed in Ansible
Using the changed_when conditional in Ansible, you can specify when a certain job has "changed" a remote node. Changed_when allows you to decide whether a change should be displayed in Ansible reports and whether a handler should be invoked or not based on return codes or output. As like other conditionals in changed_when also use and or operators for error handling in ansible playbook.
Example:
tasks:
- name: return code is not 2 report will be changed
ansible.builtin.shell: /usr/bin/billybass --mode="take me to the river"
register: bass_result
changed_when: "bass_result.rc != 2"
- name: changed status will not be reported
ansible.builtin.shell: wall 'beep'
changed_when: False
Command and Shell Success✔️
If you have a command whose successful return code is not zero, you can perform this because the command and shell modules care about return codes:
tasks:
- name: run and ignore the output
ansible.builtin.shell: /usr/bin/somecommand || /bin/true
Aborting Play on All Hosts❌
Because sometimes you want a single failure to stop play on all of the other hosts, you can successfully stop a specific play on all of the active rest of the hosts with any_error_fatals. Alternatively, you can set a maximum percentage of failures with a max to-fail percentage, which will stop play when that specific percentage level occurs. With these commands error handling in ansible playbook is really easy.
- hosts: hostname
any_errors_fatal: true
roles:
- somerole
- hosts: hostname
tasks:
- block:
- include_tasks: list.yml
any_errors_fatal: true
Max percentage:
- hosts: someserver
max_fail_percentage: 40
serial: 6
Error Control in Blocks
Blocks containing rescue and always sections let you regulate how to perform error handling in ansible playbook. These two are really useful for error handling in Ansible.
Tasks to perform when an earlier task in a block fails are specified by rescue blocks. This strategy is comparable to how many programming languages handle exceptions. Rescue blocks are only executed by Ansible once a job returns a "failed" status. Unreachable hosts and poor task descriptions won't cause the rescue block to activate.
Example:
tasks:
- name: Handle the error
block:
- name: display message
ansible.builtin.debug:
msg: 'coding ninjas'
- name: Force failure
ansible.builtin.command: /bin/false
- name: do not display
ansible.builtin.debug:
msg: 'I am not happy.'
rescue:
- name: display errors
ansible.builtin.debug:
msg: 'there is an error in a task.'
Using always:
name: code studio
block:
- name: Print a message
ansible.builtin.debug:
msg: 'coding ninjas'
- name: Force a failure
ansible.builtin.command: /bin/false
- name: do not print
ansible.builtin.debug:
msg: 'Cannot execute.'
always:
- name: will execute
ansible.builtin.debug:
msg: "This always executes."




