shellモジュールを使うときは必ず
-
check_mode: no
をつける
システムに変更を伴わないコマンドの場合は
-
changed_when: no
をつける -
failed_when
は実行するコマンドによって適切に設定する
システムに変更を伴うコマンドの場合は
- 実行したいコマンドの前に
test {{ansible_check_mode}} = False &&
をつける -
register: result
をつけてfailed_when: ansible_check_mode==False and result.rc!=0
とする
サンプル
以下は/tmp/tmpディレクトリがなかったら作成するというplaybookをshellモジュールだけで記述した例
- hosts: all
become: yes
tasks:
- name: check directory
shell: test -d /tmp/tmp
register: directory_exist
check_mode: no
failed_when: no
changed_when: no
- name: create directory
shell: "test {{ansible_check_mode}} = False && mkdir /tmp/tmp"
check_mode: no
register: result
failed_when: ansible_check_mode==False and result.rc!=0
when: directory_exist.rc == 1
解説
ansibleのshellモジュールは--checkをつけてdry runを実行するとskippedになってしまい、そのタスクが実行されるかどうかが判定できない。このshellモジュールで--checkだからskipped
はwhenの条件
より前に判定されるためwhenの条件が満たされているのかどうかも分からない。
このshellモジュールで--checkだからskipped
という事象を回避するにはcheck_mode:no
をつけるしかない。なのでまずcheck_mode:no
は必須。
そしてshellモジュールでchech_mode:no
の時の結果だが、これは必ずchenged
になる。cheanged
になってほしいのはシステムに変更が伴うコマンドを実行するときなので、システムに変更が伴わないコマンドの場合はchanged_when: no
をつけて結果をok
にする。
しかし、check_mode:no
にしてしまうと--checkの場合でもコマンドが実行されてしまいシステムに変更が加えらる可能性がある。これではdry runにならない。なのでシステムに変更を伴うコマンドを実行したい場合はコマンドを実行するかどうかをshellモジュールのコマンドの中で判定する。それがtest {{ansible_check_mode}} = False &&
をコマンドの最初につけることだ。check_mode:no
としても--check
で実行した場合はansible_check_mode
はTrue
になるのでdry runの時は以降のコマンドは実行されない。
ただし、このままだと--checkの時はコマンド結果が必ず失敗になるのでfiled_whenで--checkの時は失敗判定しないようにする。