Ansible Pilot

Run a Python Script on Remote Machines - Ansible module script

How to automate the execution of a "cars.py" custom Python script on a remote machine after transferring it and processing the output as an Ansible JSON variable using Ansible Playbook and script module.

August 18, 2022
Access the Complete Video Course and Learn Quick Ansible by 200+ Practical Lessons

How to Run Python Script on Remote Machines after transferring it?

I’m going to show you a live demo with some simple Ansible code. I’m Luca Berton and welcome to today’s episode of Ansible Pilot.

Run Python Script on Remote Machines

Let’s talk about the Ansible module script. The full name is ansible.builtin.script, which means that is part of the Ansible builtin modules included in ansible-core. The purpose of the module is to Runs a local script on a remote node after transferring it.

Parameters

Let me summarize the main parameters of the module script. This module doesn’t have any required parameters bus some options become necessary in this use case. The cmd parameter specifies the script name or path. The executable parameter specifies the interpreter name or path.

The Best Resources For Ansible

Video Course

Books

Demo

Let’s jump into a real-life Ansible Playbook to Run Python Script on Remote Machines after transferring it. I’m going to show you how to create a cars.py custom Python script that output a JSON file, transfers it to a remote machine, and executes it using python3 interpreter.

code

#!/usr/bin/env python3
import json
cars = {
    "manufacturers": [
        "Acura", "Alfa-Romeo", "Aston-Martin", "Audi", "Bentley", "BMW",
        "Bugatti", "Buick", "Cadillac", "Chevrolet", "Chrysler", "Citroen",
        "Deus Automobiles", "Dodge", "Ferrari", "Fiat", "Ford", "Geely",
        "Genesis", "GMC", "Honda", "Hyundai", "Infiniti", "Jaguar", "Jeep",
        "Kia", "Koenigsegg", "Lamborghini", "Lancia", "Land Rover", "Lexus",
        "Lincoln", "Lotus", "Maserati", "Maybach", "Mazda", "McLaren", "Mercedes",
        "Mini", "Mitsubishi", "Nissan", "Opel", "Pagani", "Peugeot", "Pontiac",
        "Porsche", "Ram", "Renault", "Rolls-Royce", "Skoda", "Smart", "Subaru",
        "Suzuki", "Tesla", "Toyota", "Volkswagen", "Volvo"
    ]
}
print(json.dumps(cars, indent=4))
---
- name: run Python script
  hosts: all
  tasks:
    - name: run cars.py script
      ansible.builtin.script:
        executable: python3
        cmd: cars.py
      register: cars_raw_output
    - name: print cars_raw_output
      ansible.builtin.debug:
        var: cars_raw_output
        verbosity: 2
    - name: convert output to JSON
      ansible.builtin.set_fact:
        cars_list: "{{ cars_raw_output.stdout | from_json }}"
    - name: print cars_list
      ansible.builtin.debug:
        var: cars_list

execution

ansible-pilot $ ansible-playbook -i ../virtualmachines/demo/inventory run_python_script.yml
PLAY [run Python script] **************************************************************************
TASK [Gathering Facts] ****************************************************************************
ok: [demo.example.com]
TASK [run cars.py script] *************************************************************************
changed: [demo.example.com]
TASK [print cars_raw_output] **********************************************************************
skipping: [demo.example.com]
TASK [convert output to JSON] *********************************************************************
ok: [demo.example.com]
TASK [print cars_list] ****************************************************************************
ok: [demo.example.com] => {
    "cars_list": {
        "manufacturers": [
            "Acura",
            "Alfa-Romeo",
            "Aston-Martin",
            "Audi",
            "Bentley",
            "BMW",
            "Bugatti",
            "Buick",
            "Cadillac",
            "Chevrolet",
            "Chrysler",
            "Citroen",
            "Deus Automobiles",
            "Dodge",
            "Ferrari",
            "Fiat",
            "Ford",
            "Geely",
            "Genesis",
            "GMC",
            "Honda",
            "Hyundai",
            "Infiniti",
            "Jaguar",
            "Jeep",
            "Kia",
            "Koenigsegg",
            "Lamborghini",
            "Lancia",
            "Land Rover",
            "Lexus",
            "Lincoln",
            "Lotus",
            "Maserati",
            "Maybach",
            "Mazda",
            "McLaren",
            "Mercedes",
            "Mini",
            "Mitsubishi",
            "Nissan",
            "Opel",
            "Pagani",
            "Peugeot",
            "Pontiac",
            "Porsche",
            "Ram",
            "Renault",
            "Rolls-Royce",
            "Skoda",
            "Smart",
            "Subaru",
            "Suzuki",
            "Tesla",
            "Toyota",
            "Volkswagen",
            "Volvo"
        ]
    }
}
PLAY RECAP ****************************************************************************************
demo.example.com           : ok=4    changed=1    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
ansible-pilot $

verbosity two execution

ansible-pilot $ ansible-playbook -i ../virtualmachines/demo/inventory run_python_script.yml -vv
ansible-playbook [core 2.13.1]
  config file = None
  configured module search path = ['/Users/lberton/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/Cellar/ansible/6.1.0/libexec/lib/python3.10/site-packages/ansible
  ansible collection location = /Users/lberton/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible-playbook
  python version = 3.10.5 (main, Jun 23 2022, 17:15:32) [Clang 13.0.0 (clang-1300.0.29.30)]
  jinja version = 3.1.2
  libyaml = True
No config file found; using defaults
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.
PLAYBOOK: run_python_script.yml *******************************************************************
1 plays in run_python_script.yml
PLAY [run Python script] **************************************************************************
TASK [Gathering Facts] ****************************************************************************
task path: /Users/lberton/prj/github/ansible-pilot/how-to-run-script/run_python_script.yml:2
ok: [demo.example.com]
META: ran handlers
TASK [run cars.py script] *************************************************************************
task path: /Users/lberton/prj/github/ansible-pilot/how-to-run-script/run_python_script.yml:5
changed: [demo.example.com] => {"changed": true, "rc": 0, "stderr": "Shared connection to demo.example.com closed.\r\n", "stderr_lines": ["Shared connection to demo.example.com closed."], "stdout": "{\r\n    \"manufacturers\": [\r\n        \"Acura\",\r\n        \"Alfa-Romeo\",\r\n        \"Aston-Martin\",\r\n        \"Audi\",\r\n        \"Bentley\",\r\n        \"BMW\",\r\n        \"Bugatti\",\r\n        \"Buick\",\r\n        \"Cadillac\",\r\n        \"Chevrolet\",\r\n        \"Chrysler\",\r\n        \"Citroen\",\r\n        \"Deus Automobiles\",\r\n        \"Dodge\",\r\n        \"Ferrari\",\r\n        \"Fiat\",\r\n        \"Ford\",\r\n        \"Geely\",\r\n        \"Genesis\",\r\n        \"GMC\",\r\n        \"Honda\",\r\n        \"Hyundai\",\r\n        \"Infiniti\",\r\n        \"Jaguar\",\r\n        \"Jeep\",\r\n        \"Kia\",\r\n        \"Koenigsegg\",\r\n        \"Lamborghini\",\r\n        \"Lancia\",\r\n        \"Land Rover\",\r\n        \"Lexus\",\r\n        \"Lincoln\",\r\n        \"Lotus\",\r\n        \"Maserati\",\r\n        \"Maybach\",\r\n        \"Mazda\",\r\n        \"McLaren\",\r\n        \"Mercedes\",\r\n        \"Mini\",\r\n        \"Mitsubishi\",\r\n        \"Nissan\",\r\n        \"Opel\",\r\n        \"Pagani\",\r\n        \"Peugeot\",\r\n        \"Pontiac\",\r\n        \"Porsche\",\r\n        \"Ram\",\r\n        \"Renault\",\r\n        \"Rolls-Royce\",\r\n        \"Skoda\",\r\n        \"Smart\",\r\n        \"Subaru\",\r\n        \"Suzuki\",\r\n        \"Tesla\",\r\n        \"Toyota\",\r\n        \"Volkswagen\",\r\n        \"Volvo\"\r\n    ]\r\n}\r\n", "stdout_lines": ["{", "    \"manufacturers\": [", "        \"Acura\",", "        \"Alfa-Romeo\",", "        \"Aston-Martin\",", "        \"Audi\",", "        \"Bentley\",", "        \"BMW\",", "        \"Bugatti\",", "        \"Buick\",", "        \"Cadillac\",", "        \"Chevrolet\",", "        \"Chrysler\",", "        \"Citroen\",", "        \"Deus Automobiles\",", "        \"Dodge\",", "        \"Ferrari\",", "        \"Fiat\",", "        \"Ford\",", "        \"Geely\",", "        \"Genesis\",", "        \"GMC\",", "        \"Honda\",", "        \"Hyundai\",", "        \"Infiniti\",", "        \"Jaguar\",", "        \"Jeep\",", "        \"Kia\",", "        \"Koenigsegg\",", "        \"Lamborghini\",", "        \"Lancia\",", "        \"Land Rover\",", "        \"Lexus\",", "        \"Lincoln\",", "        \"Lotus\",", "        \"Maserati\",", "        \"Maybach\",", "        \"Mazda\",", "        \"McLaren\",", "        \"Mercedes\",", "        \"Mini\",", "        \"Mitsubishi\",", "        \"Nissan\",", "        \"Opel\",", "        \"Pagani\",", "        \"Peugeot\",", "        \"Pontiac\",", "        \"Porsche\",", "        \"Ram\",", "        \"Renault\",", "        \"Rolls-Royce\",", "        \"Skoda\",", "        \"Smart\",", "        \"Subaru\",", "        \"Suzuki\",", "        \"Tesla\",", "        \"Toyota\",", "        \"Volkswagen\",", "        \"Volvo\"", "    ]", "}"]}
TASK [print cars_raw_output] **********************************************************************
task path: /Users/lberton/prj/github/ansible-pilot/how-to-run-script/run_python_script.yml:11
ok: [demo.example.com] => {
    "cars_raw_output": {
        "changed": true,
        "failed": false,
        "rc": 0,
        "stderr": "Shared connection to demo.example.com closed.\r\n",
        "stderr_lines": [
            "Shared connection to demo.example.com closed."
        ],
        "stdout": "{\r\n    \"manufacturers\": [\r\n        \"Acura\",\r\n        \"Alfa-Romeo\",\r\n        \"Aston-Martin\",\r\n        \"Audi\",\r\n        \"Bentley\",\r\n        \"BMW\",\r\n        \"Bugatti\",\r\n        \"Buick\",\r\n        \"Cadillac\",\r\n        \"Chevrolet\",\r\n        \"Chrysler\",\r\n        \"Citroen\",\r\n        \"Deus Automobiles\",\r\n        \"Dodge\",\r\n        \"Ferrari\",\r\n        \"Fiat\",\r\n        \"Ford\",\r\n        \"Geely\",\r\n        \"Genesis\",\r\n        \"GMC\",\r\n        \"Honda\",\r\n        \"Hyundai\",\r\n        \"Infiniti\",\r\n        \"Jaguar\",\r\n        \"Jeep\",\r\n        \"Kia\",\r\n        \"Koenigsegg\",\r\n        \"Lamborghini\",\r\n        \"Lancia\",\r\n        \"Land Rover\",\r\n        \"Lexus\",\r\n        \"Lincoln\",\r\n        \"Lotus\",\r\n        \"Maserati\",\r\n        \"Maybach\",\r\n        \"Mazda\",\r\n        \"McLaren\",\r\n        \"Mercedes\",\r\n        \"Mini\",\r\n        \"Mitsubishi\",\r\n        \"Nissan\",\r\n        \"Opel\",\r\n        \"Pagani\",\r\n        \"Peugeot\",\r\n        \"Pontiac\",\r\n        \"Porsche\",\r\n        \"Ram\",\r\n        \"Renault\",\r\n        \"Rolls-Royce\",\r\n        \"Skoda\",\r\n        \"Smart\",\r\n        \"Subaru\",\r\n        \"Suzuki\",\r\n        \"Tesla\",\r\n        \"Toyota\",\r\n        \"Volkswagen\",\r\n        \"Volvo\"\r\n    ]\r\n}\r\n",
        "stdout_lines": [
            "{",
            "    \"manufacturers\": [",
            "        \"Acura\",",
            "        \"Alfa-Romeo\",",
            "        \"Aston-Martin\",",
            "        \"Audi\",",
            "        \"Bentley\",",
            "        \"BMW\",",
            "        \"Bugatti\",",
            "        \"Buick\",",
            "        \"Cadillac\",",
            "        \"Chevrolet\",",
            "        \"Chrysler\",",
            "        \"Citroen\",",
            "        \"Deus Automobiles\",",
            "        \"Dodge\",",
            "        \"Ferrari\",",
            "        \"Fiat\",",
            "        \"Ford\",",
            "        \"Geely\",",
            "        \"Genesis\",",
            "        \"GMC\",",
            "        \"Honda\",",
            "        \"Hyundai\",",
            "        \"Infiniti\",",
            "        \"Jaguar\",",
            "        \"Jeep\",",
            "        \"Kia\",",
            "        \"Koenigsegg\",",
            "        \"Lamborghini\",",
            "        \"Lancia\",",
            "        \"Land Rover\",",
            "        \"Lexus\",",
            "        \"Lincoln\",",
            "        \"Lotus\",",
            "        \"Maserati\",",
            "        \"Maybach\",",
            "        \"Mazda\",",
            "        \"McLaren\",",
            "        \"Mercedes\",",
            "        \"Mini\",",
            "        \"Mitsubishi\",",
            "        \"Nissan\",",
            "        \"Opel\",",
            "        \"Pagani\",",
            "        \"Peugeot\",",
            "        \"Pontiac\",",
            "        \"Porsche\",",
            "        \"Ram\",",
            "        \"Renault\",",
            "        \"Rolls-Royce\",",
            "        \"Skoda\",",
            "        \"Smart\",",
            "        \"Subaru\",",
            "        \"Suzuki\",",
            "        \"Tesla\",",
            "        \"Toyota\",",
            "        \"Volkswagen\",",
            "        \"Volvo\"",
            "    ]",
            "}"
        ]
    }
}
TASK [convert output to JSON] *********************************************************************
task path: /Users/lberton/prj/github/ansible-pilot/how-to-run-script/run_python_script.yml:16
ok: [demo.example.com] => {"ansible_facts": {"cars_list": {"manufacturers": ["Acura", "Alfa-Romeo", "Aston-Martin", "Audi", "Bentley", "BMW", "Bugatti", "Buick", "Cadillac", "Chevrolet", "Chrysler", "Citroen", "Deus Automobiles", "Dodge", "Ferrari", "Fiat", "Ford", "Geely", "Genesis", "GMC", "Honda", "Hyundai", "Infiniti", "Jaguar", "Jeep", "Kia", "Koenigsegg", "Lamborghini", "Lancia", "Land Rover", "Lexus", "Lincoln", "Lotus", "Maserati", "Maybach", "Mazda", "McLaren", "Mercedes", "Mini", "Mitsubishi", "Nissan", "Opel", "Pagani", "Peugeot", "Pontiac", "Porsche", "Ram", "Renault", "Rolls-Royce", "Skoda", "Smart", "Subaru", "Suzuki", "Tesla", "Toyota", "Volkswagen", "Volvo"]}}, "changed": false}
TASK [print cars_list] ****************************************************************************
task path: /Users/lberton/prj/github/ansible-pilot/how-to-run-script/run_python_script.yml:20
ok: [demo.example.com] => {
    "cars_list": {
        "manufacturers": [
            "Acura",
            "Alfa-Romeo",
            "Aston-Martin",
            "Audi",
            "Bentley",
            "BMW",
            "Bugatti",
            "Buick",
            "Cadillac",
            "Chevrolet",
            "Chrysler",
            "Citroen",
            "Deus Automobiles",
            "Dodge",
            "Ferrari",
            "Fiat",
            "Ford",
            "Geely",
            "Genesis",
            "GMC",
            "Honda",
            "Hyundai",
            "Infiniti",
            "Jaguar",
            "Jeep",
            "Kia",
            "Koenigsegg",
            "Lamborghini",
            "Lancia",
            "Land Rover",
            "Lexus",
            "Lincoln",
            "Lotus",
            "Maserati",
            "Maybach",
            "Mazda",
            "McLaren",
            "Mercedes",
            "Mini",
            "Mitsubishi",
            "Nissan",
            "Opel",
            "Pagani",
            "Peugeot",
            "Pontiac",
            "Porsche",
            "Ram",
            "Renault",
            "Rolls-Royce",
            "Skoda",
            "Smart",
            "Subaru",
            "Suzuki",
            "Tesla",
            "Toyota",
            "Volkswagen",
            "Volvo"
        ]
    }
}
META: ran handlers
META: ran handlers
PLAY RECAP ****************************************************************************************
demo.example.com           : ok=5    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
ansible-pilot $

code with ❤️ in GitHub

Recap

Now you know how to Run Python Script on Remote Machines after transferring it with Ansible. Subscribe to the YouTube channel, Medium, Website, Twitter, and Substack to not miss the next episode of the Ansible Pilot.

Academy

Learn the Ansible automation technology with some real-life examples in my

My book Ansible By Examples: 200+ Automation Examples For Linux and Windows System Administrator and DevOps

BUY the Complete PDF BOOK to easily Copy and Paste the 200+ Ansible code

Want to keep this project going? Please donate

Access the Complete Video Course and Learn Quick Ansible by 200+ Practical Lessons
Trustpilot
Follow me

Subscribe not to miss any new releases

FREE Top 10 Best Practices

Top 10 Best Practices of Ansible Automation: save time, reduce errors and stress