Molecule : use a different ansible-core version for internal molecule playbooks and playbooks/roles tested with molecule

Hello Community,

I was hopping to be able to choose the ansible version used for my test since it is often to have older anbsible-core version used in production environment than the one used internally by molecule.
As an alternative, I tried to see if there was an option to define the ansible-playbook binary path to a virtualenv containing the ansible-playbook version targeted without success.

Is there anyway to achieve what I’m looking for ?
If no, is there any plan to add this possibility to molecule ? I assume it will be really nice

Best regards,

I use uv for that

uv run --with-requirements requirements.txt <molecule command>

requirements.txt file is simple python requirements file, where you can pin your versions

ansible-core==2.21.0
molecule==<molecule-version>

versions have to be compartible of course.

uv is a great tool and there are many more options to uv run command

usual PATH env var rules apply there.

The missing note is that you manage running molecule against multiple Ansible versions outside molecule, not inside of it.

In other words you make some scripting outside molecule to run molecule in different Ansible venvs. You can possibly even run all the scenarios for different Ansible versions in parallel.

There is no much sense in supporting something like this in molecule itself because molecule also depends on some venv.

that’s not what I’m looking for, having tox + pyenv is indeed easy to run different ansible + molecule version.

What I’m looking for is a way to run my tests against different ansible version with the exact same molecule version.

it is a long time since I dig into molecule source code but from what I remembered, ansible was called as a system command and not by using it as a module, so IMO ansible is executed outside of molecule not inside of it.

Not exactly, what I was looking for is a way to use an alternate ansible binary (who live in a dedicated venv) for some sequences : converge and idempotence

Don’t remember it was used by molecule itself when running it and don’t get the reason for its use, will try to dig in source code to understand its use

And easy path is not what you are looking for? Or am I misunderstood you?

You can’t run molecule scenario with different ansible version without changing the molecule version too.
But molecule configuration is updated with new options/breaking change over its evolution.

Having molecule use an embedded ansible as a module for its internal use (create instances, install dependenciesn destroy, ..) while using the ansible-* available on the system/venv activated for converge/idempotence should solve this use case

This is not quite true, same can be done with tox.

bash-5.2$ uv run --with-requirements req1.txt molecule --version
Installed 26 packages in 51ms
molecule 26.8.0 using python 3.14 
    ansible:2.20.0
    default:26.8.0 from molecule

bash-5.2$ uv run --with-requirements req2.txt molecule --version
Installed 26 packages in 44ms
molecule 26.8.0 using python 3.14 
    ansible:2.21.0
    default:26.8.0 from molecule

req1.txt

molecule==26.8.0
ansible-core==2.20.0

req2.txt

molecule==26.8.0
ansible-core==2.21.0

A bold claim but not true. Beside already mentioned uv and tox, it can also be done manually like in my case:

$ . .ansible_venvs/ansible-13/bin/activate
(ansible-13) $ molecule --version
molecule 25.12.0 using python 3.12
    ansible:2.20.1
    default:25.12.0 from molecule
$ deactivate
$ . .ansible_venvs/ansible-9/bin/activate
(ansible-9) $ molecule --version
molecule 25.12.0 using python 3.12
    ansible:2.16.15
    default:25.12.0 from molecule

You have plenty of options.

It is not surprising that automated testing of multiple versions is done by some mechanism outside molecule like GitHub Actions and it’s matrix feature.

Note that molecule both imports ansible-core’s Python module ansible (through ansbile_compat) and runs ansible-core executables through subprocess. So while you can modify $PATH so that molecule installed with ansible-core X runs with ansible-core Y, that’s not a good idea since then it will import the wrong ansible module.

So it’s best to have multiple venvs, each with both molecule and ansible-core installed in it.

One problem though is that any molecule version only support two ansible-core versions, since according to the README:

Molecule supports only the latest two major versions of Ansible (N/N-1).

(GitHub - ansible/molecule: An ansible-native testing framework for collections, playbooks, and roles with configurable workflows for testing any system or service · GitHub). So while technically the limits are more relaxed (molecule/pyproject.toml at main · ansible/molecule · GitHub), you won’t have much choice on which ansible-core version to use with a specific molecule version.

I did not have any issue running old ansible-core versions with molecule 26.8.0. I just had to use the right python version


bash-5.2$ uv run --python 3.13 --with-requirements req3.txt molecule --version
Installed 26 packages in 61ms
molecule 26.8.0 using python 3.13 
    ansible:2.19.0
    default:26.8.0 from molecule
bash-5.2$ uv run --python 3.13 --with-requirements req4.txt molecule --version
molecule 26.8.0 using python 3.13 
    ansible:2.19.0
    default:26.8.0 from molecule
bash-5.2$ uv run --python 3.13 --with-requirements req4.txt molecule --version
Installed 26 packages in 27ms
molecule 26.8.0 using python 3.13 
    ansible:2.18.0
    default:26.8.0 from molecule
bash-5.2$ uv run --python 3.13 --with-requirements req5.txt molecule --version
  × No solution found when resolving `--with` dependencies:
  ╰─▶ Because molecule==26.8.0 depends on one of:
          ansible-core>=2.15.0,<2.17.dev0
          ansible-core>=2.18.dev0
      and you require molecule==26.8.0, we can conclude that you require one of:
          ansible-core>=2.15.0,<2.17.dev0
          ansible-core>=2.18.dev0

      And because you require ansible-core==2.17.0, we can conclude that your requirements are unsatisfiable.
bash-5.2$ uv run --python 3.13 --with-requirements req5.txt molecule --version
Installed 26 packages in 41ms
molecule 26.8.0 using python 3.13 
    ansible:2.16.0
    default:26.8.0 from molecule

Not sure why molecule does not support ansible-core 2.17 specifically.

I hope req*.txt file I’ve used are self evident

I don’t get why it is so hard to understand the use case and why your solution @kks doesn’t respond to it.

With a fixed version of molecule, the ansible version is limited to what is specified in pyproject as stated here

As you see you can’t test your roles/playbooks with ansible 2.17 on molecule 2.26.8.

On RHEL 9, the ansible version is 2.14.18, so you can’t use molecule 2.26.8 to test roles/playbooks who will run under this host.

One way to be able to test roles/playbooks with an ansible version freely will be to be able to choose the subprocess used for specific sequence.

bash-5.2$ uv run --python 3.12 --with-requirements req5.txt molecule --version
Installed 28 packages in 43ms
molecule 24.9.0 using python 3.12 
    ansible:2.14.0
    default:24.9.0 from molecule

What feature are you looking in molecule that is available in 26 version, but not in 24? I would argue that molecule since version 4 (it is 2022) has all one need.

I suppose you do not need to test that, result is a priori failure. That is why version 2.17 is excluded from molecule support.

Likely because ansible-core 2.17 is EOL, while 2.16 isn’t really EOL yet (it’s still Supported by RH in certain situations, though it’s officially EOL upstream) and 2.18+ are still supported (Releases and maintenance — Ansible Core Documentation).