CorayThan
CorayThan

Reputation: 17825

Running Python script via ansible

I'm trying to run a python script from an ansible script. I would think this would be an easy thing to do, but I can't figure it out. I've got a project structure like this:

playbook-folder
  roles
    stagecode
      files
        mypythonscript.py
      tasks
        main.yml
  release.yml

I'm trying to run mypythonscript.py within a task in main.yml (which is a role used in release.yml). Here's the task:

- name: run my script!
  command: ./roles/stagecode/files/mypythonscript.py
  args:
    chdir: /dir/to/be/run/in
  delegate_to: 127.0.0.1
  run_once: true

I've also tried ../files/mypythonscript.py. I thought the path for ansible would be relative to the playbook, but I guess not?

I also tried debugging to figure out where I am in the middle of the script, but no luck there either.

- name: figure out where we are
  stat: path=.
  delegate_to: 127.0.0.1
  run_once: true
  register: righthere
    
- name: print where we are
  debug: msg="{{righthere.stat.path}}"
  delegate_to: 127.0.0.1
  run_once: true

That just prints out ".". So helpful ...

Upvotes: 36

Views: 148065

Answers (7)

vini
vini

Reputation: 107

If you want to run as part of gitlab runner. First run the below to get the python executable path.

  • name: show python lib/site paths python_requirements_info:
  • name: check for modern boto3 and botocore versions python_requirements_info: dependencies:
    • boto3>1.6
    • botocore<2

And then use that in the

  • name: run the python script script: <python_path> <script_name>.py

Upvotes: 0

Isaac
Isaac

Reputation: 1

If the logic of your script could be represented as a one-liner, how about the below ?

- name: " Attempt to acquire hw vendor "
  shell: |
        sudo /usr/sbin/dmidecode | /usr/bin/grep Vendor > /var/tmp/machine_Vendor.txt
  become: true

Upvotes: -1

Manoj Kumar
Manoj Kumar

Reputation: 31

To run a Python script via Ansible, you can use the command or script module in Ansible.

- name: Execute Python script
  hosts: target_hosts
  gather_facts: false

  tasks:
    - name: Run Python script
      command: python /path/to/script.py

Alternatively, you can use the script module if you want to execute a local script file on the target hosts. Here's an example:

- name: Execute Python script
  hosts: target_hosts
  gather_facts: false

  tasks:
    - name: Run Python script
      script: /path/to/local_script.py

Upvotes: 1

Hello Human
Hello Human

Reputation: 574

If you want to execute the inline script without having a separate script file (for example, as molecule test) you can write something like this:

- name: Test database connection
  ansible.builtin.command: |
    python3 -c
    "
    import psycopg2;
    psycopg2.connect(
      host='127.0.0.1',
      dbname='db',
      user='user',
      password='password'
    );
    "

You can even insert Ansible variables in this string.

Upvotes: 4

Johnny.X
Johnny.X

Reputation: 61

An alternative/straight forward solution: Let's say you have already built your virtual env under ./env1 and used pip3 install the needed python modules. Now write playbook task like:

 - name: Run a script using an executable in a system path
  script: ./test.py
  args:
    executable: ./env1/bin/python
  register: python_result
  
  - name: Get stdout or stderr from the output
    debug:
      var: python_result.stdout

Upvotes: 3

Orest Stetsiak
Orest Stetsiak

Reputation: 816

try to use script directive, it works for me

my main.yml

---
- name: execute install script
  script: get-pip.py

and get-pip.py file should be in files in the same role

Upvotes: 69

ydaetskcoR
ydaetskcoR

Reputation: 56839

If you want to be able to use a relative path to your script rather than an absolute path then you might be better using the role_path magic variable to find the path to the role and work from there.

With the structure you are using in the question the following should work:

- name: run my script!
  command: ./mypythonscript.py
  args:
    chdir: "{{ role_path }}"/files
  delegate_to: 127.0.0.1
  run_once: true

Upvotes: 17

Related Questions