Ansible connection failure with Ubuntu Server 16.04

Having trouble connecting to Ubuntu Server 16.04 from your Ansible control machine? If you ping your Ubuntu Server do you get a similar error:

ubuntu_host | FAILED! => {
    "changed": false, 
    "failed": true, 
    "module_stderr": "Shared connection to 138.68.174.106 closed.\r\n", 
    "module_stdout": "/bin/sh: 1: /usr/bin/python: not found\r\n", 
    "msg": "MODULE FAILURE", 
    "rc": 0
}

If you do, there's a simple solution (and you should have read the docs! :-D )

Ansible Python not found on Ubuntu Server 16.04

It's all about Python. By default, Ansible uses Python 2.7 (yes, even the current version of Ansible 2.4 does) despite moves to migrate to Python3.

As such, your target system needs to have Python 2.7 installed in order for Ansible to control it. Unfortunately, Ubuntu Server 16.04 doesn't come with Python 2.7 installed by default but there is a quick fix...

Install Python 2.7 on Ubuntu Server 16.04

The fix is as simple as installing a couple things - python-minimal and python-simplejson. You can do this manually the same way you'd install a package normally:

sudo apt install python-minimal python-simplejson

A note on why you need to install python-minimal on ubuntu Server 16.04

When you install python-minimal the following packages are installed:

libpython-stdlib 
libpython2.7-minimal 
libpython2.7-stdlib 
python
python-minimal 
python2.7 
python2.7-minimal

You need these extra packages in order for Ansible to work correctly, simply installing Python2.7 is not enough.

Make Ansible install Python 2.7

If you want to get Python 2.7 installed as part of a playbook when provisioning a server, it can seem a bit like chicken and the egg - you need on to do the other. But you can make use of the 'RAW' module to have Ansible install the needed version for you.

ansible ubuntu_host --sudo -m raw -a "apt install -y python-minimal python-simplejson" 

Obviously this is a manual operation, unless you add this to your Playbook, but we can do better!

Ansible automatically installing Python 2.7 on Ubuntu Server 16.04

Thanks to this page you can also use a more advanced setup that will do this as part of setting up the server by simply adding this to the top of your Playbook.yml file:

gather_facts: False
  pre_tasks:
    - name: Install python for Ansible
      raw: test -e /usr/bin/python || (apt -y update && apt install -y python-minimal)
      register: output
      changed_when: output.stdout != ""
  - setup: # aka gather_facts

The above code does the following:

  1. Turns off fact checking (as this requires Python installed)
  2. Sets up a pre_task to run before all others in the Playbook
  3. Checks to see if Python2.7 is installed and, only if not present, installs it
  4. Registers an output only if installation is needed and prints this to the terminal output.

Use Python 3 with Ansible 2.2 and above

If you're using Ansible >2.2.0, you can set the ansible_python_interpreter configuration option to /usr/bin/python3:

ansible ubuntu_host -m ping -e 'ansible_python_interpreter=/usr/bin/python3'

This tells Ansible to use Python 3 when connecting, and as Python3 is already installed on Ubuntu Server 16.04 you won't need to install anything.

Alternatively you can put this in your inventory (hosts) file:

[ubuntu_hosts]
<xxx.xxx.xxx.xxx>

[ubuntu_hosts:vars]
ansible_python_interpreter=/usr/bin/python3

If you want to make every single host use Python3, just set a variable for [all].

[all:vars]
ansible_python_interpreter=/usr/bin/python3

More info on this second method can be found in the Ansible Python3 docs.

Spotted something wrong with this content? Tell me!

Get in touch on Twitter, GitLab or by email.