4
votes

I was trying to execute a simple python --version command using Ansible, and it was not working no matter how I tried: via shell module, via command module, via script module, via playbook or ad-hoc.

I'm always getting an error:

unknown option

For example the playbook:

---

- name: testing
  hosts: myhost
  sudo: False

  tasks:
       - name: python version
         shell: python --version

Then I realized that this is due to the fact how Ansible loads the environment in SSH session. Effectively the error was not coming from the Ansible or command parsing, but from Python version 2.4, that somehow gets in the PATH (/usr/local/bin).

Seems like Python 2.4 didn't know the --version flag.

The most interesting part is that when I'm performing SSH to the same host as the same user as Ansible does I'm getting PATH elements in correct order and the first location where Python exists is the right one with Python 3, while the /usr/local/bin is buried deep in the PATH.

But when I have added a which python task into the playbook I saw that Ansible resolves Python from /usr/local/bin and that is the old one (v2.4)

When I execute the ansible myhost -m setup I can see that the ansible_env.PATH variable is way shorter then the PATH I'm getting by logging in directly.

It would be nice to understand the rules of how this is getting set up.

Exactly the same question was asked here:

http://grokbase.com/t/gg/ansible-project/1479n0d0qp/ansible-env-path-how-is-it-set

but there was no definite answer.

1

1 Answers

2
votes
  • To get the version of python executing your modules and the ansible itself you should use the ansible_fact ansible_python_version
  • (my home made recommendation) Use full path when using command module.

so the correct answer for me was: in inventory file set the ansible_python_interpreter=/path/to/correct/python and then it will be able to use the indicated python when logging to the remote and obviously find it in the PATH.

This is not true. - shell: python --version would not use the ansible_python_interpreter. It just executes whatever command you give it by looking up the executable (if it's not an absolute path) in PATH.

E.g. if

  • you've setup your startup files (/etc/profile, /etc/profile.d/*, .*rc etc.) such that python 2.4 is first in PATH and
  • you set ansible_python_interpreter to /path/to/python3 for my_host

then:

- hosts: my_host
  tasks:
    - debug: msg="{{ansible_python_interpreter}}"      # would print /path/to/python3
    - debug: msg="{{ansible_python_version}}"          # would print 3.x
    - shell: python -c 'import sys; print sys.version' # would execute python 2.4
      register: py_version
    - debug: msg="{{py_version}}"                      # would print 2.4

What you should be doing is one of the following:

  • set PATH correctly. (this is not really an option because "how ansible sets PATH" is undefined see Eugene's comment below)
  • use absolute path with command module (or shell for that matter).