てくなべ (tekunabe)

ansible / network / automation

【Ansible】pip モジュールでバージョン指定しながら複数のパッケージを指定できるようになった(Ansible 2.7新機能)

■ Ansible 2.7 で pip モジュールの name オプションで、バージョン指定しながら複数のパッケージを指定できるように

Ansible の pip モジュールでは、これまで name オプションの値をリストで指定すると、pip install pkgA pkgB pkgC のように、複数のパッケージを扱うことができました。しかし、pkgA==1.0.0 のようなバージョン指定と、リストによる複数の指定は併用できませんでした。 Ansible 2.7 では、バージョン指定しながら複数のパッケージを指定できるようになりました。

Playbook

- name: pip test
  pip:
    name:
      - netmiko>=2.2.0
      - ncclient==0.6.0
      - requests

コマンドイメージ

pip install netmiko>=2.2.0 ncclient==0.6.0 requests

この機能については、CHANGELOGには掲載されていませんが、pip モジュールのドキュメントname のオプションの説明として、以下のように記載されています。

This can be a list (since 2.2) and contain version specifiers (since 2.7).

これに伴って、例も2つ追加されています。

# Install (bottle) python package with version specifiers
- pip:
    name: bottle>0.10,<0.20,!=0.11

# Install multi python packages with version specifiers
- pip:
    name:
      - django>1.11.0,<1.12.0
      - bottle>0.10,<0.20,!=0.11



■(補足)Ansible 2.6 までの場合

比較のために、Ansible 2.6 までの状況について説明します。(2.7でも引き続き利用できる方法です)

requirements で代替可能

必要なパッケージ名と(必要であれば)バージョンを定義したリストファイルを用意して、requirements オプションで指定することでも代替可能です。

Playbook

 - name: pip test
    pip:
      requirements: /vagrant/test/requirements.txt

requirements.txt

netmiko>=2.2.0
ncclient==0.6.0
requests

コマンドイメージ

 pip install -r requirements.txt

パッケージ名だけの複数指定はOK

バージョンの指定をしなければ、リストによるパッケージ名だけの複数指定はできます。

Playbook

- name: pip test
  pip:
    name:
      - netmiko
      - ncclient
      - request

コマンドイメージ

pip intall netmiko ncclient request

1つパッケージ名だけならバージョン指定OK

パッケージ名の指定が1つだけなら、バージョン指定ができます。

Playbook

- name: pip test
  pip:
    name: netmiko
    version: 2.2.0

コマンドイメージ

pip intall netmiko==2.0.0

ですが、バージョン決め打ちの指定しかできず、 version: <= 2.2.0 といった指定はできません。

ループで回せばバージョン指定しながら複数のパッケージを指定(制限あり)

今回 Ansible 2.7 でできるようになったことの近いことは、with_listloop によるループでもできます。ただし、以下のような制限があります。

  • 「1つパッケージ名だけならバージョン指定OK」で説明した事情と同じく、<<= などの不等号を含むバージョン指定はきない
  • バージョン指定をしない場合は | default(omit) のような工夫が必要
  • ループするのでやや遅い

Playbook

- name: pip test
  pip:
    name: "{{ item.name }}"
    version: "{{ item.version | default(omit) }}"
  loop:
    - { name: "netmiko", version: "2.2.2" }
    - { name: "ncclient", version: "0.6.0" }
    - { name: "requests" }

コマンドイメージ(pip コマンド自体が複数)

pip intall netmiko==2.2.0
pip install ncclient==0.6.0
pip install requests

おわりに

地味なアップデートですが、これがやりたかった!というからもいらっしゃるのではないでしょうか。 このように、Ansible のアップデートは、CHANGELOG にな掲載されないものもあります。 普段お使いのモジュールの説明ドキュメントを見ると、なにか新しい発見があるかもしれません。

モジュール一覧はこちら