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:
- Turns off fact checking (as this requires Python installed)
- Sets up a pre_task to run before all others in the Playbook
- Checks to see if
Python2.7
is installed and, only if not present, installs it - 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.