使用Ansible的shell模块时,要考虑检查模式并保持幂等性:改进

我之前尝试在shell模块中使用以下方式,在文件不存在时执行,并在文件存在时显示”ok”,同时在检查模式下执行时能以”changed”或”ok”等方式展示。

    Ansible の shell モジュールでチェックモードも考慮する – Qiita

如果使用最新版本的 Ansible(2.1以上),可以通过ansible_check_mode魔术变量来判断是否在检查模式下运行,因此可以更简洁地实现如下:

- hosts: localhost
  tasks:
    - name: create hoge
      shell: |
        # ファイルが存在するなら ok を標準出力に出して終了
        if [ -e /tmp/hoge ]; then
          echo ok
          exit
        fi

        # チェックモードなら何もしない
        if [ "$ansible_check_mode" -ne 0 ]; then
          exit
        fi

        # 実際の処理
        uname -a > /tmp/hoge

      environment:
        # ansible_check_mode を環境変数で渡す
        ansible_check_mode: '{{ ansible_check_mode|int }}'
      register: res
      # チェックモードでも実行する
      check_mode: no
      # 標準出力が ok なら変更なしとみなす
      changed_when: res.stdout != 'ok'

这个例子太简单了,基本上不需要使用 shell 模块吧?虽然是为了示例而准备的,但是希望大家能理解这其实是只能通过更多的 shell 模块来实现的事情……比如,通过检查 make -q 的退出代码来判断是否需要执行?

---
- hosts: localhost
  tasks:
    - name: make hoge
      shell: |
        make -q
        if [ $? -ne 1 ]; then
          # 終了コードが 1 以外ならビルド不要かエラーのどっちか
          exit $?
        fi
        if [ "$ansible_check_mode" -eq 0 ]; then
          if ! make; then
            exit 2
          fi
        fi
        exit 1
      environment:
        ansible_check_mode: '{{ ansible_check_mode|int }}'
      register: res
      check_mode: no
      changed_when: res.rc == 1
      failed_when: not res.rc in (0, 1)

无论是在检查模式下还是不是,如果需要进行构建,它将变为changed,如果不需要,它将变为ok。

广告
将在 10 秒后关闭
bannerAds