A playbook I'm using is failing mysteriously on a client's legacy Debian 5 box. The playbook itself and my Ansible configuration are solid, and I've been running them successfully against a variety of old and new hosts, ranging from CentOS 6 and 7.x boxes to Debian 10, but this one machine is giving me trouble, and I can't figure out why.
Here's a failing minimal example playbook:
- hosts: deb5
gather_facts: no
tasks:
- name: random test task
shell:
cmd: "sed -e 's/netmask/netflask/' /etc/network/interfaces"
register: test_out
failed_when: no
- debug: var=test_out
Here's the corresponding inventory:
# my ansible.cfg has 'interpreter_python = /usr/bin/python3' but I override it for
# the rare older machines without Python 3, like this one.
deb5 ansible_host=xxx.xxx.xxx.xxx ansible_python_interpreter=/usr/bin/python
And finally the ansible.cfg:
[defaults]
remote_user = some_user
interpreter_python = /usr/bin/python3
[privilege_escalation]
become = True
become_ask_pass = True
become_flags = -i
The playbook is run with no other parameters than -i inventory
and the playbook name. Here's the output of the debug task, showing the captured output of the failing shell
sed
task:
ok: [deb5] => {
"test_out": {
"changed": false,
"failed": false,
"failed_when_result": false,
"module_stderr": "Shared connection to xxx.xxx.xxx.xxx closed.\r\n",
"module_stdout": "/bin/sh: /bin/sh: cannot execute binary file\r\n",
"msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
"rc": 126
}
}
The sed
task that gets run is not at fault here, and could be any other one as far as I've seen (I also tried command
instead of shell
, and running awk
rather than sed
). This is further evidenced by the fact that if I take out gather_facts: no
, the playbook fails in the fact gathering phase already, never making it to the task:
TASK [Gathering Facts]
fatal: [deb5]: FAILED! => {"ansible_facts": {}, "changed": false, "failed_modules": {"ansible.legacy.setup": {"failed": true, "module_stderr": "Shared connection to xxx.xxx.xxx.xxx closed.\r\n", "module_stdout": "/bin/sh: /bin/sh: cannot execute binary file\r\n", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 126}}, "msg": "The following modules failed to execute: ansible.legacy.setup\n"}
Based on googling, "cannot execute binary file" often indicates an architecture mismatch, but I don't see how this would apply here. When I SSH to the server and run any of the commands involved (/bin/sh
, /usr/bin/python
, sed
), they all work fine. My macOS Ansible controller is x86_64, as is the Debian 5 box, according to uname -m
.
One notable thing about the Debian 5 box is that its Python is very old, version 2.5.2. Ansible only supports Pythons from 2.6 up on target machines at the moment, I think. However, this is likely not the culprit here, since even the raw
module (which operates without Python, and can be used to install Python on hosts without it) fails:
# Debian 5
- hosts: deb5
gather_facts: no
tasks:
- name: random test task
raw: "sed -e 's/netmask/netflask/' /etc/network/interfaces"
register: test_out
failed_when: no
- debug: var=test_out
The output in that case:
ok: [deb5] => {
"test_out": {
"changed": true,
"failed": false,
"failed_when_result": false,
"msg": "non-zero return code",
"rc": 126,
"stderr": "Shared connection to xxx.xxx.xxx.xxx closed.\r\n",
"stderr_lines": [
"Shared connection to xxx.xxx.xxx.xxx closed."
],
"stdout": "/bin/sh: /bin/sh: cannot execute binary file\r\n",
"stdout_lines": [
"/bin/sh: /bin/sh: cannot execute binary file"
]
}
}
I don't know enough about Ansible internals or its operating principles to come up with any other tests I could do, so I hope someone here has some further ideas.
/bin/sh
actually executable on the target host?sed
,python
, etc.) all work fine when executed in a terminal session in the middle there.