LoginSignup
6

More than 5 years have passed since last update.

AnsibleのScriptモジュールで冪等性をいい感じに担保したい

Last updated at Posted at 2017-04-24

はじめに

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を作成することで実現できます。

mkhoge.sh
#!/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
mkhoge.yml
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しか使ったことないですし、
便利な記述を見つけることができたらまたまとめたいと思います。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6