使用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。