34

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 ...

Vincent Doba
  • 4,343
  • 3
  • 22
  • 42
CorayThan
  • 17,174
  • 28
  • 113
  • 161

7 Answers7

65

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

tbobm
  • 113
  • 1
  • 9
Orest Stetsiak
  • 776
  • 6
  • 8
  • This is the better answer and I'm not even sure why I didn't suggest it other than more closely following the OP's original code. Use roles and then use the syntactic sugar around them such as the search paths for scripts/files and templates etc. – ydaetskcoR Feb 02 '17 at 07:07
  • 1
    This solution run script on remote host. @ydaetskcoR solution run on local (management) host. – mmv-ru Apr 14 '18 at 09:22
  • if I am trying to run this I am getting error name: Run a script using an executable in a system path script: /home/user/sample.py args: executable: python2.7 – user583088 Jul 18 '19 at 02:06
  • I create another python script to write a file which did work well , but dont understand why I am not seeing print statements – user583088 Jul 19 '19 at 20:57
17

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
ydaetskcoR
  • 53,225
  • 8
  • 158
  • 177
  • That would screw up my directory I intend to run the python script in, but I suppose I can pass that as a param to the python script. Thanks! – CorayThan Feb 01 '16 at 21:39
  • 1
    Then simply change the `command` line to `command: ./"{{ role_path }}"/files/mypythonscript.py` if your Python script needs to be ran from some specific path (and obviously change the `chdir` arg to the path you want it to be) – ydaetskcoR Feb 01 '16 at 22:41
  • 1
    I hope the entire value of chdir should be double quoted which could prevent syntax error. – S.K. Venkat Mar 20 '18 at 08:53
  • I m not able to understand what role path is . I am trying to run python script which is on ansible server /home/user . but if I am providing path it does not work. I am getting errors – user583088 Jul 18 '19 at 01:55
  • role_path points to the top level folder for the role, and the role specific folders - files, templates, task, etc - are below that. e.g. if you role is name "myrole" role_path's value might be /home/user/project/playbooks/roles/myrole" – majorgear May 04 '22 at 15:27
3

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
Johnny.X
  • 61
  • 3
2

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.

Hello Human
  • 454
  • 7
  • 11
1

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
0

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
Isaac
  • 1
  • 1
0

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
vini
  • 87
  • 12