概要
なにかのモジュールでエラーが発生する際にそのエラーハンドリングとしてignore_errors
を利用することがある(エラーを無視して、次の処理で戻り値を基に処理分岐するような実装)と思いますが、以下のようにモジュールの実行時エラーがスルーされる場合もあるので、追加の確認処理を設けるとより安全になるかと思います。
コード
以下ではdebugモジュールのパラメータmsg
をmsgs
にし、あえて実行時エラーを発生させます。
後続のassert
は説明が簡単になるように簡単なアサーション条件になっています。
- name: Sample
hosts: localhost
connection: local
tasks:
- ansible.builtin.debug:
msgs: "test"
ignore_errors: yes
register: _result_debug
- ansible.builtin.debug:
msg="{{ _result_debug }}"
- ansible.builtin.assert:
that:
- not _result_debug.changed
実行ログ
以下のようにfailed=0
で処理が通過します。
後続処理の実装によっては問題ないが、サンプルコードのように実行時エラーを見抜けない場合があります。
TASK [Gathering Facts] **********************************
Wednesday 08 December 2021 22:37:30 +0900 (0:00:00.027) 0:00:00.027 ****
ok: [localhost]
TASK [ansible.builtin.debug] **********************************
Wednesday 08 December 2021 22:37:31 +0900 (0:00:00.521) 0:00:00.549 ****
fatal: [localhost]: FAILED! => {"msg": "Invalid options for ansible.builtin.debug: msg2"}
...ignoring
TASK [debug] **********************************
Wednesday 08 December 2021 22:37:31 +0900 (0:00:00.020) 0:00:00.569 ****
ok: [localhost] => {
"msg": {
"changed": false,
"failed": true,
"msg": "Invalid options for ansible.builtin.debug: msg2"
}
}
TASK [ansible.builtin.assert] **********************************
Wednesday 08 December 2021 22:37:31 +0900 (0:00:00.031) 0:00:00.601 ****
ok: [localhost] => {
"changed": false,
"msg": "All assertions passed"
}
PLAY RECAP **********************************
localhost: ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
実行時エラーを防ぐには
ignore_errors
の直後にnot _result_debug.failed
を確認することで防ぐことができます。
ちなみにassert
モジュールの公式ドキュメントではfail_msg
パラメータは文字列のみと書いていたが、実際は配列でも定義できます。また、必ず文字列に変換するようにstring
フィルタも忘れずに。
- name: Sample
hosts: localhost
connection: local
tasks:
- ansible.builtin.debug:
msg2: "test"
ignore_errors: yes
register: _result_debug
- debug:
msg="{{ _result_debug }}"
- ansible.builtin.assert:
that:
- not _result_debug.failed
fail_msg:
- "{{ _result_debug | string }}"
- ansible.builtin.assert:
that:
- not _result_debug.changed
実行ログ
追加したassert
で実行時エラーをブロックしてくれてます。
TASK [Gathering Facts] **********************************
Wednesday 08 December 2021 22:56:10 +0900 (0:00:00.027) 0:00:00.027 ****
ok: [localhost]
TASK [ansible.builtin.debug] **********************************
Wednesday 08 December 2021 22:56:10 +0900 (0:00:00.512) 0:00:00.539 ****
fatal: [localhost]: FAILED! => {"msg": "Invalid options for ansible.builtin.debug: msg2"}
...ignoring
TASK [debug] **********************************
Wednesday 08 December 2021 22:56:11 +0900 (0:00:00.020) 0:00:00.559 ****
ok: [localhost] => {
"msg": {
"changed": false,
"failed": true,
"msg": "Invalid options for ansible.builtin.debug: msg2"
}
}
TASK [ansible.builtin.assert] **********************************
Wednesday 08 December 2021 22:56:11 +0900 (0:00:00.030) 0:00:00.590 ****
fatal: [localhost]: FAILED! => {
"assertion": "not _result_debug.failed",
"changed": false,
"evaluated_to": false,
"msg": [
"{'failed': True, 'msg': 'Invalid options for ansible.builtin.debug: msg2', 'changed': False}"
]
}
PLAY RECAP **********************************
localhost: ok=3 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=1
ちなみに公式ドキュメントでも同じようなことが書かれています。
失敗したコマンドの無視
通常、Playbook はタスクが失敗したホストでこれ以上のステップの実行を停止します。 ただし、場合によっては、次に進みます。 これを行うには、以下のようなタスクを作成します。
name: this will not be counted as a failure command: /bin/false ignore_errors: yes
上記のシステムは、特定のタスクの障害の戻り値のみを管理することに注意してください。 したがって、未定義の変数が使用されているか、構文エラーが発生した場合は、ユーザーがアドレスを指定することが必要になるエラーが出力されます。 接続または実行の問題の失敗を防ぐ訳ではないことに注意してください。 この機能は、タスクを実行でき、「faileded」の値を返す必要がある場合にのみ機能します