Ansible with ansible_python_interpreter on Ubuntu targets: /bin/sh: 1: /usr/bin/env python3: not found
After upgrading to Ansible in recent weeks, the playbook to upgrade my Linux VMs stopped working with a cryptic error message, /bin/sh: 1: /usr/bin/env python3: not found
ansible-playbook -i inventory.ini upgrade_linux_vms.yml ─╯
PLAY [all] ********************************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************************
fatal: [dnsmichi.at]: FAILED! => {"ansible_facts": {}, "changed": false, "failed_modules": {"ansible.legacy.setup": {"failed": true, "module_stderr": "Shared connection to dnsmichi.at closed.\r\n", "module_stdout": "/bin/sh: 1: /usr/bin/env python3: not found\r\n", "msg": "The module failed to execute correctly, you probably need to set the interpreter.\nSee stdout/stderr for the exact error", "rc": 127}}, "msg": "The following modules failed to execute: ansible.legacy.setup\n"}
I did not find the time to investigate, and just SSH'd into the 2 VMs and ran apt update && apt upgrade
manually. If you know me, I will try to find a solution when it gets annoying.
Context
The Python interpreter on Ubuntu/Debian is called python3
Ansible uses automated discovery methods that sometimes throw warnings or errors for Python paths on Ubuntu. Therefore I followed the Ansible docs and explicitly set the ansible_python_interpreter
variable to /usr/bin/env python3
in my inventory ini file. The env
binary will automatically detect the current binary in the PATH
environment variable – this could be the system-provided /usr/bin/python3
path, or a custom Python setup in /usr/local
or similar.
Root cause analysis
While upgrading to macOS Sequoia today, I took the time to upgrade Homebrew and additionally went through Linux maintenance steps again. Searching for the error message brought up an Ansible issue saying "ansible_python_interpreter="/usr/bin/env python3" doesn't work anymore"
My Ansible configuration includes the all:vars
section setting ansible_python_interpreter='/usr/bin/env python3'
It most likely does not like the 2 commands in a single string separated by whitespace and instead needs a single binary. 🤔
After reading through the issue comments and referenced Git commits, I tried the following resolution paths:
- Remove/comment out the variable. Warning again 😬
- Hardcode to Python binary path
ansible_python_interpreter='/usr/bin/python3'
- worked fine. ✅
Solution
I do not plan to use a different Python interpreter on the Linux VMs, also because all workloads run in Docker containers. My infrastructure only uses Ubuntu and no other Linux distributions. Hardcoding the Python path to /usr/bin/python3
works fine for me, in this commit.
## set up ssh user name and path to python3 ##
[all:vars]
ansible_become=yes
ansible_become_method=sudo
# https://github.com/ansible/ansible/issues/83476
ansible_python_interpreter='/usr/bin/python3'
If your setup uses different Linux distributions and Python paths, specify the ansible_python_interpreter
in the servers:vars
group or server specific vars
section in your inventory ini configuration.
The broken documentation example with /usr/bin/env python3
was reverted in this commit.