Introduction

ansible.builtin.pip installs Python packages from PyPI, Git repos, or local files. It supports virtual environments, requirements files, and version pinning — everything you need to manage Python dependencies on remote hosts.

Basic Usage

# Install a package
- name: Install Flask
  ansible.builtin.pip:
    name: flask

# Install specific version
- name: Install Flask 3.0
  ansible.builtin.pip:
    name: flask==3.0.0

# Install multiple packages
- name: Install Python packages
  ansible.builtin.pip:
    name:
      - flask==3.0.0
      - gunicorn>=21.2.0
      - redis
      - celery[redis]

# Install latest version
- name: Upgrade pip
  ansible.builtin.pip:
    name: pip
    state: latest

Parameters

ParameterDefaultDescription
name—Package name(s) with optional version
requirements—Path to requirements.txt
statepresentpresent, absent, latest, forcereinstall
virtualenv—Virtual environment path
virtualenv_commandvirtualenvCommand to create venv (python3 -m venv)
virtualenv_python—Python interpreter for venv
executable—pip executable path (pip3)
extra_args—Extra arguments for pip
editablefalseInstall in editable mode (-e)
chdir—Change to directory before running
umask—umask for install command

Virtual Environments

# Create venv and install packages
- name: Setup application virtualenv
  ansible.builtin.pip:
    name:
      - flask
      - gunicorn
      - psycopg2-binary
    virtualenv: /opt/myapp/venv
    virtualenv_command: python3 -m venv

# Install from requirements into venv
- name: Install requirements
  ansible.builtin.pip:
    requirements: /opt/myapp/requirements.txt
    virtualenv: /opt/myapp/venv

Requirements Files

# Install from requirements.txt
- name: Install from requirements
  ansible.builtin.pip:
    requirements: /opt/myapp/requirements.txt

# Install into virtualenv from requirements
- name: Install app dependencies
  ansible.builtin.pip:
    requirements: "{{ app_dir }}/requirements.txt"
    virtualenv: "{{ app_dir }}/venv"
    virtualenv_command: python3 -m venv

Remove Packages

- name: Remove package
  ansible.builtin.pip:
    name: flask
    state: absent

- name: Remove multiple packages
  ansible.builtin.pip:
    name:
      - flask
      - gunicorn
    state: absent

Practical Patterns

Application Deployment

---
- name: Deploy Python application
  hosts: appservers
  become: true
  vars:
    app_dir: /opt/myapp
    app_user: deploy
  tasks:
    - name: Ensure pip is installed
      ansible.builtin.apt:
        name:
          - python3-pip
          - python3-venv
        state: present

    - name: Create app directory
      ansible.builtin.file:
        path: "{{ app_dir }}"
        state: directory
        owner: "{{ app_user }}"

    - name: Clone application
      ansible.builtin.git:
        repo: git@github.com:myorg/myapp.git
        dest: "{{ app_dir }}"
        version: "{{ app_version }}"
      become_user: "{{ app_user }}"
      register: git_result

    - name: Install dependencies
      ansible.builtin.pip:
        requirements: "{{ app_dir }}/requirements.txt"
        virtualenv: "{{ app_dir }}/venv"
        virtualenv_command: python3 -m venv
      become_user: "{{ app_user }}"
      when: git_result.changed
      notify: Restart application

  handlers:
    - name: Restart application
      ansible.builtin.service:
        name: myapp
        state: restarted

Install from Git

# Install from Git URL
- name: Install from GitHub
  ansible.builtin.pip:
    name: "git+https://github.com/myorg/mylib.git@v1.2.0"

# Install in editable mode (development)
- name: Install editable
  ansible.builtin.pip:
    name: /opt/myapp
    editable: true
    virtualenv: /opt/myapp/venv

Use pip3 Explicitly

- name: Install with pip3
  ansible.builtin.pip:
    name: flask
    executable: pip3

# Or specify Python version for venv
- name: Use Python 3.11
  ansible.builtin.pip:
    name: flask
    virtualenv: /opt/myapp/venv
    virtualenv_python: python3.11

Extra pip Arguments

# Install with extra index URL
- name: Install from private PyPI
  ansible.builtin.pip:
    name: mycompany-tools
    extra_args: "--index-url https://pypi.mycompany.com/simple/"

# Install with no-cache and trusted host
- name: Install with options
  ansible.builtin.pip:
    name: flask
    extra_args: "--no-cache-dir --trusted-host pypi.mycompany.com"

# Install pre-release
- name: Install pre-release
  ansible.builtin.pip:
    name: flask
    extra_args: "--pre"

Troubleshooting

"pip not found"

# Install pip first
- name: Install pip (Debian/Ubuntu)
  ansible.builtin.apt:
    name: python3-pip
    state: present

# Or (RHEL)
- name: Install pip (RHEL)
  ansible.builtin.yum:
    name: python3-pip
    state: present

"Permission denied" with System pip

Use virtualenv or --user:

# Best: use virtualenv
- pip:
    name: flask
    virtualenv: /opt/myapp/venv

# Or install as user
- pip:
    name: flask
    extra_args: "--user"
  become_user: deploy

Externally Managed Environment (PEP 668)

On newer systems (Ubuntu 23.04+, Debian 12+), pip refuses to install system-wide:

# Use virtualenv (recommended)
- pip:
    name: flask
    virtualenv: /opt/myapp/venv
    virtualenv_command: python3 -m venv

# Or break-system-packages (not recommended)
- pip:
    name: flask
    extra_args: "--break-system-packages"

Conclusion

ansible.builtin.pip manages Python packages idempotently. Always use virtual environments (virtualenv parameter) for application deployments — it isolates dependencies and avoids system conflicts. Use requirements for reproducible installs from a requirements file. Pin versions in production (flask==3.0.0). On modern systems with PEP 668, virtualenvs are required — system-wide pip installs are blocked by default.