はじめに
Ansibleの次のようなモジュールは冪等性を担保してくれません。
毎回毎回実行し、ステータスはchangedになってしまいます。
- command
- shell
- script
そこで、よくある冪等性の担保として事前に状態を確認するタスクを用意し、
その結果に応じてskipするか実行するかを判断するものです。
こんなやつ↓
tasks:
- name: check hoge file
command: ls /tmp/hoge
register: result
changed_when: false
always_run: yes
- name: make hoge file
command: touch /tmp/hoge
when: result.rc != 0
Ansibleでは、基本的にモジュール側で冪等性を担保するため、
Playbookでの条件分岐は単純なものしかできず、複雑な条件分岐は難しいと思っています。
commandモジュールやshellモジュールだけで解決できるような処理ならいいですが、
複雑なことをやらせようとするとPlaybookがどんどん長くなってしまいます。
解決方法
そこで、シェルスクリプトに冪等性を担保させ、Ansibleには実行と、終了時の結果確認のみをさせるようにします。
以下のようにシェルスクリプトとPlaybookを作成することで実現できます。
#!/bin/bash
changed="no"
if [ -f /tmp/hoge ]; then
touch /tmp/hoge
changed="yes"
fi
if [ $changed == "yes" ]; then
exit 254
else
exit 0
fi
tasks:
- name: make hoge file
script: mkhoge.sh
register: result
changed_when: result.rc == 254
failed_when: result.rc not in [0, 254]
registerでスクリプトの終了コードを取得し、
- 0 -> ok
- 254 -> changed
- それ以外 -> failed
という動作になります。
おわりに
今回の内容が使えるのは
- 標準モジュールで実現できない
- 変数が不要な決まった処理
- 実行判断の条件分岐が複雑または多い
といったパターンの処理をさせたい場合ですので、あまり使う機会はないかな?と思います。
ただ、今までシェルスクリプトを使ってきていてそれを有効活用したいとかであれば有用かと思います。
registerとかchanged_when, failed_whenでの条件分岐だったり、with_itemsでのループだったり、
結構できることはあるものの知らないことがまだまだありそうです。
with_****系とかたくさんあるようですが、with_itemsしか使ったことないですし、
便利な記述を見つけることができたらまたまとめたいと思います。