Ansible Task Execution Scenarios
This table outlines how different Ansible directives affect the continuation of a play and the final task status when a task reports a non-zero return code (which typically indicates a failure).
| Scenario | Task Fails (rc != 0) | Play Continues? | Failure Status |
| Default (No Directives) | Yes | NO. (Play stops) (unless in a block with rescue ) | Task marked failed. |
| 1. ignore_errors: yes | Yes | YES. (Play continues) Output shows FAILED! => ... ignoring | Task marked ignored=1 in the final recap, but in the Task execution stage task will be reported as failed and Ansible proceed with next step. |
| 2. failed_when: false | Yes | YES. (Play continues) | Task marked ok or changed (based on changed_when: false directive ), but never failed. |
| 3. changed_when: false | Yes | NO. (Play stops) (unless in a block with rescue ) | Task marked failed (The directive only affects the changed status, not the failed status). |
The changed_when: false directive is typically used to prevent a task from reporting a 'changed' status, but it does not prevent a task from failing when its return code is non-zero. Therefore, it behaves like the Default scenario when a failure occurs.
The ignore_errors: yes tells Ansible: If this task fails (returns a non-zero exit code), report the failure, but keep running the rest of the playbook on this host.
A common use case is running a cleanup command where the file/service might not exist on all hosts, which would cause the task to fail but should not stop the entire play.
Ignore_errors: yes: The task still reports a failed status, but the playbook keeps running. The failure is visible in the output (often marked with ... ignoring).
Failed_when: false: The task is never marked as failed (it reports ok or changed), and the play keeps running. The original failure is completely hidden from Ansible's status tracking.By default, an Ansible task is marked as failed if the underlying command returns a non-zero exit code or if an Ansible module reports an error, applying failed_when: false to a task tells Ansible to never mark that specific task as failed, regardless of the task's normal return code or output.
Let's see an example:
oelggvm01 is my oracle db server and I'm using below ansible playbook to manage my listener.
[oracle@oel01db ansible-project]$ cat ./inventory/hosts
[db_servers]
oelggvm01
[oracle@oel01db ansible-project]$
[oracle@oel01db ansible-project]$ cat ./playbooks/changed.failed.ignore_example.yml
- name: Oracle Listener Health Check (With ignore_errors example)
hosts: db_servers
become_user: oracle
gather_facts: no
tasks:
- name: Check listener status
environment:
ORACLE_HOME: /u01/app/oracle/product/19.0.0/dbhome_1
PATH: /u01/app/oracle/product/19.0.0/dbhome_1/bin
shell: lsnrctl status
register: listener_status
changed_when: false
failed_when: false
- name: Print listener status
debug:
msg: "Listener status is: {{ listener_status.stdout }}"
- name: Stop listener (may already be down)
environment:
ORACLE_HOME: /u01/app/oracle/product/19.0.0/dbhome_1
PATH: /u01/app/oracle/product/19.0.0/dbhome_1/bin
shell: lsnrctl stop
ignore_errors: yes
changed_when: false
- name: Start listener if it is down
environment:
ORACLE_HOME: /u01/app/oracle/product/19.0.0/dbhome_1
PATH: /u01/app/oracle/product/19.0.0/dbhome_1/bin
shell: lsnrctl start
when: "'TNS-12541' in listener_status.stdout"
changed_when: true
[oracle@oel01db ansible-project]$
1. lets verify listener is down on the managed node
[oracle@oelggvm01 dbhome_1]$ lsnrctl status
LSNRCTL for Linux: Version 19.0.0.0.0 - Production on 14-DEC-2025 05:35:20
Copyright (c) 1991, 2025, Oracle. All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.0.111)(PORT=1521)))
TNS-12541: TNS:no listener
TNS-12560: TNS:protocol adapter error
TNS-00511: No listener
Linux Error: 111: Connection refused
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1521)))
TNS-12541: TNS:no listener
TNS-12560: TNS:protocol adapter error
TNS-00511: No listener
Linux Error: 2: No such file or directory
[oracle@oelggvm01 dbhome_1]$
First I've commented out below highlihgted
[oracle@oel01db ansible-project]$ cat ./playbooks/changed.failed.ignore_example.yml
- name: Oracle Listener Health Check (With ignore_errors example)
hosts: db_servers
become_user: oracle
gather_facts: no
tasks:
- name: Check listener status
environment:
ORACLE_HOME: /u01/app/oracle/product/19.0.0/dbhome_1
PATH: /u01/app/oracle/product/19.0.0/dbhome_1/bin
shell: lsnrctl status
register: listener_status
#changed_when: false
failed_when: false
- name: Print listener status
debug:
msg: "Listener status is: {{ listener_status.stdout }}"
- name: Stop listener (may already be down)
environment:
ORACLE_HOME: /u01/app/oracle/product/19.0.0/dbhome_1
PATH: /u01/app/oracle/product/19.0.0/dbhome_1/bin
shell: lsnrctl stop
#ignore_errors: yes
changed_when: false
- name: Start listener if it is down
environment:
ORACLE_HOME: /u01/app/oracle/product/19.0.0/dbhome_1
PATH: /u01/app/oracle/product/19.0.0/dbhome_1/bin
shell: lsnrctl start
when: "'TNS-12541' in listener_status.stdout"
changed_when: true
[oracle@oel01db ansible-project]$
Here fist task (lsnrctl status) is marked as changed=1 as #changed_when is updated as false
Also the play stopped its execution in the second task as #ignore_errors: yes
Next see the effect of commenting failed_when: false from the first task.
[oracle@oel01db ansible-project]$ cat ./playbooks/changed.failed.ignore_example.yml
- name: Oracle Listener Health Check (With ignore_errors example)
hosts: db_servers
become_user: oracle
gather_facts: no
tasks:
- name: Check listener status
environment:
ORACLE_HOME: /u01/app/oracle/product/19.0.0/dbhome_1
PATH: /u01/app/oracle/product/19.0.0/dbhome_1/bin
shell: lsnrctl status
register: listener_status
#changed_when: false
#failed_when: false
- name: Print listener status
debug:
msg: "Listener status is: {{ listener_status.stdout }}"
- name: Stop listener (may already be down)
environment:
ORACLE_HOME: /u01/app/oracle/product/19.0.0/dbhome_1
PATH: /u01/app/oracle/product/19.0.0/dbhome_1/bin
shell: lsnrctl stop
#ignore_errors: yes
changed_when: false
- name: Start listener if it is down
environment:
ORACLE_HOME: /u01/app/oracle/product/19.0.0/dbhome_1
PATH: /u01/app/oracle/product/19.0.0/dbhome_1/bin
shell: lsnrctl start
when: "'TNS-12541' in listener_status.stdout"
changed_when: true
[oracle@oel01db ansible-project]$
Here playbook stopped in the first task itself and it is marked as failed
Let's remove all comment and re-run
[oracle@oel01db ansible-project]$ cat ./playbooks/changed.failed.ignore_example.yml
- name: Oracle Listener Health Check (With ignore_errors example)
hosts: db_servers
become_user: oracle
gather_facts: no
tasks:
- name: Check listener status
environment:
ORACLE_HOME: /u01/app/oracle/product/19.0.0/dbhome_1
PATH: /u01/app/oracle/product/19.0.0/dbhome_1/bin
shell: lsnrctl status
register: listener_status
changed_when: false
failed_when: false
- name: Print listener status
debug:
msg: "Listener status is: {{ listener_status.stdout }}"
- name: Stop listener (may already be down)
environment:
ORACLE_HOME: /u01/app/oracle/product/19.0.0/dbhome_1
PATH: /u01/app/oracle/product/19.0.0/dbhome_1/bin
shell: lsnrctl stop
ignore_errors: yes
changed_when: false
- name: Start listener if it is down
environment:
ORACLE_HOME: /u01/app/oracle/product/19.0.0/dbhome_1
PATH: /u01/app/oracle/product/19.0.0/dbhome_1/bin
shell: lsnrctl start
when: "'TNS-12541' in listener_status.stdout"
changed_when: true
[oracle@oel01db ansible-project]$
Now the playbook ignore all error and started listener, please note ignored=1
Verify listener status
[oracle@oelggvm01 dbhome_1]$ lsnrctl status >/dev/null 2>&1; echo $?
0
[oracle@oelggvm01 dbhome_1]$
No comments:
Post a Comment