Troubleshooting Ansible Playbook: Python Script Execution Fails After Successful File Upload


4 views

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:

  1. Environment Path Issues: The Python environment might be different when invoked through Ansible
  2. Working Directory Problems: The script might depend on relative paths
  3. 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