Ansible supported Python version on _target_

Hi there :waving_hand:

When looking at the table of supported versions of Python on the target nodes in Ansible over at Ansible-core | endoflife.date I see a pattern that is slightly concerning to me.

While I really like the fact that Ansible is very much alive and under heavy development, as a sysadmin I see a concerning pattern when looking at the versions of Python required by the clients/targets for the automation.

A while ago, when Ansible 2.17 was released, we also ran into this issue, where the Core team decided to drop Python 3.6. Some of us voiced concerns about dropping a python version for a (big) OS that is still around for another 3,5 years. Also see the discussions here (ansible-core 2.17 removing target support for Python 2.7 and 3.6 Ā· Issue #54 Ā· ansible-collections/news-for-maintainers Ā· GitHub) and here (Discussion: ansible-core 2.17 removing target support for Python 2.7 and 3.6 Ā· ansible-collections/news-for-maintainers Ā· Discussion #55 Ā· GitHub)

At the time, this was inconvenient at best, because there was still a broad support of community based collections and we (in our RHEL8 environment) have been running with Ansible 2.16 quite happily ever since, getting patches via Red Hat etc.

Which brings us to the current state, for some usecases we use community code for which there is no certified alternative, but we also have environments that use non-Red Hat EL8). And the current state of things is much less peachy, as we currently see breakage because the collections follow (mostly) whatever requirements ansible-core ā€˜demands’ on the controller/client. Which is how it’s supposed to be, no argument there.

But, to get back to the point, the pattern I see is that every new release (which comes fast) seems to drop the lowest version of Python on the target compared to the previous version. If this pattern continues it’s not too farfetched to think that by the time Python 3.15 hits the streets, the next release of Ansible will drop EL9. Six (6) years before EL9 is slated for end of maintenance (not even mentioning ELS).

So I have some questions:

  • What is the current plan of the Core team on the supported requirements on the targets?
  • What recourse do we, the sysadmins that have to keep systems running, have in case this does change on the Ansible side? What reasonable expectations can we have that the ā€˜magic glue’ we use to connect ā€œeverything and the kitchen sinkā„¢ā€ will keep supporting the systems we’ll need to run for years to come without resorting to all kinds of hacks that fix compatibility
  • Same goes for the collection maintainers, some of the OS-es (Proxmox, based on Debian for example) don’t move as fast as Python does. What do we do when we have a collection that cannot support the new ansible-core because the target $thing does not work with that version of Python?

I get that using all of the new fancy Python features is cool and it’s nice to keep the spectrum of supported versions to a minimum, but again, my primary job is a sysadmin and I have to use Ansible on whatever systems I encounter. And I am not always in the position to ā€˜demand’ certain OS versions. Or the other way around, Red Hat releases their OS-es with a specific Python version as /usr/libexec/platform-python with the intention for it to be the stable interface for other system modules (be it Ansible or otherwise) that will not change during the lifecycle of the OS.

TL;DR, I fear that Ansible is chasing new Python versions so fast that it might become irrelevant because it cannot target nothing because the target does not run a supported version of Python.

1 Like

I fully agree with you (and it’s one of the reason why I continue to hope for ā€œexecution pluginsā€ - or however they should be named - which allow to support older Python versions without having to drop support for module_utils etc.)

I think dropping support for older Python versions on the controller is perfectly fine. It’s also perfectly fine for many collections that (mostly, or even exclusively) contain modules that are almost always run on the controller. But some things definitely should better keep compatible with old Pythons, especially all the low-level things.

(I’m thinking of whether it would make sense to create a new collection community.core for that, and migrate modules from other collections such as community.general to there. I really don’t want to support old Pythons and ansible-cores for community.general, but for a smaller, more specialized collection that’s perfectly fine IMO. But that still doesn’t solve the ansible-core problem, where a new enough ansible-core version effectively prevents execution of modules and module utils - even if they still support Python 2.6 - on older Python versions like Python 3.6.)

RH’s official answer to all this are execution environments, which are better than nothing, but IMO they are more like a band-aid than a proper solution. (And you really don’t want to split up playbooks into different playbooks that each needs a different EE… :scream:)


There’s one thing in your post I’d like to clarify:

I’m assuming you mean a new ansible-core 2.x.0 release. (And not a new Python 3.y.0 release.)

It’s only every second release: basically once a new Python version is added (which happens once per year), an old Python is dropped. The ansible-core versions 2.15 - 2.18 were kind of outliers: there it looks like one version is dropped every release, i.e. every half a year. But that was mainly to reduce the number of supported Python versions to the current count (3 on controller, 6 on target) without dropping too much at once. (I’m not sure whether that was the official strategy, but it felt very much like that.)

1 Like

Talking about RHEL8, I think that Python 3.6 is the default and supported for the full lifecycle of this major RHEL release. But it looks that there are also newer versions available.

Can’t you just install a newer version the target and it just works? Or wouldn’t this work because the default python version (3.6) is used?

I’m sorry if this is a stupid question, but I’m mostly involved with collections that run on the controller node and talk to some API. Not with ones that run on the target.

1 Like
  1. You cannot use a modern ansible-core to install these older Python versions in a nice way (i.e. without using the raw module).
  2. Certain modules, including the package managing modules, require to be run with the system Python. So you can run a lot of things, but not basic tasks such as installing/removing/upgrading packages.

Especially 2. is the main reason why the situation sucks so much… If the only disadvantage would be that you need to install a newer Python first (somehow), it would be a lot easier.

3 Likes

I have worn many hats and can relate to the challenges of using, packaging and maintaining ansible things :stuck_out_tongue:

I don’t really have any good solution to suggest right now but some thoughts and comments.

Execution environments (as built/meant for awx/aap) lets you pick your version of python, ansible-core, ansible, dependencies and other things but at the end of the day it’s not fundamentally different than using a regular container image or a virtualenv of your preferred python interpreter..

I think dropping support for older Python versions on the controller is perfectly fine.

That’s the controller side and I agree, it’s probably fine. You can install it where you want and you run it however you want. Run it in k8s if you want :sweat_smile:

For the targets, I understand and can totally relate to wanting to reduce the maintenance burden but the reality is that there are a lot of LTS distros (RHEL, Debian, Ubuntu LTS to name a few) that have lifecycles that are supported far beyond the EOL of any python version.

Dropping support for the python version of these distros makes it a bit more difficult to manage a living datacenter. We can have thousands of these, it makes upgrading ansible a bit harder.

For example, CentOS 7, RHEL 7, Debian 10 (Buster) and Ubuntu 16.04 shipped python 2.7 by default.

RHEL 7 supported ended in 2024, Ubuntu 16.04 until (at least) 2026 and Debian 10 is no longer supported since 2024.

python2.7 went EOL on 2020-01-01 but it’s actually kind of supported until 2026, actually ?

I don’t know what to do about this.

It’s ok to expect users to update to modern distributions but reality is we are busy and we do not always have the luxury of keeping thousands of machines upgraded easily :stuck_out_tongue:

I just mean to point out that dropping python versions for distros that are still supported can be a big papercut.

You cannot use a modern ansible-core to install these older Python versions in a nice way (i.e. without using the raw module).

Yes, we can probably jump through hoops to get the right version of a python interpreter installed somehow.

But I think Ansible is supposed to be agentless, simple to use, because you don’t (usually) need to install anything, it’s just ssh, but actually python too, but at whatever the default version of python each distro happened to pick years ago.

Edit: I mixed up RHEL8 and RHEL7 :sob:

1 Like

Thanks for all the replies!

Agreed, because if for whatever reason the controller is not able to run the modules, this is exactly where EE’s come in (and you can also run those with ansible-navigator if you don’t have AWX/AAP :slight_smile:

Yes, exactly, and the EL distro’s (RHEL, Rocky, Alma etc.) are impacted most by these due to the /usr/libexec/platform-python begin static

Yes, I’m guessing that once Ansible 2.22 rolls around they drop Pyton 3.9 (given that Python 3.15 is around by then)

Well, not on all distros, I’m not too sure how this works on Debian (it’s been a while), but for EL the modules that interact with for example Yum/DNF have to use /usr/libexec/platform-python, which means for EL8 3.6.8, EL9 3.9.18. And Ansible’s interpreter discovery plugin will always attempt to run modules with that interpreter as well.

And when trying to run a newer version of Ansible on those targets will either result in an error finding a suitable interpreter, or Python errors because the interpreter is not supported.

Indeed, but that’s the point with EL at least, that’s something they explicitly changed when designing RHEL8 (https://developers.redhat.com/blog/2018/11/14/python-in-rhel-8-3 and Chapter 16. Installing and using dynamic programming languages | Configuring basic system settings | Red Hat Enterprise Linux | 8 | Red Hat Documentation)

Agreed :slight_smile: and I’m fully in favor of EE’s, because it allows one to have a static, immutable, personalize Ansible executioner. And that on it’s own is brilliant, no more juggling dependencies, installing obscure Python packages from outside of PyPI (looking at you VMware) and hoping nothing breaks this time after upgrading your system. Heck, you can even stick it inside a CI job that runs a test playbook to ensure you can still talk to <insert thing here>!

Well this exactly, I already have to keep everything updated, secured and functioning. And we’re trying real hard to keep the pace (we’re already planning RHEL9 upgrades across the board, because RHEL10 has been released, which mean N-1 is now 9 :slight_smile: ), but we can’t keep up if the tools we need to use drop support for the OS-es we need (again, sysadmins don’t always have a choice here).

Well these are the ā€˜all kinds of hacks that fix compatibility’ that I meant in my post :wink:

And frankly, my work is impossible to do in a reasonable amount of time without tools like Ansible, there’s just too many systems, hardening guidelines to apply, patches to install, you name it.

When doing some more searching I ran across this post from @sivel (Python 3.7+ Impact on EL8 (future for EL9) - #13 by sivel) in which he explained the viewpoint from the Core team’s side of things. Which I can fully understand, but I think we’re going in the wrong direction as of now.

And with regards to what we could possibly do to fix this, I think we have a few options/directions in which we can look:

  • Investigate ā€˜LTS’ releases of Ansible, because most of the major distro’s seem to hover around the same versions, this might just work
  • Expand the range of supported Python on the targets only. Controller is fine, because that’s relatively easy to fix with EE’s, vens or some other means (it’s just 1 system/container image after all)

:warning: Possible AI lies incoming: I had Chat whip up a table of current supported versions of Debian, Suse, Ubuntu and RHEL and their supposed default version of Python:

Distro family Specific distro / version Default Python version (system)
EL RHEL 8 (platform-python) 3.6 (Red Hat Developer)
EL RHEL 9 (platform-python) 3.9 (Red Hat Docs)
EL RHEL 10 (platform-python) 3.12 (Red Hat Docs)
Debian Debian 11 (ā€œBullseyeā€) 3.9 (Debian Wiki)
Debian Debian 12 (ā€œBookwormā€) 3.11 (Debian Wiki)
Debian Debian 13 (ā€œTrixieā€) 3.13 (Debian Wiki)
Ubuntu Ubuntu 20.04 LTS (ā€œFocalā€) 3.8 (documentation.ubuntu.com)
Ubuntu Ubuntu 22.04 LTS (ā€œJammyā€) 3.10 (documentation.ubuntu.com)
Ubuntu Ubuntu 24.04 LTS (ā€œNobleā€) 3.12 (documentation.ubuntu.com)
Ubuntu Ubuntu 25.04 (ā€œPluckyā€) 3.13 (documentation.ubuntu.com)
SUSE (SLE) SLES 15 (Base system) 3.6 (SUSE Documentation)
SLES 15 SP4+ (Python 3 module) SLES 15 SP4 / SP5 3.11 (SUSE Documentation)