In order to run the dnf module you need to use the system Python for which the Python dnf bindings (python3-dnf) are available. I believe that for AlmaLinux 8 the system Python version is 3.6 which also means that you need to run the version of ansible-core that supports running Python 3.6 on target machines, the last such version is ansible-core2.16, see Releases and maintenance — Ansible Community Documentation.
My ansible-core is 2.18.7 but more invest reveal that the OS were update form CentOS7 to Almalinux8, and the issue could be related to “alternatives” configuration. I’m not confident with the “alternatives” configuration
If I launch my script on a fresh installed workstation on Alamlinux8 the installation pass
That’s sound really strange for me, the OS upgrade could affect the system ?
Martin is correct, you cannot use ansible-core>=2.17 with the yum/dnf modules on EL8 and older OS systems (RHEL/CentOS/Alma/Rocky, etc). The OS upgrade and alternatives configuration have nothing to do with it, and in fact shouldn’t have worked before the CentOS7 → AlmaLinux8 upgrade either.
Yep, you can use command or shell instead if you must use newer Ansible.
However, you can use different versions of Ansible side-by-side using venv. Pipx and Pipenv are both good for this. Or you can use ansible-navigator and use EE’s with specific Ansible versions. If you use AWX/AAP, you can also specify the EE’s to use there as well.
Just want to make sure you know that you have options.
Hey, I ran into this exact problem and ended up building a proper fix rather than a workaround.
The root cause: ansible-core >= 2.17 requires Python 3.10+ on managed hosts (modules use from __future__ import annotations), but python3-dnf on EL8 only exists for Python 3.6/3.9. So there’s no supported Python version that satisfies both constraints at once.
I built carlijoy.compat — an Ansible collection that backports the original ansible.builtin.dnf from ansible-core 2.15 as a self-executing zip that runs under /usr/libexec/platform-python (the EL8 system Python that has python3-dnf). It’s a proper drop-in with full feature parity, not a subprocess reimplementation.
This works as ansible-modules can be all programm that accepts a JSON as stdin and returns a JSON. In this case ansible treats the backport as a standalone program (which it kind of is).
Install via pip/uv (no ansible-galaxy needed):
pip install ansible-el-compat
Or via Galaxy:
ansible-galaxy collection install carlijoy.compat
Then replace ansible.builtin.dnf with carlijoy.compat.dnf in your playbooks — the interface is identical.