問題
対象ホスト上でのコマンド実行結果により処理を変更させるには、shellなどでignore_errors: trueとしてコマンドを実行させ、制御対象モジュールにて、whenを用いて実行可否を決める対応が可能だが、
- shell: ls -d /tmp/abc # コマンド実行
register: file_ck # 実行結果保存
ignore_errors: true # コマンドがエラーであってもansible処理を継続させる
- debug: msg="ファイルなし"
when: file_ck is failed # 上のコマンド実行結果がfailedならば実行
- debug: msg="ファイルあり"
when: file_ck is success # 上のコマンド実行結果がsuccessならば実行
しかしこの場合、コマンド実行結果がfailedのケースでは、(意図通りではあるが、)出力がfatal:となり、Ansibleとしての実行が失敗した様にも見えてしまう。
TASK [shell] *****************************************************************************
fatal: [ansiblepush-centos-7]: FAILED! => {"changed": true, "cmd": "ls -d /tmp/abc", "delta": "0:00:00.004833", "end": "2018-11-07 03:13:54.603112", "msg": "non-zero return code", "rc": 2, "start": "2018-11-07 03:13:54.598279", "stderr": "ls: /tmp/abc にアクセスできません: そのようなファイルやディレクトリはありません", "stderr_lines": ["ls: /tmp/abc にアクセスできません: そのようなファイルやディレクトリはありません"], "stdout": "", "stdout_lines": []}
...ignoring
TASK [debug] *****************************************************************************
ok: [ansiblepush-centos-7] => {
"msg": "ファイルなし"
}
TASK [debug] *****************************************************************************
skipping: [ansiblepush-centos-7]
解決
この様な表示を防ぐには、failed_when: falseとして常にsuccessと認識させ、判定はシンプルにrcで確認すれば良い。
- shell: ls -d /tmp/abc
register: file_ck
failed_when: false # 常にsuccessと認識させる。rcなどの属性は変更しない。
# - debug: var=file_ck # file_ckの内容詳細を表示するにはコメントイン
- debug: msg="ファイルなし"
when: file_ck.rc != 0 # failedとはならないので、file_ck is failed では識別できない。
- debug: msg="ファイルあり"
when: file_ck.rc == 0
TASK [shell] *****************************************************************************
changed: [ansiblepush-centos-7]
TASK [debug] *****************************************************************************
ok: [ansiblepush-centos-7] => {
"msg": "ファイルなし"
}
TASK [debug] *****************************************************************************
skipping: [ansiblepush-centos-7]
補足
なお、shellなどを使用した状況確認時には、changedとしてカウントされる。
shellなどによる実行内容が変更を行わないことが明らかならば、合わせてchanged_when: falseをつけてchangedとカウントさせない様にしておけば良いでしょう。
- shell: ls -d /tmp/abc
register: file_ck
failed_when: false
changed_when: false # これでchangedとカウントされない
- debug: msg="ファイルなし"
when: file_ck.rc != 0
- debug: msg="ファイルあり"
when: file_ck.rc == 0
TASK [shell] *****************************************************************************
ok: [ansiblepush-centos-7] # changed:から変更されている
TASK [debug] *****************************************************************************
ok: [ansiblepush-centos-7] => {
"msg": "ファイルなし"
}
TASK [debug] *****************************************************************************
skipping: [ansiblepush-centos-7]
追記
- もう少し頑張ってみる例
- Ansible: shellモジュールに冪等性および正しいchanged結果を持たせる為のロジック例
- https://qiita.com/hiroyuki_onodera/items/e2cf26d02f5bda85cd4d