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!
Comments
I had the same problem with gathering facts on Ubuntu 16.04. Your post saved me, thanks!
Useful post - thanks for the insight.
Do you know if this problem will persist for future versions of Ubuntu? Or is there a specific Ansible version in which this problem goes away?
Hi Jeff,
I read your ansible and raspberry pi tips with relish. I can't get past on of these issues on CentOS 7. Here's a sample session:
```$ rm ~/.ansible.cfg
$ ansible -e ansible_python_interpreter=/bin/python3 -i 172.24.145.147, -m ping -u ansible all
[WARNING]: sftp transfer mechanism failed on [172.24.145.147]. Use ANSIBLE_DEBUG=1 to see detailed
information
[WARNING]: scp transfer mechanism failed on [172.24.145.147]. Use ANSIBLE_DEBUG=1 to see detailed
information
172.24.145.147 | UNREACHABLE! => {
"changed": false,
"msg": "Data could not be sent to remote host \"172.24.145.147\". Make sure this host can be reached over ssh: ",
"unreachable": true
}
$ ssh [email protected]
Last login: Fri Oct 29 23:32:41 2021 from hadar.vindaloo.com
[ansible@client-13 ~]$ ls -l /bin/python3
lrwxrwxrwx. 1 root root 9 Oct 29 16:18 /bin/python3 -> python3.6
[ansible@client-13 ~]$ /bin/python3
Python 3.6.8 (default, Nov 16 2020, 16:55:22)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> exit()
[ansible@client-13 ~]$ logout
Connection to 172.24.145.147 closed.
$ ansible --version
ansible 2.9.7
config file = None
configured module search path = [u'/home/chris/.ansible/plugins/modules', u'/usr/local/share/py27-ansible/plugins/modules']
ansible python module location = /usr/local/lib/python2.7/site-packages/ansible
executable location = /usr/local/bin/ansible
python version = 2.7.18 (default, Jun 2 2020, 04:52:07) [GCC 4.2.1 Compatible FreeBSD Clang 8.0.0 (tags/RELEASE_800/final 356365)]
$```