Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible: Install Python module only if it not exist

Tags:

ansible

devops

I need to install Python pip via Ansible on a remote server. I do it like this and it work:

  - name: Download pip installer
    get_url:
      url: https://bootstrap.pypa.io/pip/2.7/get-pip.py
      dest: /tmp/get-pip.py

  - name: Install pip
    shell: /usr/bin/python /tmp/get-pip.py

One problem - it have status "changed" every time when I run a playbook. I don't need to install it every time I run playbook.

How can I check and install the pip module only if it didn't installed before?

like image 215
seventh Avatar asked Jun 12 '26 13:06

seventh


2 Answers

Since a system where pip hasn't been installed reports with

pip --version; echo $?
-bash: pip: command not found
127

you could implement installation and version tests before running the download and installation task.

---
- hosts: test
  become: false
  gather_facts: false

  tasks:

  - name: Gather installed pip version, if there is any
    shell:
      cmd: pip --version | cut -d ' ' -f 2
    register: result
    failed_when: result.rc != 0 and result.rc != 127
    # Since this is a reporting task, it should never change
    # as well run and register a result in any case
    changed_when: false
    check_mode: false

  - name: Set default version, if there is no
    set_fact:
      result:
        stdout_lines: "00.0.0"
    when: "'command not found' in result.stdout"

  - name: Report result
    debug:
      msg: "{{ result.stdout }}"
    check_mode: false
    when: result.stdout != "20.3.4"

Resulting into an output of

TASK [Gather installed pip version, if there is any] ***
ok: [test.example.com]

TASK [Report result] ***********************************
ok: [test.example.com] =>
  msg: 20.3.4

Further Q&A

  • Whats the best way in Ansible to check if a command is available?
  • Ansible: How to install a package only if same version not installed?

Documentation

  • Defining failure
  • Defining "changed"
  • Using check_mode

... just an example add-on with shell operators

  - name: Install 'pip' only if it not exist
    shell: 
      cmd: pip --version || /usr/bin/python /tmp/get-pip.py
  • Use of && and || operators
  • Boolean operators
like image 96
U880D Avatar answered Jun 17 '26 23:06

U880D


You can easily bypass both tasks by using the creates parameter which exists for shell and uri. It expects a filename which will be checked for existence. If the file exists the task will not be run.

Note: In my below not entirely tested example, I infered that your script installs the binary in /usr/local/bin/pip. Adapt to the exact installation location if different.

---
- name: Install pip
  hosts: all
  gather_facts: false

  vars:
    pip_location: /usr/local/bin/pip

  tasks:
    - name: Download pip installer
      get_url:
        url: https://bootstrap.pypa.io/pip/2.7/get-pip.py
        dest: /tmp/get-pip.py
        creates: "{{ pip_location }}"

    - name: Install pip
      shell:
        cmd: /usr/bin/python /tmp/get-pip.py
        creates: "{{ pip_location }}"

References:

  • creates parameter in shell module
  • creates parameter in uri module
like image 40
Zeitounator Avatar answered Jun 18 '26 01:06

Zeitounator



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!