Python 3.7+ Impact on EL8 (future for EL9)

Ansible is intended to be used to manage other platforms. Is it smart to remove support for a platform we are very likely going to see for at least the next 8 years? There are recent posts here of individuals running EL6 based platforms yet.

I like that we have the EE capability in ansible-navigator, awx, and automation-controller. I don’t think that mechanism should be the primary way to manage nodes that are otherwise supported in the ecosystem like EL8 today with Python 3.6 maintained by the EL8 team on it’s own lifecycle separate of upstream CPython.

We have Python 3.9 in EL9, this is a continuous cycle. We can expect to see Python 3.13 in October of 2024 and a currently yearly release cycle. The platform-python in EL9 is Python 3.9. The current documented target node support targets would have EL9 out of support by ansible-core by as early as an ansible-core release after October 2026 and latest by the release after October 2027.

I’ve focused on EL8 and EL9 so far; the situation is interesting when looking at Windows. The minimum PowerShell target is 3.0 which maps to Server 2008!

Having ansible-core 2.16 supported by the RHEL package management team in RHEL 8 isn’t a fix for customers running AAP2 on RHEL9 or even OpenShift that happen to have to manage RHEL 8 nodes. Then what happens in 2026 / 2027 with customers running RHEL 9.

I get the desire to want to get off of crufty Python versions as much as the next person. I personally struggled with the Python 2 and 3 changes in and out of Ansible plenty. This just seems to go against what Ansible is used for.

There are other posts that talk about the removal like https://forum.ansible.com/t/ansible-core-devel-drops-support-for-python-3-7/4736 and even a discussion item that I did not notice on GitHub.

This post is meant to focus on is it smart or good to remove support for Python versions on managed nodes that might have their own lifecycle for that product and it’s included Python interpreter?

1 Like

I’ve been thinking of whether I should ask a similar question (since I’m still wondering what to do with Ansible 10.0 release throws SynaxError while gathering fact · Issue #425 · ansible-community/ansible-build-data · GitHub - there is nothing the Ansible community package can do about it, but just closing it also isn’t great).

I’ve been wondering if there is a way to ‘properly’ use ansible-core 2.17 with RHEL 8 targets. Obviously ansible-core 2.17 cannot cope with Python 3.6 anymore, so the default Python version of RHEL 8 won’t work. But if you install a newer Python version (which I understand can be done from the system packages), you still have the problem that the dnf module requires a Python library that’s only available for Python 3.6, I think, and not for newer Python modules on RHEL 8 (but maybe this isn’t correct?) - which would effective disallow you to install software with Ansible. If my assumptions are correct (I don’t use any version of RHEL so I have no way to verify), this basically means that ansible-core 2.17 cannot ‘properly’ manage RHEL 8 targets. And as you pointed out, a few years later we’ll have the same problem with the then latest ansible-core and RHEL 9, and so on.

While thinking on whether I should ask a question, I’ve been wondering whether it would be better if more parts of ansible-core would be moved to actual collections - in fact all modules and plugins that don’t need special access to ansible-core internals. (I would even go so far to argue that most of the module utils should be moved into that collection as well.) This would at least make it easier to use an older ansible-core (that still supports the Python versions you need) without having to lose all interesting features that need ansible-core support. But also this doesn’t really solve the real problem - you “quickly” won’t be able to use the latest ansible-core version with RHEL x.

One could also ask differently, is it smart for RHEL 8 (or 9 or …) to stick to the same (and eventually very old) Python for all system things during their lifetime?

And yes, I know, usually the folks who need to administer them aren’t the ones who decided to stick to some (eventually) ancient RHEL version for a very long time.

I guess that both your question and mine have something in common: there is no good answer to them (in the sense that every answer will make a substantial amount of folks not very happy).

That’s not correct and if it’s in our docs somewhere please let us know so we can correct it. The minimum PowerShell version is now 5.1. We also align ourselves to the normal Windows support cycle so 2016 is our baseline as Server 2012 and 2012 R2 went end of life (excluding Azure) in October last year.

@jborean according to Releases and maintenance — Ansible Core Documentation ansible-core 2.17 supports “PowerShell 3 - 5.1”. Since that’s the main table (including the out-commented entries: ansible-documentation/docs/docsite/rst/reference_appendices/release_and_maintenance.rst at devel · ansible/ansible-documentation · GitHub) used to figure out which ansible-core version supports what, it should really be updated if it’s wrong :slight_smile:

1 Like

I am one of those who have been running ansible to manage RHEL 5 a yew years past its extended support and doing the same with RHEL6 as well. And although I find it lovely that people want to keep support for older versions it is not really necessary. People do not upgrade systems because they do not want to touch them. So even the ansible playbooks rarely get any changes to them. And you generally do not even want to upgrade the ansible version. For RHEL 5 we would load up ansible 2.5 without any issues. You just don’t touch legacy systems unless it is to fix a critical bug or to upgrade the OS.

And for initialising python on target nodes it is common to use the raw module. Unless you make your own images of course as you would then just add the newer python packages to the image from the start.

So we should at least make an effort to have one supported ansible version which support the platform python on major long term support OS, both RHEL and Debian. But the last two, three years of an OS is not as important. And even then it is not that big of a deal if the platform python version is not supported if you can install another supported python version easily. This does become more important as we see both RHEL and Debian move away from platform python.

On the controller side of things it is very different. If you upgrade to the latest version of ansible then we can assume you are also running a fairly new OS. I expect most ansible-core 2.17 to be deployed on RHEL 9 or Debian Bookworm or equivalent. And those who run on older versions do expect to have some problems such as having to install a newer version of python, possibly from EPEL instead of the official sources. So I am willing to drop support for python 3.10 on the control node. Those who still run RHEL 8 control nodes can find a way to install python 3.11 on it or use an older ansible version.

1 Like

@felixfontein thanks for letting me know, I’ve opened Fix up PowerShell and Windows support lifecycle by jborean93 · Pull Request #1587 · ansible/ansible-documentation · GitHub which will hopefully clarify that problem.

2 Likes

@jborean I like the idea of tying support for target nodes to levels that match support levels. As you mentioned the runtime, PowerShell, is maintained as part of that OS’ lifecycle.

As @felixfontein mentioned it’s a quagmire. Should Ansible have to author code compatible with old Python versions or should distributions be pushed to upgrade their runtimes just so modern Ansible can manage them?

I think it is reasonable to assume Ansible can communicate to and manage major Linux platforms during their lifecycle similar to Windows as an end-user. The new quagmire then of course is what is a major Linux platform? The nice thing about x versions of Python back is it’s tied to Python and not any Linux distributions.

I say this with appreciation for the product and all the hard work that goes into it. My comments come from only wanting it to be the best it can be.

how is this problem solved in AAP? :slight_smile: I’m guessing there customers do want to manage RHEL8 at least until the end of it’s “normal” lifecycle 2029.

Over on GitHub the answer was to use Ansible 2.16, which is kind of an ‘LTS’ release, and is what’s installed via DNF on a RHEL 8 host.

While sticking to ansible-core 2.16 works, it’s a problem for users of the Ansible community package. Its version 9 is supported half a year longer than usual (until ~November 2024, same as version 10), but after that there only will be new releases for Ansible community package 11 (and newer). So you won’t get any new collection updates, including no bugfixes and no security fixes (if applicable).

At that point you basically have to install newer versions of collections yourself.

(Also note that ansible-core 2.16 will be End of Life in May 2025: Releases and maintenance — Ansible Core Documentation. As far as I understood RH will still provide fixes for it to keep the system roles in RHEL 8 working, but that’s basically it. For any other problem that doesn’t affect the system roles, there will be no more patches. This is I guess what is meant with “kind of an ‘LTS’ release”.)

We are just finding this as we started testing 2.17 and encountered the errors on all of our RHEL8 boxes. As others said, RHEL 8 is supported for quite some time more, so this certainly causes a conundrum for us.

I guess we have to start managing 2 different EEs and set jobs in the controller to use the specific one needed depending on the targets.

3 Likes

I happened on this thread again after overhearing a couple of different teams mention that they were looking at alternatives to Ansible due to these difficulties. As a Python open source maintainer, I deeply share the desire to get rid of old versions but this feels suboptimal to me.

One of the thoughts I had is that where this has come up in my experience has almost exclusively been the python-dnf dependency where Ansible was otherwise functional using the Python 3.11 installed from Red Hat’s repository for RHEL8. This made me wonder what percentage of problems would be resolved if Red Hat’s Python packaging team could make the dnf bindings available in the newer versions as well, and what the best path for Red Hat customers might be to request that.

I’ve held off on posting, largely because this is super complex problem. One we haven’t felt we’ve had a perfect solution for going on years now. This topic consumes an inordinate amount of engineering time continuously trying meet the needs of users, while simultaneously acknowledging our engineering limitations. Each year, or multiple times a year we think we’ve come to a concensus, and rinse and repeat. Hopefully with what we’ve learned and past things we’ve done, we continue to get better, but alas, onto some more in depth info.

I know at first it probably seems easy to say “we’ll just keep supporting Python 3.6”. As of now our lifecycle intends to cover the 6 latest python versions. In the past, this was achievable, largely due to the release cadence of Python, and the uptake and stability of Python3. We initially decided when adding Python 3 support, that a minimum of Python 3.5 would be required, as older versions lacked in functionality to make it feasible to support both Python2 and Python3 simultaneously.

Starting with Python 3.7 all releases following have moved to a yearly release cadence. Python 3.5 support ended in September 2020, with 3.6 support ending in December 2021. We do often run into Python bugs, and lets say we run into a bug in an old version, we have a few choices: 1) Ignore it, 2) Implement a work around, 3) Submit and maintain a patch for RHEL python releases. This adds to the engineering maintenance burden as well.

On the flip side of supporting old things, we also have to support new things. We’ve worked out our upstream releases in a way that we can deliver support for the latest Python release within about 4 weeks of the Python release. This also allows Fedora to pull in the new Python version, and have a version of ansible-core that supports this.

With some of that information set aside for now, lets look at the RHEL8 lifecycle. First, we’ve never officially supported any RHEL version into its ELS, so we’ll take May 2029 as the EOL of RHEL8. By May 2029 there will theoretically be 12 Python versions to support if we start with Python 3.6, and a possible Python 3.17 releasing around October 2028.

Even with maintaining the 6 (or 7 depending on the release) latest Python versions we’ve already seen situations where functionality was deprecated, replaced, removed and then the replaced functioality has become deprecated, and replaced with new functionality. We honestly didn’t see that much turnover attempting to support Python 2 and Python 3 at the same time. It was largely 2 branches. We’re now talking about the potential of 3 or more branches, exceeding the complexity of Py2 and Py3. And while some argument could be made about skipping certain Python versions, I think ultimately we’d be in just the same situation not including support for some arbitrary Python, and probably make our matrix of supportability that much more complicated, and likely not reduce engineering effort.

Somewhere along the line, either here, or in other discussions, I probably mentioned that some version of ansible-core would remain available on these platforms for managing these platforms. Initially this was only slated for ansible-core packaged within RHEL itself, but has since been extended to AAP. Although to be clear, the support provided for this is a bit more limited than a normal upstream release, as the support only applies to critical security vulnerabilities. So bugs, features, and such wouldn’t be something that would be addressed.

For RHEL8, due to the timing of when we made the decision, ansible-core 2.16 is that version, and this selection is the outlier (and yes once you read the next sentence you may question your sanity, but relax, it’s not you who has lost it, it’s definitely me). For RHEL9, this is ansible-core 2.14, since the default Python in RHEL9 is Python 3.9, and Py3.9 was supported by an actively supported core version at the time of the decision. RHEL10 will have ansible-core 2.16 iirc.

In AAP this will require some amount of work by the users of AAP to select an appropriate EE (execution environment) and limit the inventory as needed.

I should also clarify, as I may have made statements that were sort of incorrect or misleading, in that we don’t really drop support for OSes. We drop support for Python versions. It just so happens, that as we drop support for older Python versions, the newer Python versions made available in OSes often don’t offer Python dependencies, specifically around system bindings. While python3-dnf comes to the top of the list quickly, it should be noted to support that, it requires bindings for rpm, libdnf, dnf, libcomps, and gpgme.

We recently ran through an activity to determine across all Red Hat supported collections, what python modules or python bindings would be required. This totalled up to 41 packages, about half of which are not actually python packages, but other applications that produce python bindings. I make this distinction here to indicate the added complexity of building the bindings over that of a standard python module. All in all, the agreement was that it wasn’t feasible to do the full scope of work, as it came to total of something like 1.5 years of engineering work. Could it be done to a smaller subet? Possibly, and while I think the 5 needed for dnf to function could solve some problems, for any level of playbook complexity, I think users may just find themselves stuck at one of those other missing deps.

Maybe someone will search my github repos, finding a completely unsupported repo with dnf in the name that does some things.

Anyway, I probably forgot something, and you may have questions I didn’t answer. Nevertheless, this topic is endlessly complicated. Is this why I love bourbon? Who can honestly say?

2 Likes

While I wouldn’t say our team is looking at Alternatives to Ansible over the dropping of Python 3.6 support, it certainly has put a damper on things.

We intentionally choose to use RHEL for the long life of support, and have a large number of RHEL 8 in our environment. Now with 2.17 effectively dropping support for it, we have a conundrum of not being able to upgrade Ansible, and as a result, not being able to upgrade several collections that are now starting to only support 2.17 in later versions.

This causes a split in our repo organization and EE strategy, as we can’t be on the latest Ansible and the latest community.vmware collection and still have interoperability with our RHEL 8 boxes. We keep our collections in our repo with ansible.cfg pointing to the repo, but that won’t work if we split into 2 EEs, one for current version and one that is stuck on 2.16 with an unsupported Ansible so we can keep using it with our supported RHEL 8 environments.

I’m not a Linux guy primarily, but over the last 3 years have used Ansible for a ton of VMware, Cisco UCS, Dell server, and more, and gotten more familiar with Linux along the way. Now it kinda feels like the rug is being pulled out from under us, as our keeping up with Ansible versions and collections is going to halt, until most of our RHEL 8 is no longer in play, which is quite a ways out.