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 - Learn root cause analysis and how to fix the problem

Terminal on macOS, ansible-playbook run to upgrade Linux VMs, red error message

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:

  1. Remove/comment out the variable. Warning again 😬
  1. 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.