Ansible:在单个会话中安装多个 Python 包

Ansible: install multiple Python packages on a single session

我的一本剧本包含安装基本 Python 软件包的任务:

---
  -
    name: "Install Python packages: {{ python_packages_to_install }}"
    sudo: true
    pip: name={{ item }}
    with_items: python_packages_to_install

具有以下软件包列表:

-
  include: python_basics.yaml
  vars:
     python_packages_to_install:
       - virtualenv
       - pss
       - requests
       - comment-builder
       - boto
       - ansible
       - uwsgitop
       - gitpull
       - ipython

任务正常运行并安装包:

TASK: [common | Install Python packages: ['virtualenv', 'pss', 'requests', 'comment-builder', 'boto', 'ansible', 'uwsgitop', 'gitpull', 'ipython']] ***
ok: [push-prod-01] => (item=virtualenv)
ok: [push-prod-01] => (item=pss)
ok: [push-prod-01] => (item=requests)
ok: [push-prod-01] => (item=comment-builder)
ok: [push-prod-01] => (item=boto)
ok: [push-prod-01] => (item=ansible)
ok: [push-prod-01] => (item=uwsgitop)
ok: [push-prod-01] => (item=gitpull)
changed: [push-prod-01] => (item=ipython)

问题是每一行都是使用连续的 SSH 命令执行的,而不是在一次调用中安装所有包。

有没有办法在 Ansible pip 命令上安装多个 Python 包?

与 Ansible apt 模块不同,the pip module 不接受以逗号分隔的包列表。相反,您可以提供所有包名称作为 space 分隔字符串,使用 == 语法指定版本:

python_packages_to_install: "virtualenv==1.11.6 pss requests comment-builder boto ansible uwsgitop gitpull ipython"

如果您像我一样,可能会觉得管理起来丑陋且不切实际。另一种方法是使用 pip 模块中的 requirements 选项来指定需求文件。当然,您首先需要创建需求文件,可能需要使用模板。

扩展 Ben 的回答,您还可以像现有的那样继续将包列表保存为 yaml 列表,并在将其传递给 pip 模块时投影为单个值,例如:

pip: name="{{ python_packages_to_install | join(' ') }}"

让您的剧本更易于维护...

Ansible pip 模块现在支持 multi-python 包安装。

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

参考:https://docs.ansible.com/ansible/latest/collections/ansible/builtin/pip_module.html