How to Use Ansible ignore_errors to Handle Task Failures

Ansible ignore_errors Example

Ansible is a handy tool to simplify configuration management and application deployment. However, when running a playbook, some tasks may fail. By default, a task failure halts the playbook execution. But what if you want to continue executing the playbook despite a failure? This is where Ansible’s ignore_errors directive becomes useful.

This article provides an in-depth understanding of the ignore_errors directive and explains when and how to use it with examples.

What is ignore_errors in Ansible?

The ignore_errors directive in Ansible allows you to specify that the failure of a particular task should not stop the playbook’s execution. When ignore_errors: yes is added to a task, Ansible will log the failure but will proceed with subsequent tasks.

Key Points:

  • It applies only to the task it is declared in.
  • Failures are still logged in the output, but they don’t halt the execution.

Why Use ignore_errors in Ansible?

While ignoring errors is not always recommended, there are scenarios where it becomes essential:

  • Non-critical Tasks: Tasks that are optional or do not significantly impact the workflow.
  • Dynamic Environments: Environments where certain tasks may fail unpredictably but are safe to ignore.
  • Testing and Debugging: Debugging playbooks to determine how subsequent tasks behave after a failure.

Syntax and Usage of ignore_errors

The syntax for using ignore_errors is simple. You add the directive to a task with the value yes.

Example:

- name: Attempt to install a package
  ansible.builtin.yum:
    name: non-existent-package
    state: present
  ignore_errors: yes

In this example, even if the package installation fails, Ansible will continue executing the playbook.

Example 1: Ignoring a Simple Command Failure

This example playbook demonstrates a scenario where a command might fail, but you want to proceed with other tasks.

- name: Handle Directory Creation
  hosts: all
  become: yes
  tasks:
    - name: Create a directory
      ansible.builtin.command:
        cmd: mkdir /tmp/test_dir
      ignore_errors: yes

    - name: Notify directory creation
      ansible.builtin.debug:
        msg: "Directory creation attempted. Playbook will proceed regardless of success or failure."

If the directory already exists, the command will fail, but the playbook will continue execution.

Example 2: Ignoring Errors in Loops

Some iterations may fail when looping through items. Using ignore_errors, you can ensure the loop continues despite failures.

- name: Install Packages Across Servers
  hosts: app_servers
  become: yes
  tasks:
    - name: Install multiple packages
      ansible.builtin.yum:
        name: "{{ item }}"
        state: present
      loop:
        - httpd
        - non-existent-package
        - nginx
      ignore_errors: yes

Ansible will attempt to install each package using the yum module. If non-existent-package fails, the other items in the loop will still execute.

Example 3: Conditional Execution After Ignoring Errors

You can use ignore_errors in combination with conditionals to manage task execution based on previous results.

- name: Run a Command with Conditional Handling
  hosts: database_servers
  become: yes
  tasks:
    - name: Run a database-related command
      ansible.builtin.command:
        cmd: /usr/bin/db-migration-script
      register: result
      ignore_errors: yes

    - name: Check if command succeeded
      ansible.builtin.debug:
        msg: "Migration succeeded with output: {{ result.stdout }}"
      when: result.failed == false

    - name: Handle migration failure
      ansible.builtin.debug:
        msg: "Migration failed but was ignored."
      when: result.failed == true

This example handles success and failure separately after ignoring errors, providing better control over the playbook flow.

Real-World Example: Handling Software Installation Across Multiple Operating Systems

In a multi-operating-system environment, you may need to install software packages that vary between systems. For example, nginx might be installed using apt on Ubuntu and yum on CentOS.

However, if the playbook encounters an unknown package manager or other issues, some tasks may fail. Using ignore_errors, you can ensure the playbook continues on other systems.

- name: Install NGINX Across Multiple Environments
  hosts: all
  become: yes
  tasks:
    - name: Install nginx on Debian-based systems
      ansible.builtin.apt:
        name: nginx
        state: present
      when: ansible_os_family == "Debian"
      ignore_errors: yes

    - name: Install nginx on Red Hat-based systems
      ansible.builtin.yum:
        name: nginx
        state: present
      when: ansible_os_family == "RedHat"
      ignore_errors: yes

    - name: Validate NGINX installation
      ansible.builtin.command:
        cmd: nginx -v
      register: nginx_check
      ignore_errors: yes

    - name: Log installation results
      ansible.builtin.debug:
        msg: >
          NGINX installation succeeded on {{ inventory_hostname }}
          with output: {{ nginx_check.stdout if not nginx_check.failed else 'Installation failed' }}

    - name: Handle installation failures
      ansible.builtin.debug:
        msg: >
          Installation failed on {{ inventory_hostname }} but was ignored.
      when: nginx_check.failed

In this playbook:

  • Uses when conditional to install nginx using the appropriate package manager for Debian-based or Red Hat-based systems.
  • If either installation fails, the failure is logged, but the playbook continues.
  • Failure messages are logged with clear details about which host encountered the issue and why.

Conclusion

The ignore_errors directive is a valuable feature in Ansible for handling non-critical task failures without halting playbook execution. It ensures that your automation workflow continues even when certain tasks fail. By following best practices and using ignore_errors judiciously, you can create resilient and reliable playbooks.

FAQs

1. Is ignore_errors compatible with block statements?

Yes, you can use ignore_errors within a task inside a block. However, it doesn’t affect the behavior of other tasks in the block.

2. Can I debug why a task failed when using ignore_errors?

Yes, by registering the task's output, you can analyze the failure using a debug task to print details like stdout and stderr.

3. How can I combine ignore_errors with error handling?

Use register to capture the task result and combine it with conditional checks (when) or rescue blocks for advanced error handling.

About Hitesh Jethva

I am Hitesh Jethva, Founder and Author at Code2DevOps.com. With over 15 years of experience in DevOps and open source technologies, I am passionate about empowering teams through automation, continuous integration, and scalable solutions.

View all posts by Hitesh Jethva