How to instruct Ansible to use specific version of Python
Instruct Ansible to use a specific version of Python interpreter on the remote host.
Remote host#
$ lsb_release -a No LSB modules are available. Distributor ID: Debian Description: Debian GNU/Linux 10 (buster) Release: 10 Codename: buster
Python interpreters on the remote system.
$ ls -l /usr/bin/python* lrwxrwxrwx 1 root root 7 Mar 4 2019 /usr/bin/python -> python2 lrwxrwxrwx 1 root root 9 Mar 4 2019 /usr/bin/python2 -> python2.7 -rwxr-xr-x 1 root root 3689352 Oct 10 22:02 /usr/bin/python2.7 lrwxrwxrwx 1 root root 33 Oct 10 22:02 /usr/bin/python2.7-config -> x86_64-linux-gnu-python2.7-config lrwxrwxrwx 1 root root 16 Mar 4 2019 /usr/bin/python2-config -> python2.7-config lrwxrwxrwx 1 root root 9 Mar 26 2019 /usr/bin/python3 -> python3.7 -rwxr-xr-x 2 root root 4877888 Apr 3 2019 /usr/bin/python3.7 -rwxr-xr-x 2 root root 4877888 Apr 3 2019 /usr/bin/python3.7m lrwxrwxrwx 1 root root 10 Mar 26 2019 /usr/bin/python3m -> python3.7m lrwxrwxrwx 1 root root 14 Mar 4 2019 /usr/bin/python-config -> python2-config
Ansible playbook and inventory.#
Sample python_interpreter_test_inventory.yml Ansible inventory file.
--- python_interpreter_test_default: hosts: debian10_python_default: ansible_host: 192.168.50.221 python_interpreter_test_defined: vars: ansible_python_interpreter: /usr/bin/python3 hosts: debian10_python_group_defined: ansible_host: 192.168.50.221 debian10_python_defined: ansible_host: 192.168.50.221 ansible_python_interpreter: /usr/bin/python2 debian10_python_auto: ansible_host: 192.168.50.221 ansible_python_interpreter: auto debian10_python_auto_legacy: ansible_host: 192.168.50.221 ansible_python_interpreter: auto_legacy
Sample python_interpreter_test_playbook.yml Ansible playbook file.
--- - hosts: python_interpreter_test_default, python_interpreter_test_defined gather_facts: yes serial: 1 tasks: - debug: var=ansible_python_interpreter - debug: var=ansible_python_version
Define and check Python interpreter#
I am using Ansible 2.9.2 with a modification applied to INTERPRETER_PYTHON_DISTRO_MAP map (to support Debian 10) in lib/ansible/config/base.yml file from Default to python3 on Debian 10 #63097 merge request. This change will go live in Ansible 2.10.
INTERPRETER_PYTHON: name: Python interpreter path (or automatic discovery behavior) used for module execution default: auto_legacy env: [] ini: - vars: - version_added: "2.8" description: - Path to the Python interpreter to be used for module execution on remote targets, or an automatic discovery mode. Supported discovery modes are ``auto``, ``auto_silent``, and ``auto_legacy`` (the default). All discovery modes employ a lookup table to use the included system Python (on distributions known to include one), falling back to a fixed ordered list of well-known Python interpreter locations if a platform-specific default is not available. The fallback behavior will issue a warning that the interpreter should be set explicitly (since interpreters installed later may change which one is used). This warning behavior can be disabled by setting ``auto_silent``. The default value of ``auto_legacy`` provides all the same behavior, but for backwards-compatibility with older Ansible releases that always defaulted to ``/usr/bin/python``, will use that interpreter if present (and issue a warning that the default behavior will change to that of ``auto`` in a future Ansible release. INTERPRETER_PYTHON_DISTRO_MAP: name: Mapping of known included platform pythons for various Linux distros default: centos: &rhelish '6': /usr/bin/python '8': /usr/libexec/platform-python debian: '10': /usr/bin/python3 fedora: '23': /usr/bin/python3 redhat: *rhelish rhel: *rhelish ubuntu: '14': /usr/bin/python '16': /usr/bin/python3 version_added: "2.8" # FUTURE: add inventory override once we're sure it can't be abused by a rogue target # FUTURE: add a platform layer to the map so we could use for, eg, freebsd/macos/etc? INTERPRETER_PYTHON_FALLBACK: name: Ordered list of Python interpreters to check for in discovery default: - /usr/bin/python - python3.7 - python3.6 - python3.5 - python2.7 - python2.6 - /usr/libexec/platform-python - /usr/bin/python3 - python # FUTURE: add inventory override once we're sure it can't be abused by a rogue target version_added: "2.8"
Since Ansible 2.8, the default value ansible_python_interpreter is auto_legacy , which means that it will prefer /usr/bin/python (if it exists) over the discovered Python version. You can set it to auto , which will be default in the future, so it will work oppositely.
To suppress the deprecation and fallback warning use auto_legacy_silent or auto_silent values.
Alternatively, set it to the path of a specific Python interpreter.
To illustrate this, use the Ansible playbook that was described earlier.
$ ansible-playbook -i python_interpreter_test_inventory.yml python_interpreter_test_playbook.yml
PLAY [python_interpreter_test_default, python_interpreter_test_defined] *********************************************************************************************************** TASK [Gathering Facts] ************************************************************************************************************************************************************ ok: [debian10_python_default] TASK [debug] ********************************************************************************************************************************************************************** ok: [debian10_python_default] => < "ansible_python_interpreter": "VARIABLE IS NOT DEFINED!" > TASK [debug] ********************************************************************************************************************************************************************** ok: [debian10_python_default] => < "ansible_python_version": "2.7.16" > PLAY [python_interpreter_test_default, python_interpreter_test_defined] *********************************************************************************************************** TASK [Gathering Facts] ************************************************************************************************************************************************************ ok: [debian10_python_defined] TASK [debug] ********************************************************************************************************************************************************************** ok: [debian10_python_defined] => < "ansible_python_interpreter": "/usr/bin/python2" > TASK [debug] ********************************************************************************************************************************************************************** ok: [debian10_python_defined] => < "ansible_python_version": "2.7.16" > PLAY [python_interpreter_test_default, python_interpreter_test_defined] *********************************************************************************************************** TASK [Gathering Facts] ************************************************************************************************************************************************************ ok: [debian10_python_auto] TASK [debug] ********************************************************************************************************************************************************************** ok: [debian10_python_auto] => < "ansible_python_interpreter": "auto" > TASK [debug] ********************************************************************************************************************************************************************** ok: [debian10_python_auto] => < "ansible_python_version": "3.7.3" > PLAY [python_interpreter_test_default, python_interpreter_test_defined] *********************************************************************************************************** TASK [Gathering Facts] ************************************************************************************************************************************************************ ok: [debian10_python_auto_legacy] TASK [debug] ********************************************************************************************************************************************************************** ok: [debian10_python_auto_legacy] => < "ansible_python_interpreter": "auto_legacy" > TASK [debug] ********************************************************************************************************************************************************************** ok: [debian10_python_auto_legacy] => < "ansible_python_version": "2.7.16" > PLAY [python_interpreter_test_default, python_interpreter_test_defined] *********************************************************************************************************** TASK [Gathering Facts] ************************************************************************************************************************************************************ ok: [debian10_python_group_defined] TASK [debug] ********************************************************************************************************************************************************************** ok: [debian10_python_group_defined] => < "ansible_python_interpreter": "/usr/bin/python3" > TASK [debug] ********************************************************************************************************************************************************************** ok: [debian10_python_group_defined] => < "ansible_python_version": "3.7.3" > PLAY RECAP ************************************************************************************************************************************************************************ debian10_python_auto : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 debian10_python_auto_legacy : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 debian10_python_default : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 debian10_python_defined : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 debian10_python_group_defined : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Follow me on Mastodon , check out source code ad GitHub