Open
Description
Summary
The problem occurs if the any_errors_fatal parameter is enabled and one of the hosts is expected to fail with an error.
Ansible correctly transitions all hosts into rescue mode, but when plays are subsequently launched, Ansible only replays roles on the host where the error occurred, ignoring all others.
Issue Type
Bug Report
Component Name
linear.py
Ansible Version
$ ansible --version
ansible [core 2.17.5]
config file = /tests/ansible.cfg
configured module search path = ['/usr/share/ansible/plugins/modules']
ansible python module location = /venv_test_ansible/lib/python3.11/site-packages/ansible
executable location = /venv_test_ansible/bin/ansible
python version = 3.11.6 (v3.11.6:8b6ee5ba3b, Oct 2 2023, 11:18:21) [Clang 13.0.0 (clang-1300.0.29.30)] (/venv_test_ansible/bin/python3.11)
jinja version = 3.1.4
libyaml = True
Configuration
# if using a version older than ansible-core 2.12 you should omit the '-t all'
$ ansible-config dump --only-changed -t all
ANY_ERRORS_FATAL(ansible.cfg) = True
CACHE_PLUGIN(ansible.cfg) = jsonfile
CACHE_PLUGIN_CONNECTION(ansible.cfg) = cache.json
CONFIG_FILE() = ansible.cfg
DEFAULT_DEBUG(env: ANSIBLE_DEBUG) = False
DEFAULT_FORKS(ansible.cfg) = 20
DEFAULT_GATHERING(ansible.cfg) = smart
DEFAULT_STDOUT_CALLBACK(ansible.cfg) = yaml
DEFAULT_TIMEOUT(ansible.cfg) = 600
DEPRECATION_WARNINGS(ansible.cfg) = False
DISPLAY_SKIPPED_HOSTS(ansible.cfg) = False
ENABLE_TASK_DEBUGGER(env: ANSIBLE_ENABLE_TASK_DEBUGGER) = False
HOST_KEY_CHECKING(ansible.cfg) = False
INVENTORY_ENABLED(ansible.cfg) = ['script', 'ini', 'yaml']
PAGER(env: PAGER) = less
VARIABLE_PRECEDENCE(ansible.cfg) = ['all_plugins_play', 'all_inventory', 'all_plugins_inventory', 'groups_plugins_play', 'groups_inventory', 'groups_plugins_inventory']
CACHE:
=====
jsonfile:
________
_uri(ansible.cfg) = cache.json
CALLBACK:
========
default:
_______
display_skipped_hosts(ansible.cfg) = False
CONNECTION:
==========
paramiko_ssh:
____________
host_key_checking(ansible.cfg) = False
ssh_args(ansible.cfg) = -o ControlMaster=auto -o ControlPersist=600s
timeout(ansible.cfg) = 600
ssh:
___
control_path(ansible.cfg) = %(directory)s/%%h-%%r
host_key_checking(ansible.cfg) = False
pipelining(ansible.cfg) = True
ssh_args(ansible.cfg) = -o ControlMaster=auto -o ControlPersist=600s
timeout(ansible.cfg) = 600
OS / Environment
RHEL 8, DEBIAN 10
Steps to Reproduce
- name: Get ping response
hosts: all
tasks:
- name: checkup
block:
- name: debug
debug:
msg: 'start'
- ansible.builtin.debug: msg="{{ test_msg }}"
when: inventory_hostname == 'host_3'
- block:
- name: debug
debug:
msg: 'test1'
- name: debug
debug:
msg: 'test2'
when: inventory_hostname in groups["test_group"]
- name: debug
debug:
msg: 'finish'
rescue:
- ansible.builtin.debug:
msg: "{{ ansible_failed_result | d(false) }}"
always:
- name: debug
debug:
msg: 'finish always'
- name: test
hosts: all
tasks:
- ansible.builtin.debug:
msg: "{{ play_hosts }}"
Expected Results
PLAY [Get ping response] *******************************************************************************************************************************************************************************************************
TASK [debug] *******************************************************************************************************************************************************************************************************************
task path: 1.yml:8
ok: [host_1] =>
msg: start
ok: [host_2] =>
msg: start
ok: [host_3] =>
msg: start
TASK [ansible.builtin.debug] ***************************************************************************************************************************************************************************************************
task path: 1.yml:12
fatal: [host_3]: FAILED! =>
msg: |-
The task includes an option with an undefined variable.. 'test_msg' is undefined
The error appears to be in '1.yml': line 12, column 11, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
- ansible.builtin.debug: msg="{{ test_msg }}"
^ here
We could be wrong, but this one looks like it might be an issue with
missing quotes. Always quote template expression brackets when they
start a value. For instance:
with_items:
- {{ foo }}
Should be written as:
with_items:
- "{{ foo }}"
META: cleared host errors
TASK [ansible.builtin.debug] ***************************************************************************************************************************************************************************************************
task path: 1.yml:35
ok: [host_1] =>
msg: false
ok: [host_2] =>
msg: false
ok: [host_3] =>
msg:
failed: true
msg: |-
The task includes an option with an undefined variable.. 'test_msg' is undefined
The error appears to be in '1.yml': line 12, column 11, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
- ansible.builtin.debug: msg="{{ test_msg }}"
^ here
We could be wrong, but this one looks like it might be an issue with
missing quotes. Always quote template expression brackets when they
start a value. For instance:
with_items:
- {{ foo }}
Should be written as:
with_items:
- "{{ foo }}"
TASK [debug] *******************************************************************************************************************************************************************************************************************
task path: 1.yml:39
ok: [host_1] =>
msg: finish always
ok: [host_2] =>
msg: finish always
ok: [host_3] =>
msg: finish always
PLAY [test] ********************************************************************************************************************************************************************************************************************
TASK [ansible.builtin.debug] ***************************************************************************************************************************************************************************************************
task path: 1.yml:47
ok: [host_1] =>
msg:
- host_1
- host_2
- host_3
ok: [host_2] =>
msg:
- host_1
- host_2
- host_3
ok: [host_3] =>
msg:
- host_1
- host_2
- host_3
PLAY RECAP *********************************************************************************************************************************************************************************************************************
host_1 : ok=4 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
host_2 : ok=4 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
host_3 : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=1 ignored=0
The expected result can be achieved by adding the following task on rescue:
meta: clear_host_errors
However, it seems that the playbook should either completely fail or replay all subsequent hosts.
Actual Results
PLAY [Get ping response] *******************************************************************************************************************************************************************************************************
TASK [debug] *******************************************************************************************************************************************************************************************************************
task path: 1.yml:8
ok: [host_1] =>
msg: start
ok: [host_2] =>
msg: start
ok: [host_3] =>
msg: start
TASK [ansible.builtin.debug] ***************************************************************************************************************************************************************************************************
task path: 1.yml:12
fatal: [host_3]: FAILED! =>
msg: |-
The task includes an option with an undefined variable.. 'test_msg' is undefined
The error appears to be in '1.yml': line 12, column 11, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
- ansible.builtin.debug: msg="{{ test_msg }}"
^ here
We could be wrong, but this one looks like it might be an issue with
missing quotes. Always quote template expression brackets when they
start a value. For instance:
with_items:
- {{ foo }}
Should be written as:
with_items:
- "{{ foo }}"
TASK [ansible.builtin.debug] ***************************************************************************************************************************************************************************************************
task path: 1.yml:33
ok: [host_1] =>
msg: false
ok: [host_2] =>
msg: false
ok: [host_3] =>
msg:
failed: true
msg: |-
The task includes an option with an undefined variable.. 'test_msg' is undefined
The error appears to be in '1.yml': line 12, column 11, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
- ansible.builtin.debug: msg="{{ test_msg }}"
^ here
We could be wrong, but this one looks like it might be an issue with
missing quotes. Always quote template expression brackets when they
start a value. For instance:
with_items:
- {{ foo }}
Should be written as:
with_items:
- "{{ foo }}"
TASK [debug] *******************************************************************************************************************************************************************************************************************
task path: 1.yml:37
ok: [host_1] =>
msg: finish always
ok: [host_2] =>
msg: finish always
ok: [host_3] =>
msg: finish always
PLAY [test] ********************************************************************************************************************************************************************************************************************
TASK [ansible.builtin.debug] ***************************************************************************************************************************************************************************************************
task path: 1.yml:45
ok: [host_3] =>
msg:
- host_3
PLAY RECAP *********************************************************************************************************************************************************************************************************************
host_1 : ok=3 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
host_2 : ok=3 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
host_3 : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=1 ignored=0
As I understand, this effect appeared after the following PR:
dc38914#diff-0ede8d71618eb5bdee10d0d8c7b802a2415dc130ce819a715afa157db818ca09
Code of Conduct
- I agree to follow the Ansible Code of Conduct