Ansibleではエラーが発生すると処理は中断されます。エラー発生時、block – rescue などでリカバリして処理を続行することが可能ですが、エラー内容を確認するためにログを遡る必要があります。
ログ出力量が少ない場合は問題ないですが、ログが大量の場合は探すのが面倒ですよね。
今回は、エラー発生時に作成される、エラー情報を格納した変数「ansible_failed_task」・「ansible_failed_result」を使用して、ログの最後でエラー情報を確認してみたいと思います。
テスト用のプレイブック
下記はテスト用に作成したプレイブックです。
---
- hosts: all
gather_facts: False
tasks:
- block:
- name: "強制エラー用のタスク"
shell: ls -l /abc
register: result
rescue:
- name: "エラー発生時のリカバリ用のタスク"
shell: whoami
- name: "変数【ansible_failed_task】"
debug:
msg: "{{ ansible_failed_task }}"
- name: "変数【ansible_failed_result】"
debug:
msg: "{{ ansible_failed_result }}"
- name: "変数【result】"
debug:
msg: "{{ result }}"
- name: "エラー情報まとめ"
debug:
msg:
- "【エラータスク名】{{ ansible_failed_task.name }}"
- "【 実行コマンド】{{ ansible_failed_result.cmd }}"
- "【リターンコード】{{ ansible_failed_result.rc }}"
- "【 エラーの内容】{{ ansible_failed_result.stderr }}"
プレイブックの解説ですが、まず「強制エラー用のタスク」で「ls -l /abc」を実行しています。
これは、存在しないディレクトリに[ls]コマンドを実行してエラーを発生させています。
また、register で変数[result]に実行結果を格納しています。
次に「rescue」として、「エラー発生時のリカバリ用のタスク」で「whoami」を実行しています。
処理が rescue に飛んだことを確認したいので、処理内容は何でもいいので、whoami としました。
以降は、各変数に格納された情報を debug – msg で出力しています。
最後に各変数から、エラー情報をまとめたタスクを入れてみました。
実行結果
テスト用のプレイブックを実行した結果をタスクごとに確認してみたいと思います。
まずは、「強制エラー用のタスク」になります。
存在しないディレクトリに[ls]コマンドを実行したので、「No such file or directory」が出力されていますね。
TASK [強制エラー用のタスク] ************************************************************** fatal: [192.168.56.105]: FAILED! => {"changed": true, "cmd": "ls -l /abc", "delta": "0:00:00.005005", "end": "2022-05-21 03:31:42.830922", "msg": "non-zero return code", "rc": 2, "start": "2022-05-21 03:31:42.825917", "stderr": "ls: cannot access '/abc': No such file or directory", "stderr_lines": ["ls: cannot access '/abc': No such file or directory"], "stdout": "", "stdout_lines": []}
次に、「エラー発生時のリカバリ用のタスク」です。
「rescue」に入り、「whoami」が実行されていることが確認できます。
TASK [エラー発生時のリカバリ用のタスク] ******************************************************** changed: [192.168.56.105] => {"changed": true, "cmd": "whoami", "delta": "0:00:00.003319", "end": "2022-05-21 03:31:43.277000", "rc": 0, "start": "2022-05-21 03:31:43.273681", "stderr": "", "stderr_lines": [], "stdout": "awx", "stdout_lines": ["awx"]}
ここから、エラー情報が格納された各変数を確認していきます。
まずは、「ansible_failed_task」です。
かなり様々な情報が格納されていますが、有用な情報は「name」とかですかね。
TASK [変数【ansible_failed_task】] ************************************************* ok: [192.168.56.105] => { "msg": { "action": "command", "any_errors_fatal": false, "args": { "_raw_params": "ls -l /abc", "_uses_shell": true, "warn": true }, "async": 0, "async_val": 0, "become": false, "become_exe": null, "become_flags": null, "become_method": "sudo", "become_user": null, "changed_when": [], "check_mode": false, "collections": [], "connection": "smart", "debugger": null, "delay": 5, "delegate_facts": null, "delegate_to": null, "diff": false, "environment": [ {} ], "failed_when": [], "finalized": false, "ignore_errors": null, "ignore_unreachable": null, "loop": null, "loop_control": null, "loop_with": null, "module_defaults": [], "name": "強制エラー用のタスク", "no_log": null, "notify": null, "parent": { "any_errors_fatal": false, "become": false, "become_exe": null, "become_flags": null, "become_method": "sudo", "become_user": null, "check_mode": false, "collections": [], "connection": "smart", "debugger": null, "delegate_facts": null, "delegate_to": null, "dep_chain": null, "diff": false, "environment": null, "eor": false, "ignore_errors": null, "ignore_unreachable": null, "module_defaults": null, "name": "", "no_log": null, "port": null, "remote_user": "awx", "run_once": null, "tags": [], "throttle": 0, "vars": {}, "when": [] }, "parent_type": "Block", "poll": 15, "port": null, "register": "result", "remote_user": "awx", "retries": 3, "run_once": null, "squashed": false, "tags": [], "throttle": 0, "until": [], "uuid": "0242ac14-0004-b579-def7-000000000008", "vars": {}, "when": [] } }
「ansible_failed_result」も見てみます。
こちらは「cmd」、「rc」、「stderr」があれば解析に役立ちそうです。
TASK [変数【ansible_failed_result】] *********************************************** ok: [192.168.56.105] => { "msg": { "changed": true, "cmd": "ls -l /abc", "delta": "0:00:00.005005", "end": "2022-05-21 03:31:42.830922", "failed": true, "invocation": { "module_args": { "_raw_params": "ls -l /abc", "_uses_shell": true, "argv": null, "chdir": null, "creates": null, "executable": null, "removes": null, "stdin": null, "stdin_add_newline": true, "strip_empty_ends": true, "warn": true } }, "msg": "non-zero return code", "rc": 2, "start": "2022-05-21 03:31:42.825917", "stderr": "ls: cannot access '/abc': No such file or directory", "stderr_lines": [ "ls: cannot access '/abc': No such file or directory" ], "stdout": "", "stdout_lines": [] } }
「result」です。
こちらは「ansible_failed_result」と「invocation」以外は同じ内容ですね。
なので、「ansible_failed_result」を使用することで、各タスクに register の記述を省略することが出来ますね。
TASK [変数【result】] ************************************************************** ok: [192.168.56.105] => { "msg": { "changed": true, "cmd": "ls -l /abc", "delta": "0:00:00.005005", "end": "2022-05-21 03:31:42.830922", "failed": true, "msg": "non-zero return code", "rc": 2, "start": "2022-05-21 03:31:42.825917", "stderr": "ls: cannot access '/abc': No such file or directory", "stderr_lines": [ "ls: cannot access '/abc': No such file or directory" ], "stdout": "", "stdout_lines": [] } }
「エラー情報まとめ」の実行結果です。
必要な情報をまとめておくことで、かなり見やすくなりました。
TASK [エラー情報まとめ] **************************************************************** ok: [192.168.56.105] => { "msg": [ "【エラータスク名】強制エラー用のタスク", "【 実行コマンド】ls -l /abc", "【リターンコード】2", "【 エラーの内容】ls: cannot access '/abc': No such file or directory" ] }
記事は以上です。
「rescue」を使用すると、「failed」が「rescue」となり、正常終了として扱われます。
その際、「failed」が発生していた情報を確認する場合に有用だと思いますので是非ご活用頂ければと思います。
コメント