I’m encountering an issue while running Ansible on Rocky Linux 8.10 (Green Obsidian) with Python 3.12 in localhost. I tested different versions of Ansible within a virtual environment, using the same playbook each time. Here are my findings:
Ansible 11.1.0 / Ansible-core 2.18 → KO
Ansible 10.7 / Ansible-core 2.17.7 → KO
Ansible 9.13.0 / Ansible-core 2.16.14 → OK
For both failing cases, I get the following error when running my playbook:
TASK [setup_server : Install required packages on CentOS] *************************************************************************************************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: SyntaxError: future feature annotations is not defined
fatal: [localhost]: FAILED! => changed=false
module_stderr: |-
Traceback (most recent call last):
File "<stdin>", line 12, in <module>
File "<frozen importlib._bootstrap>", line 971, in _find_and_load
File "<frozen importlib._bootstrap>", line 951, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 894, in _find_spec
File "<frozen importlib._bootstrap_external>", line 1157, in find_spec
File "<frozen importlib._bootstrap_external>", line 1131, in _get_spec
File "<frozen importlib._bootstrap_external>", line 1112, in _legacy_get_spec
File "<frozen importlib._bootstrap>", line 441, in spec_from_loader
File "<frozen importlib._bootstrap_external>", line 544, in spec_from_file_location
File "/tmp/ansible_ansible.legacy.dnf_payload_p6gl3c4k/ansible_ansible.legacy.dnf_payload.zip/ansible/module_utils/basic.py", line 5
SyntaxError: future feature annotations is not defined
module_stdout: ''
msg: |-
MODULE FAILURE
See stdout/stderr for the exact error
rc: 1
ansible-core 2.17 and newer do not support the default system python 3.6. I know you mention python3.12, however the dnf module requires the python dnf/rpm/gpgme/etc bindings, which are only packaged for the system python.
We have a feature called “respawn” which will attempt to respawn the module being executed, against known system python versions if the python bindings are missing from the python version specified by ansible_python_interpreter.
As such, in order for the dnf module to potentially work, it has to respawn on an interpreter that supports the python bindings it requires.
We’ve recently improved the method in which the other python interpreters are polled for respawn, to omit python versions that we no longer support. But that only cleans up the messaging on the failure to run the module.
So long story short, ansible-core 2.17+ simply cannot perform package related tasks against RHEL8. There are other modules in other collections that also won’t work as well due to this limitation.
RedHat has lifecycles for its software leaving supportability, Python 3.6’s end of life was in 2021. Not sure what kind of discussion remains to be had.
Don’t know if I’ve ever seen an official RedHat person ever post here, even the open source project maintainers have been scarce since last summer. Might be more productive to open a ticket with RH and get their stance that way
You may want to check this response for more detailed information:
However, the long story short is the response I provided above, with the exception that Red Hat customers get extended critical security support for ansible-core 2.14 and ansible-core 2.16.
I ran into the same wall and built a solution hopefully worth sharing here.
The issue is a genuine incompatibility with no clean official fix: ansible-core >= 2.17 needs Python 3.10+ on the managed host, but python3-dnf on EL8 tops out at Python 3.9. The respawn mechanism that’s supposed to handle this fails because the respawned interpreter (3.6) doesn’t satisfy ansible-core 2.17’s own from __future__ import annotations requirement.
I built carlijoy.compat — a collection that backports the original ansible.builtin.dnf from ansible-core 2.15 as a self-contained executable that runs under /usr/libexec/platform-python (the EL8 system Python with dnf bindings). The module interface is identical to ansible.builtin.dnf.
pip install ansible-el-compat
# or
ansible-galaxy collection install carlijoy.compat
# Before
- ansible.builtin.dnf:
name: httpd
state: present
# After
- carlijoy.compat.dnf:
name: httpd
state: present