Recently, as I've been building more and more servers running Ubuntu 16.04, I've hit the following errors:
PLAY [host] ************************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************
fatal: [1.2.3.4]: UNREACHABLE! => {"changed": false, "msg": "SSH Error: data could not be sent to remote host \"1.2.3.4\". Make sure this host can be reached over ssh", "unreachable": true}
or:
/bin/sh: 1: /usr/bin/python: not found
The former error seems to happen when you're running a playbook on an Ubuntu 16.04 host (with
gather_facts: yes
), while the latter happens if you're using a minimal distribution that doesn't include Python at all. The problem, in both cases, is that Python 2.x is not installed on the server, and there are two different fixes:
- If you already have Python 3 installed on the server (such is the case with Ubuntu 16.04, by default), you can set in your inventory:
ansible_python_interpreter=/usr/bin/python3. This enables Ansible's ( currently experimental as of 2.3 ) Python 3 support, which seems to work well for most Ansible modules. - If you don't have Python installed on the server, you should change the structure of your playbook so it will ensure Python 2 is installed prior to running the rest of the playbook. See the below example, which is lifted from Drupal VM :
---
- hosts: drupalvm
gather_facts: no
pre_tasks:
# See: https://github.com/geerlingguy/drupal-vm/issues/1245
- name: Install Python if it's not available.
raw: test -e /usr/bin/python || (apt -y update && apt install -y python-minimal)
register: output
changed_when: output.stdout != ""
- action: setup
tags: ['always']
Note that I set
gather_facts: no
(this prevents Ansible from trying to run Python modules before Python is available)âthen after ensuring Python is present, I run the task
action: setup
(with the
always
tag so it's always run, even if you're just running a subset of tasks later). This is basically a 'poor man's
gather_facts
' that gathers facts in the middle of a playbook.
Using this, you should be able to overcome the problems caused by not having Python 2 available on the server you're controlling. Hopefully Ansible will be 100% compatible with Python 3 soon, and this problem will not require any additional code to make it work!