Ansibleでタスクを実行するリモートホストで追加のPythonパッケージが必要な場合に、プレイの中でまずpipでパッケージを入れるタスクを実行した上で依存パッケージが必要なタスク実行を一気通貫で処理する、というもの。
ありがちな例としては、ローカルホスト実行でなくリモート接続し、OS設定でなくAPI使ったミドルウェア設定などを行うようなパターン。

本記事ではpynetboxが必要なNetBox操作を例にプレイを紹介。
- リモートでvenvを作成し仮想環境内のPythonでpipを使うタスク
- get-pip.pyでpipをシステムワイドにインストールしてpipを使うタスク
- python3-pipパッケージがある場合でシステムワイドに入れるパターン
リモートでvenvを作成し仮想環境内のPythonでpipを使うタスク
プレイ実装の流れは以下の通り。
依存パッケージを使うタスクにはansible_python_interpreterでvenvのpythonインタプリタのパスを指定するのがポイント。
複数(大量に)ある場合は、playやroleを分けて丸ごとvarsで指定する方が記述量が減るので良いと思う。
python3-venvのインストール- venv作成しつつpipでパッケージインストール
- 上記のvenvをインタプリタに指定してタスク実行
- name: install venv ansible.builtin.apt: name: - python3-venv update_cache: true become: true - name: create venv ansible.builtin.pip: name: - pip - pynetbox state: latest virtualenv: "{{ venv_path }}" virtualenv_command: python3 -m venv become: true - name: create site # 追加パッケージが必要なタスク netbox.netbox.netbox_site: netbox_url: "https://{{ netbox_address }}" netbox_token: "{{ my_netbox_token }}" validate_certs: false data: name: sample-site state: present vars: ansible_python_interpreter: "{{ venv_path }}/bin/python"
やっているのは以前書いた以下の内容に、前処理としてvenvの作成も組み込んでいるという内容。
get-pip.pyでpipをシステムワイドにインストールしてpipを使うタスク
OSのパッケージ管理でpython3-pipが存在しない場合。
(存在する場合はpython3-pipをaptやdnfでインストールすればOK -> 後述)
- name: install pip ansible.builtin.shell: cmd: curl -sS https://bootstrap.pypa.io/get-pip.py | python3 - --break-system-packages creates: /usr/local/bin/pip become: true - name: install pynetbox ansible.builtin.pip: name: - pynetbox break_system_packages: true become: true - name: create site netbox.netbox.netbox_site: netbox_url: "https://{{ netbox_address }}" netbox_token: "{{ my_netbox_token }}" validate_certs: false data: name: sample-site state: present
以下でも書いた通り、PEP 668によるシステムPythonとの競合ガードがかかっているため、pipのインストールおよびパッケージインストールともにbreak-system-packagesを有効にするのがポイント。
(なお、Ubuntu24.04にpython3-pipが無いのは勘違い)
これ以降の依存パッケージが必要なタスクは、インタプリタの指定などの小細工は不要になるので普通に記述すればOK
python3-pipパッケージがある場合でシステムワイドに入れるパターン
上二つを組み合わせればOK
- name: install venv ansible.builtin.apt: name: - python3-pip update_cache: true become: true - name: install pynetbox ansible.builtin.pip: name: - pynetbox # break_system_packages: true # PEP668のガードがかかる場合は有効にする become: true
ちなみにEC2でデプロイしたUbuntu 24.04はpython3-pipが無いと思い込んでたけど、デプロイ直後だとローカルのリポジトリ情報に入っていなかっただけでapt-get updateしたらちゃんとあった…ただしPEP668ガードは生きているので回避策は必要。
プレイブックの実装としてはどれがあるべき姿なんだろうね…
Python的にはvevn使う方法だろうけど、環境構築的には「競合しないことをテストできていれば」システムワイドにpip入れても問題ないのでは…という気持ちも。