Real Ansible dependencies to managed nodes for very old and new linux nodes

Hi,

tl;dr: I have a wide range of versions of managed linux nodes, but suddenly fail to manage new linux versions. Does Ansible support many different versions, or do I need multiple Ansible versions, or appliances with different Ansible versions?

in detail:

I have a question about the general understanding of the possible usage. I have certain (automation and test) systems, mostly debian-inherited linux machines. Reproducible results over years (!) are important in my field. Years ago I had choosen Ansible, because it has almost no dependencies to the managed nodes, and successfully used it without hassle. To be stable, I never installed extra community packages, to save dependencies.

The manual says, Ansible has requirements on the managers node, like core installation and packages, such as specific Python versions, but on the managed node you just need some Python, and even Python 2 is good for most cases.

For regression tests I have to run things on old virtual machines (like “bullseye” - Debian GNU/Linux 11). These I also manage with Ansible. These environments is mostly frozen. To compare now I added a new linux version VM (here, “trixie” - Debian GNU/Linux 13). Unfortunately, Ansible does not work for this new node (ModuleNotFoundError: No module named 'ansible.module_utils.six.moves' - the other old nodes work fine).

Internet search suggests that I could have a version incompatiblity issue, but I don’t understand it. My manager node is unchanged (old) and my managed node should not need an own ansible installation at all. I think the error message comes from the managed node (otherwise it would not explain why the old nodes work and just the new one generates this error). However, on the nodes, there is no ansible and thus especially no ansible.module_utils.six. The internet search found many cases of this error, but mostly when having wrong versions on the manager node, but my manager node works fine for old managed nodes.

Now I’m afraid that Ansible might expect the same (or similar) Python version on manager node and managed node - and this I think would kill my use case. I have a wide range of systems for the regression tests. Normally I would try updating, but I read that newer Ansible versions have newer requirements, so I’m afraid then the new node would work, but not the old nodes anymore. I could need several parallel Ansible manager versions.

In that case, I would need a different setup, for example several Ansible Manager containers sharing the same playbooks. And some management for these containers. Is this the way to go, or am I missing a point?

I found no information in the manual or using Google, so I kindly ask here in the hope to get some pointer or a short overview how I should shape my setup.

For the future, I’d like to manage nodes as old as lets say 10 years.

Any hints, pointers/links, corrections or suggestions appreciated!

Steffen

ps: Information about upgrading the old VMs is not needed, please take this as given; and no, there of couse is no way to reach any of that from the internet, it is a fully isolated virtual environement with a software defined, isolated network, only acessible via security gateways (Citrix + SSH jump hosts).


Some technical details.

Manager node

$ grep PRETTY /etc/os-release
PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
$ ansible --version
ansible 2.10.8
  config file = /home/sdettmer/work/tisc-hub/ansible/ansible.cfg
  configured module search path = ['/home/sdettmer/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.9.2 (default, Feb 28 2021, 17:03:44) [GCC 10.2.1 20210110]

Managed node old and working:

root@h107:~# grep PRETTY /etc/os-release
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
root@h107:~# ansible --version
-bash: ansible: command not found
root@h107:~# python3 --version
Python 3.11.2

Managed node new and not working:

root@h999:~# grep PRETTY /etc/os-release
PRETTY_NAME="Debian GNU/Linux 13 (trixie)"
root@h999:~# ansible --version
-bash: ansible: command not found
root@h999:~# python3 --version
Python 3.13.5

The error seems to be exactly the same for all my receipts, here a simple ping as example:

$ ansible c3-h999 -m ping
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: ModuleNotFoundError: No module named 'ansible.module_utils.six.moves'
c3-h999| FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "module_stderr": "Shared connection to 10.x.x.x closed.\r\n",
    "module_stdout": "Traceback (most recent call last):\r\n  File \u001b[35m\"/root/.ansible/tmp/ansible-tmp-1770662804.1542516-281584-215623321951359/AnsiballZ_ping.py\"\u001b[0m, line \u001b[35m102\u001b[0m, in \u001b[35m<module>\u001b[0m\r\n    \u001b[31m_ansiballz_main\u001b[0m\u001b[1;31m()\u001b[0m\r\n    \u001b[31m~~~~~~~~~~~~~~~\u001b[0m\u001b[1;31m^^\u001b[0m\r\n  File \u001b[35m\"/root/.ansible/tmp/ansible-tmp-1770662804.1542516-281584-215623321951359/AnsiballZ_ping.py\"\u001b[0m, line \u001b[35m94\u001b[0m, in \u001b[35m_ansiballz_main\u001b[0m\r\n    \u001b[31minvoke_module\u001b[0m\u001b[1;31m(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\u001b[0m\r\n    \u001b[31m~~~~~~~~~~~~~\u001b[0m\u001b[1;31m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m\r\n  File \u001b[35m\"/root/.ansible/tmp/ansible-tmp-1770662804.1542516-281584-215623321951359/AnsiballZ_ping.py\"\u001b[0m, line \u001b[35m37\u001b[0m, in \u001b[35minvoke_module\u001b[0m\r\n    from ansible.module_utils import basic\r\n  File \u001b[35m\"/tmp/ansible_ping_payload_tyhjlkx9/ansible_ping_payload.zip/ansible/module_utils/basic.py\"\u001b[0m, line \u001b[35m176\u001b[0m, in \u001b[35m<module>\u001b[0m\r\n\u001b[1;35mModuleNotFoundError\u001b[0m: \u001b[35mNo module named 'ansible.module_utils.six.moves'\u001b[0m\r\n",
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
    "rc": 1
}

and the interesting part from -vvv:

The full traceback is:
Traceback (most recent call last):
  File "/root/.ansible/tmp/ansible-tmp-1770662937.6844063-281623-102993577514679/AnsiballZ_ping.py", line 102, in <module>
    _ansiballz_main()
    ~~~~~~~~~~~~~~~^^
  File "/root/.ansible/tmp/ansible-tmp-1770662937.6844063-281623-102993577514679/AnsiballZ_ping.py", line 94, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
    ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/.ansible/tmp/ansible-tmp-1770662937.6844063-281623-102993577514679/AnsiballZ_ping.py", line 37, in invoke_module
    from ansible.module_utils import basic
  File "/tmp/ansible_ping_payload_f8mucvl_/ansible_ping_payload.zip/ansible/module_utils/basic.py", line 176, in <module>
ModuleNotFoundError: No module named 'ansible.module_utils.six.moves'

The same is working agains the other nodes:

$ ansible c3-h107 -m ping
c3-h107 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}

The ansible-core support matrix might help?

For your Trixie servers you need to specify the path to Python3, I add this to the YAML inventory, but there are other ways of doing this:

all:
  vars:
    ansible_python_interpreter: /usr/bin/python3
1 Like

Hi,
thank you for your quick reply!

The ansible-core support matrix might help?

Do you think "Target Python " means requirements to the managed node? That would be bad for me.

That would be only “Python 3.9 - 3.14” for the most recent ansible, this would not even cover up LTS distributions (and in enterprise environment, sometimes we would be glad to even have active supported linuxes) and cannot be the case I think? Do you know why it should need a recent python on the managed node, isn’t Python backward-compatible? I think this is why they installed as python2 and pyhton3m as this broke scripts. Does Debian support installing several Python3 versions at the same time?

I use old hosts style inventory and added

[all:vars]
ansible_python_interpreter=/usr/bin/python3

but it has no visible effect, the error keeps the same.

Yes I believe so.

Does setting ansible_python_interpreter on the command line work?

ansible-playbook sample-playbook.yml -e 'ansible_python_interpreter=/usr/bin/python3'

As suggested here:

Also:

The default interpreter path may also be set in ansible.cfg.

So try creating or editing ansible.cfg in the project root to include:

[defaults]
ansible_python_interpreter = /usr/bin/python3

Does setting ansible_python_interpreter on the command line work?

I can set this, for example to an older version installed via pyenv, and I did so in my inventory, but it does not work entirely correctly: at least, python3-apt is not available and cannot be installed.

If only apt (and dnf) are concerned, I think I rewrite this using command: apt -y install ....