【问题标题】:Installing multiple packages in Ansible在 Ansible 中安装多个包
【发布时间】:2019-03-01 11:49:39
【问题描述】:

我在 Ansible 中有这个任务:

- name: Install mongodb
  yum:
    name:
    - "mongodb-org-{{ mongodb_version }}"
    - "mongodb-org-server-{{ mongodb_version }}"
    - "mongodb-org-mongos-{{ mongodb_version }}"
    - "mongodb-org-shell-{{ mongodb_version }}"
    - "mongodb-org-tools-{{ mongodb_version }}"
    state: present
  notify: Restart mongodb

有没有一种方法可以指示版本而不必使用这样的循环?有什么更“优雅”的写法?

- name: Install mongodb
  yum:
    name: "{{ item }}-{{ mongodb_version }}"
    state: present
    loop:
    - mongodb-org-server
    - mongodb-org-mongos
    - mongodb-org-shell
    - mongodb-org-tools
  notify: Restart mongodb

【问题讨论】:

  • 我怀疑有没有更好的解决方案。也许如果您将包列表作为变量,然后使用name 中的变量。它至少会使代码更清晰,并将逻辑与变量和常量分开。
  • 为了更清楚一点,我会使用 var 文件夹并创建一个包含所需 mongodb 列表的 var,然后调用该 var,这样您的整体任务将更加清晰看着它。

标签: ansible


【解决方案1】:

令我惊讶的是我没有在所有答案中找到最简单的解决方案就是这样。参考问题标题Installing multiple packages in Ansible这是(使用yum module):

- name: Install MongoDB
  yum:
    name:
      - mongodb-org-server
      - mongodb-org-mongos
      - mongodb-org-shell
      - mongodb-org-tools 
    state: latest
    update_cache: true

或使用apt module

- name: Install MongoDB
  apt:
    pkg:
      - mongodb-org-server
      - mongodb-org-mongos
      - mongodb-org-shell
      - mongodb-org-tools 
    state: latest
    update_cache: true

两个模块都支持内联列表!

您问题的第二部分如何将特定版本号集成到包列表中。没问题 - 只需删除 state: latest(因为将特定版本号与 state: latest 一起使用会引发错误)并使用前面的 = 将版本号添加到包名称中,如下所示:

- name: Install MongoDB
  yum:
    name:
      - mongodb-org-server=1:3.6.3-0centos1.1
      - mongodb-org-mongos=1:3.6.3-0centos1.1
      - mongodb-org-shell=1:3.6.3-0centos1.1
      - mongodb-org-tools=1:3.6.3-0centos1.1 
    update_cache: true

您还可以进一步优化和模板化版本号。在这种情况下不要忘记添加引号:)

【讨论】:

  • 这是正确的答案。我不知道其他人在做什么。
  • 要么我误解了这个问题,要么这并没有真正回答它。
  • 嗯,答案是关于在 Ansible 中安装多个包 - 你所说的“不回答”究竟是什么意思?
【解决方案2】:

把它变成一个Ansible Role,叫做mongo,得到目录结构:

playbook.yml
roles
|-- mongo
|  |-- defaults
|  |    |-- main.yml
|  |
|  |-- tasks
|  |    |-- main.yml
|  |
|  |-- handlers
|  |    |-- main.yml

将所需的MongoDB包和版本添加到默认变量文件roles/mongo/defaults/main.yml

mongo_version: 4.0
mongo_packages:
- mongodb-org-server
- mongodb-org-mongos
- mongodb-org-shell
- mongodb-org-tools

重写roles/mongo/tasks/main.yml文件中的任务:

- name: Install mongodb
  yum:
    name: "{{ item }}-{{ mongo_version }}"
    state: present
  with_items: "{{ mongo_packages }}"
  notify: Restart mongodb

在文件 roles/mongo/handlers/main.yml 中添加您的处理程序逻辑以重新启动 MongoDB。

编写一个名为playbook.yml 的剧本来调用该角色。

---
- hosts: all
  roles:
  - mongo

【讨论】:

    【解决方案3】:

    我认为这是最好的方法,但由于包名不应该是硬编码的,所以最好保留在 vars/main.yml 例如

    mongodb_version: 5
    packages:
      - "mongodb-org-shell-{{ mongodb_version }}"
      - "mongodb-org-server-{{ mongodb_version }}"
    

    在你的剧本中将其称为

    - name: Install mongodb packages
      yum: name={{ item }}
           state=latest
      with_items: "{{ packages}}"
    

    【讨论】:

    • 如果我使用循环安装包,yum 模块会报错。
    【解决方案4】:

    现在 yum 模块直接接受这样的包数组

      vars:
        pkgs:
          - screen
          - rubygems
          - ksh
          - strace
    
      tasks:
      - name: Install pre-requisite packages
        yum: name={{ pkgs }} state=installed
    

    【讨论】:

      【解决方案5】:

      一个更优雅的方法是使用这样的方法,如果每次运行脚本时都安装了,它不会继续重新检查每个包:

      vars/main.yml 或类似:

        packages_to_install:
          - mongodb-org-server
          - mongodb-org-mongos
          - mongodb-org-shell
          - mongodb-org-tools  
      

      tasks/main.yml 或类似地址:

        - name: "Get installed packages"
          yum:
            list: "installed"
          register: installed_packages
      
        - name: "Install missing packages"
          package: 
            state: "present"
            name: "{{ item }}"
          with_items: "{{ packages_to_install | difference(installed_packages | json_query('results[*].name')) }}"
      

      本质上,这会检查已安装的内容并仅安装缺少的软件包。与直觉相反,这更快。您也可以使用dnf 代替yum

      【讨论】:

        【解决方案6】:

        有些人提到了允许传递列表的语法,但您不需要将代码特殊化为 aptyum。这是使用通用包管理器模块的命令:

        - name: Install packages
          become: yes
          package:
            name:
              - tmux
              - rsync
              - zsh
              - rsync
              - wget
            state: present
        

        (或state: latest。)此功能仅适用于 Ansible 2.9 的 documented,因此可能是新功能。

        【讨论】:

          猜你喜欢
          • 2017-10-16
          • 1970-01-01
          • 2018-12-12
          • 1970-01-01
          • 1970-01-01
          • 2023-02-22
          • 1970-01-01
          • 2017-04-22
          • 2013-03-10
          相关资源
          最近更新 更多