I recently encountered a frustrating situation where my Ansible playbook successfully uploaded a Python script to remote servers, but failed to execute it - even though the same script runs perfectly when executed manually on the target servers. Here's the exact playbook I used:
- hosts : mygroup
user : user
sudo : yes
tasks :
- name : Copy script
copy : 'src=/home/user/Scripts/logchecker.py dest=/opt/root2/logchecker.py owner=root group=root mode=755'
- name : Execute script
command : '/usr/bin/python /opt/root2/logchecker.py'
After extensive testing, I discovered several potential culprits:
- Environment Path Issues: The Python environment might be different when invoked through Ansible
- Working Directory Problems: The script might depend on relative paths
- Permission Challenges: Even with sudo, some environment variables might not propagate
Here are three working approaches I've validated:
Solution 1: Explicitly Set Working Directory
- name : Execute script
command : '/usr/bin/python /opt/root2/logchecker.py'
args:
chdir: /opt/root2/
Solution 2: Use Absolute Paths Everywhere
- name : Execute script
shell : |
cd /opt/root2/
/usr/bin/python /opt/root2/logchecker.py
Solution 3: Full Environment Control
- name : Execute script
command : '/usr/bin/python /opt/root2/logchecker.py'
environment:
PYTHONPATH: "/opt/root2/"
HOME: "/root"
After testing all approaches, here's my recommended production-ready version:
- hosts : mygroup
become : yes
become_user : root
tasks :
- name : Ensure target directory exists
file:
path: /opt/root2/
state: directory
mode: '0755'
- name : Copy script with proper permissions
copy :
src: /home/user/Scripts/logchecker.py
dest: /opt/root2/logchecker.py
owner: root
group: root
mode: '0755'
- name : Execute script with full environment control
command : /usr/bin/python /opt/root2/logchecker.py
args:
chdir: /opt/root2/
environment:
PYTHONPATH: "/opt/root2/"
HOME: "/root"
This version handles all edge cases I encountered during my testing.
If you're still facing issues, try these debugging steps:
- name : Debug Python environment
command : which python
register : python_path
- name : Show Python path
debug : var=python_path
And to check file permissions:
- name : Verify script permissions
stat :
path: /opt/root2/logchecker.py
register : script_stat
- name : Display permissions
debug : var=script_stat
When working with Ansible playbooks to deploy and execute Python scripts across multiple servers, a common pitfall occurs where file transfer succeeds but script execution fails. Here's a deeper look at the issue:
- hosts: mygroup
user: user
become: yes
tasks:
- name: Copy script
copy:
src: /home/user/Scripts/logchecker.py
dest: /opt/root2/logchecker.py
owner: root
group: root
mode: '0755'
- name: Execute script
command: /usr/bin/python /opt/root2/logchecker.py
The execution failure could stem from several factors:
Environment Path Issues
- name: Execute script (explicit path)
command: /usr/bin/env python /opt/root2/logchecker.py
Python Version Mismatch
Try specifying the exact Python version:
- name: Execute with python3
command: /usr/bin/python3 /opt/root2/logchecker.py
Working Directory Problems
Add working directory specification:
- name: Execute script with working dir
command: /usr/bin/python /opt/root2/logchecker.py
args:
chdir: /opt/root2/
Here's a more robust version that handles common edge cases:
- hosts: mygroup
become: yes
vars:
script_name: logchecker.py
script_src: /home/user/Scripts/{{ script_name }}
script_dest: /opt/root2/{{ script_name }}
tasks:
- name: Verify Python is installed
package:
name: python3
state: present
- name: Create destination directory
file:
path: /opt/root2
state: directory
mode: '0755'
owner: root
group: root
- name: Copy script
copy:
src: "{{ script_src }}"
dest: "{{ script_dest }}"
owner: root
group: root
mode: '0755'
- name: Validate script syntax
command: python3 -m py_compile "{{ script_dest }}"
register: syntax_check
ignore_errors: yes
- name: Execute script
command: python3 "{{ script_dest }}"
environment:
PYTHONUNBUFFERED: 1
args:
chdir: /opt/root2
When troubleshooting, add these verification steps:
- name: Verify script exists
stat:
path: /opt/root2/logchecker.py
register: script_stat
- name: Check script permissions
command: ls -la /opt/root2/logchecker.py
register: ls_output
changed_when: false
- name: Debug output
debug:
msg: "Script exists: {{ script_stat.stat.exists }}, Permissions: {{ ls_output.stdout }}"
For complex Python deployments, consider:
- name: Install Python requirements
pip:
requirements: /opt/root2/requirements.txt
executable: pip3
- name: Run script as module
command: python3 -m logchecker
args:
chdir: /opt/root2