Handling Errors
1. Ignoring Errors
| Directive | Description | Usage |
|---|---|---|
| ignore_errors | Continues execution even if a task fails | ignore_errors: yes |
| ignore_unreachable | Continues execution if a host is unreachable | ignore_unreachable: yes |
Example: Using ignore_errors
- name: Run a command that might fail
command: /bin/false
ignore_errors: yes
register: result
- name: Display the result
debug:
msg: "Command failed with code {{ result.rc }}"
2. Defining Failure Conditions
| Property | Description | Values |
|---|---|---|
| fail_when | Condition under which a task should fail | true or false |
| failed_when | Conditional expression that determines if a task has failed | Any valid Jinja2 expression |
| ignore_errors | Whether to continue executing even if a task fails | true, false, or yes/no |
Example: Using failed_when
- name: Check if a file exists
stat:
path: /etc/myapp/config.ini
register: config_file
- name: Fail if config file does not exist
debug:
msg: "Configuration file missing"
failed_when: config_file.stat.exists == false
Example: Using ignore_errors
- name: Try to remove a file
file:
path: /tmp/somefile.txt
state: absent
ignore_errors: true
- name: Continue with other tasks
debug:
msg: "File removal attempted"
3. Defining Success Conditions
| Property | Description | Default | Notes |
|---|---|---|---|
| changed_when | Condition under which the task is marked as changed | true |
Useful for tasks that don't change the system but should report as changed |
| failed_when | Condition under which the task is marked as failed | false |
Allows overriding the default failure logic based on command output or return code |
| check_mode | Whether to run in check mode (dry-run) | false |
Set to true to simulate task execution without making changes |
Example: Using changed_when
- name: Check if file exists and report change
stat:
path: /etc/myconfig.conf
register: file_stat
changed_when: file_stat.stat.exists == false
Example: Using failed_when
- name: Run command and fail on specific output
command: echo "error occurred"
register: cmd_result
failed_when: "'error' in cmd_result.stdout"
4. Using Block Error Handling
| Directive | Description | Usage |
|---|---|---|
| block | Groups tasks together to handle errors collectively | block: followed by a list of tasks |
| rescue | Tasks to run if any task in the block fails | rescue: followed by a list of tasks |
| always | Tasks to run regardless of success or failure | always: followed by a list of tasks |
Example: Basic Block with Rescue
- name: Run tasks with error handling
block:
- name: Try to copy a file
copy:
src: /tmp/source.txt
dest: /tmp/dest.txt
- name: Try to restart a service
systemd:
name: myservice
state: restarted
rescue:
- name: Log failure
debug:
msg: "Block failed, logging error"
- name: Send alert
mail:
to: admin@example.com
subject: Ansible Playbook Failed
body: The playbook failed during block execution.
always:
- name: Cleanup
file:
path: /tmp/temp_file.txt
state: absent
Note: The
rescue block runs only if any task in the block fails. The always block runs regardless of success or failure.
Block Error Handling Summary
- block: Groups tasks for collective error handling
- rescue: Executes only if a task in the block fails
- always: Executes regardless of success or failure
5. Catching Errors
| Handler | Description | Usage |
|---|---|---|
| rescue | Executes if a task fails | rescue: block in a block |
| always | Executes regardless of success or failure | always: block in a block |
Example: Using rescue and always blocks
- name: "Run tasks with error handling"
block:
- name: "Attempt to create directory"
file:
path: /tmp/test_dir
state: directory
- name: "Try to copy file"
copy:
src: /etc/hosts
dest: /tmp/hosts_backup
rescue:
- name: "Handle failure by logging"
debug:
msg: "Failed to copy file"
- name: "Always run cleanup"
file:
path: /tmp/test_dir
state: absent
always:
- name: "Log completion"
debug:
msg: "Cleanup completed"
Note: The
rescue and always blocks are part of the block structure and allow for more granular error handling in Ansible playbooks.
6. Running Cleanup
Example: Cleanup with Ansible
- name: Run cleanup tasks
hosts: all
tasks:
- name: Remove temporary files
file:
path: "/tmp/temp_<var>{{ item }}</var>"
state: absent
loop:
- "file1"
- "file2"
- name: Stop and remove containers
docker_container:
name: "{{ item }}"
state: absent
loop:
- "webapp"
- "db"
| Task | Description | Parameters | Notes |
|---|---|---|---|
| file | Manage files and directories | path, state |
Use absent to delete files or directories |
| docker_container | Manage Docker containers | name, state |
Set state: absent to stop and remove containers |
Note: Always test cleanup tasks in a non-production environment to avoid unintended data loss.
Warning: Ensure that cleanup tasks do not interfere with ongoing operations or other systems.
Cleanup Best Practices
- Use
filemodule to remove temporary files and directories - Use
docker_containerordocker_imageto clean up Docker resources - Implement error handling to prevent cleanup from failing the entire playbook
- Log cleanup actions for auditing and debugging purposes
7. Using any_errors_fatal
| Option | Values | Notes |
|---|---|---|
| any_errors_fatal | true or false |
Stops execution on first error when set to true |
Example: Using any_errors_fatal in a Playbook
---
- name: Example Playbook with any_errors_fatal
hosts: all
any_errors_fatal: true
tasks:
- name: Task that might fail
command: /bin/false
Note: When
any_errors_fatal is set to true, the playbook will stop executing on the first task that fails, regardless of other hosts or tasks in the play.
8. Setting Max Fail Percentage
Use the max_fail_percentage directive to control how many tasks or hosts can fail before the playbook stops executing.
| Parameter | Description | Default |
|---|---|---|
| max_fail_percentage | Maximum percentage of hosts or tasks that can fail before playbook halts | 0% |
Example: Setting max_fail_percentage to 25%
- name: Playbook with max fail percentage
hosts: all
max_fail_percentage: 25
tasks:
- name: Task that might fail
command: /bin/false
Note: This setting applies to the entire play and affects all hosts in the play. It does not apply per-host or per-task.
9. Retrying Tasks
| Option | Values | Notes |
|---|---|---|
| retries | 3 |
Number of retry attempts |
| delay | 1 |
Delay between retries in seconds |
| backoff | true |
Exponential backoff for delays |
Example: Retry configuration
- name: Task with retries
ansible.builtin.command: echo "Hello World"
retries: 3
delay: 2
backoff: true
Note: Retries are applied to tasks that fail with a non-zero exit code.
10. Aborting on First Failure
| Option | Values | Notes |
|---|---|---|
| any_errors_fatal | true |
Abort playbook execution on first error |
| max_fail_percentage | 0 |
Maximum percentage of hosts that can fail before aborting |
Example: Using any_errors_fatal
---
- hosts: all
any_errors_fatal: true
tasks:
- name: Install package
apt:
name: nginx
state: present
Note:
any_errors_fatal is applied at the playbook level and affects all hosts in the play.
11. Handling Connection Errors
| Error Type | Description | Solution |
|---|---|---|
| connection_timeout | Timeout while waiting for a connection to the target host. | Adjust ansible_connection_timeout or increase network reliability. |
| authentication_failure | Failed to authenticate with the target host using provided credentials. | Verify SSH keys, passwords, or token validity in inventory or vars. |
| network_unreachable | Network path to the target host is unreachable. | Check network configuration, firewall rules, and reachability from the control node. |
Example: Setting Connection Timeout
- name: Example Playbook with Timeout
hosts: all
vars:
ansible_connection_timeout: 30
tasks:
- name: Fetch system info
command: uname -a
Note: Ansible uses a default connection timeout of 10 seconds. For environments with high latency or slow network conditions, increasing this value can prevent connection-related failures.