【问题标题】:How 'not to run multiple times' command/shell task in Ansible playbook如何在 Ansible 剧本中“不运行多次”命令/shell 任务
【发布时间】:2022-01-09 18:59:25
【问题描述】:

我在 Ansible 中有一个任务是通过 RubyGems 选项安装 SASS 实用程序,它运行良好,没有任何问题。如果我再次重新运行相同的剧本,它将尝试再次重新安装此实用程序。

在这种情况下,如何在 Ansible playbook 中使用命令或 shell 运行一次。我已经以某种方式处理它不使用“何时”选项运行安装,但需要更好的逻辑/实现指导

任务信息:

- name: Install SASS packages by using npm utility.
  command: /usr/bin/npm install -g sass

为了消除在 Ansible playbook 中重新运行上述命令任务,我使用了以下验证逻辑并添加了如下所示的“何时”选项。这很好还是我们有更好的方法来处理这个问题?

- name: Validation of SASS packages availability.
  shell: /usr/local/bin/sass --version
  register: result
- debug:
    msg: "{{ result.stdout }}"

- name: Install SASS packages by using npm utility.
  command: /usr/bin/npm install -g sass
  when: "'No such file or directory' in result.stdout"

结果:

TASK [mean-stack : Validation of SASS packages availability.] ************************************************************************************
changed: [linuxosdev003.local.lab]

TASK [mean-stack : debug] ************************************************************************************************************************
ok: [linuxosdev003.local.lab] => {
    "msg": "1.47.0 compiled with dart2js 2.15.1"
}

TASK [mean-stack : Install SASS packages by using npm utility.] **********************************************************************************
skipping: [linuxosdev003.local.lab]

PLAY RECAP ***************************************************************************************************************************************
linuxosdev003.local.lab    : ok=6    changed=1    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

【问题讨论】:

标签: sass ansible ansible-facts


【解决方案1】:

如果你想要一个幂等剧本,你应该尽可能避免commandshell。特别是您的示例 - 删除 sass 并尝试您的剧本。它应该失败。检查文件是否存在

- name: "Check, if file exists"
  stat:
    path: "/usr/local/bin/sass"
  register: sass_installed

但是 - 正如已经评论过的 - 使用 ansible 模块来安装 NPM 包,就像使用系统包(packageyumapt)或 Python 模块(使用 pip)一样。该模块也可在 RedHat 最新版本 2.9 中的 https://docs.ansible.com/ansible/2.9/modules/npm_module.html 下使用,并且应该很简单:

- name: "Install NPM package: sass"
  npm:
    name: "sass"

如果你需要安装多个 NPM 包,你可以遍历它们

- name: "Install NPM packages"
  npm:
    name: "{{ item }}"
  loop:
    - "package1"
    - "package2"

【讨论】:

    【解决方案2】:

    正如@β.εηοιτ.βε 和@TRW 已经提到的,使用模块将消除对此类检查的需要。

    但是,如果只是检查路径是否存在那么简单,那么command module 本身可以这样使用:

    - name: Install SASS packages by using npm utility.
      command:
        cmd: /usr/bin/npm install -g sass
        creates: /usr/local/bin/sass
    

    这等于您的when 条件,即当creates 中给出的路径不存在时,命令将运行。

    【讨论】:

      【解决方案3】:

      如果包管理器可用于这些任务,我更喜欢@β.εηοιτ.βε 和@TRW 的解决方案,有时可能需要留在shell 模块上。对于这种情况,我使用与原始问题类似的方法。

      ---
      - hosts: test.example.com
        become: no
        gather_facts: no
      
        tasks:
      
        - name: Gather installed Java version, if there is any
          shell:
            cmd: java -version 2>&1 | head -1 | cut -d '"' -f 2
          register: result
          check_mode: false
          changed_when: false
          failed_when: result.rc != 0 and result.rc != 127
      
        - name: Set default version, if there is no
          set_fact:
            result:
              stdout_lines: "0.0.0_000"
          when: "'command not found' in result.stdout"
          check_mode: false
      
        - name: Report result
          debug:
            msg: "{{ result.stdout_lines }}"
          check_mode: false
      

      如果需要,将根据安装的版本调用安装程序或更新程序来安装或更新到最新版本。

      感谢

      【讨论】:

      • TRW β.εηοιτ.βε seshadri_c 和@U880D 对这个问题的反应很好。尽管我在剧本中得到了使用“何时”的答案/逻辑,但我将坚持使用 npm 模块以提高幂等性。再次感谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-31
      • 1970-01-01
      • 2013-12-09
      • 2014-01-27
      • 2022-01-24
      • 1970-01-01
      相关资源
      最近更新 更多