Ansible Documentation
Blocks error handling通常のタスクの動作
block 内のタスクが失敗した場合、その対象ホストの play の実行はその時点で終了します。動作確認用の play です。block内の 2 つ目のタスクで shell モジュールを使用して diff コマンドを実行します。ファイルの内容は対象ホスト node-c0706 は異なり、node-u1804 は同じです。--- - hosts: all gather_facts: no tasks: - name: block 内でエラーが発生する例 block: - name: 1 つ目のタスク debug: msg: "1 つ目" - name: 2 つ目のタスク shell: diff ~/file-a ~/file-b - name: 3 つ目のタスク debug: msg: "3 つ目" - name: block の外のタスク debug: msg: "block の外"ファイルの内容が異なる node-c0706 は 2 つ目のタスクでしてエラーが発生し、それ以降のタスクは実行されません。ファイルの内容が同じ node-u1804 はエラーが発生せず、すべてのタスクが実行されました。
ansibleman@ubuntu-pc:~/ansible/block$ ansible-playbook -i hosts.yml site.yml
PLAY [all] *********************************************************************************************************
TASK [1 つ目のタスク] ****************************************************************************************************
ok: [node-c0706] => {
"msg": "1 つ目"
}
ok: [node-u1804] => {
"msg": "1 つ目"
}
TASK [2 つ目のタスク] ****************************************************************************************************
changed: [node-u1804]
fatal: [node-c0706]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "cmd": "diff ~/file-a ~/file-b", "delta": "0:00:00.008303", "end": "2019-05-26 19:45:33.416847", "msg": "non-zero return code", "rc": 1, "start": "2019-05-26 19:45:33.408544", "stderr": "", "stderr_lines": [], "stdout": "1c1\n< abc\n---\n> xyz", "stdout_lines": ["1c1", "< abc", "---", "> xyz"]}
TASK [3 つ目のタスク] ****************************************************************************************************
ok: [node-u1804] => {
"msg": "3 つ目"
}
TASK [block の外のタスク] ************************************************************************************************
ok: [node-u1804] => {
"msg": "block の外"
}
PLAY RECAP *********************************************************************************************************
node-c0706 : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
node-u1804 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ansibleman@ubuntu-pc:~/ansible/block$
rescue
rescue を使用して block 内のタスクでエラーが発生した場合に実行するタスクを定義します。rescue 内のタスクが実行されるのは、block 内のすべてのタスクの実行が終了した後になります。--- - hosts: all gather_facts: no tasks: - name: block 内でエラーが発生する例 block: - name: 1 つ目のタスク debug: msg: "1 つ目" - name: 2 つ目のタスク shell: diff ~/file-a ~/file-b - name: 3 つ目のタスク debug: msg: "3 つ目" rescue: - name: block 内でエラーが発生したときの処理 debug: msg: "ファイルの内容が異なります" - name: block の外のタスク debug: msg: "block の外"node-u1804 はエラーが発生していないので rescue で定義したタスク以外はすべて実行されました。node-c0706 は block 内の 2 つ目のタスクでエラーが発生したので block 内のタスクの実行を中断し rescue 内で定義したタスクを実行しました。rescue 内のタスクを実行した後はエラーがなかったように block の外のタスクを実行しています。RECAP でも failed はカウントされず、rescued がカウントされました。
ansibleman@ubuntu-pc:~/ansible/block$ ansible-playbook -i hosts.yml site.yml
PLAY [all] *********************************************************************************************************
TASK [1 つ目のタスク] ****************************************************************************************************
ok: [node-c0706] => {
"msg": "1 つ目"
}
ok: [node-u1804] => {
"msg": "1 つ目"
}
TASK [2 つ目のタスク] ****************************************************************************************************
fatal: [node-c0706]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "cmd": "diff ~/file-a ~/file-b", "delta": "0:00:00.006554", "end": "2019-05-26 19:58:34.499283", "msg": "non-zero return code", "rc": 1, "start": "2019-05-26 19:58:34.492729", "stderr": "", "stderr_lines": [], "stdout": "1c1\n< abc\n---\n> xyz", "stdout_lines": ["1c1", "< abc", "---", "> xyz"]}
changed: [node-u1804]
TASK [3 つ目のタスク] ****************************************************************************************************
ok: [node-u1804] => {
"msg": "3 つ目"
}
TASK [block 内でエラーが発生したときの処理] ***************************************************************************************
ok: [node-c0706] => {
"msg": "ファイルの内容が異なります"
}
TASK [block の外のタスク] ************************************************************************************************
ok: [node-c0706] => {
"msg": "block の外"
}
ok: [node-u1804] => {
"msg": "block の外"
}
PLAY RECAP *********************************************************************************************************
node-c0706 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=1 ignored=0
node-u1804 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ansibleman@ubuntu-pc:~/ansible/block$
rescue 内で次の 2 つの変数を使用して、rescue が呼ばれた原因を確認できます。
- ansible_failed_task
- rescue を呼び出すトリガーになったタスクの情報
- ansible_failed_result
- rescue を呼び出すトリガーになったタスクの実行結果(register 変数で取得できる内容と同じ)
--- - hosts: all gather_facts: no tasks: - name: block 内でエラーが発生する例 block: - name: 1 つ目のタスク debug: msg: "1 つ目" - name: 2 つ目のタスク shell: diff ~/file-a ~/file-b - name: 3 つ目のタスク debug: msg: "3 つ目" rescue: - name: block 内でエラーが発生したときの処理 debug: msg: "ファイルの内容が異なります" - name: ansible_failed_task の値 debug: var: ansible_failed_task - name: ansible_failed_result の値 debug: var: ansible_failed_result - name: block の外のタスク debug: msg: "block の外"実行結果です。rescue を呼び出すトリガーになったタスクは ansible_failed_task.name で確認できます。
ansibleman@ubuntu-pc:~/ansible/block$ ansible-playbook -i hosts.yml site.yml
PLAY [all] *********************************************************************************************************
TASK [1 つ目のタスク] ****************************************************************************************************
ok: [node-c0706] => {
"msg": "1 つ目"
}
ok: [node-u1804] => {
"msg": "1 つ目"
}
TASK [2 つ目のタスク] ****************************************************************************************************
fatal: [node-c0706]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "cmd": "diff ~/file-a ~/file-b", "delta": "0:00:00.006094", "end": "2019-05-26 20:17:47.858342", "msg": "non-zero return code", "rc": 1, "start": "2019-05-26 20:17:47.852248", "stderr": "", "stderr_lines": [], "stdout": "1c1\n< abc\n---\n> xyz", "stdout_lines": ["1c1", "< abc", "---", "> xyz"]}
changed: [node-u1804]
TASK [3 つ目のタスク] ****************************************************************************************************
ok: [node-u1804] => {
"msg": "3 つ目"
}
TASK [block 内でエラーが発生したときの処理] ***************************************************************************************
ok: [node-c0706] => {
"msg": "ファイルの内容が異なります"
}
TASK [ansible_failed_task の値] **************************************************************************************
ok: [node-c0706] => {
"ansible_failed_task": {
"action": "command",
"any_errors_fatal": false,
"args": {
"_raw_params": "diff ~/file-a ~/file-b",
"_uses_shell": true,
"warn": true
},
"async": 0,
"async_val": 0,
"become": false,
"become_flags": null,
"become_method": "sudo",
"become_user": null,
"changed_when": [],
"check_mode": false,
"collections": null,
"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": "2 つ目のタスク",
"no_log": null,
"notify": null,
"parent": {
"any_errors_fatal": false,
"become": false,
"become_flags": null,
"become_method": "sudo",
"become_user": null,
"check_mode": false,
"collections": null,
"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": "block 内でエラーが発生する例",
"no_log": null,
"port": null,
"remote_user": null,
"run_once": null,
"tags": [],
"vars": {},
"when": []
},
"parent_type": "Block",
"poll": 10,
"port": null,
"register": null,
"remote_user": null,
"retries": 3,
"run_once": null,
"squashed": false,
"tags": [],
"until": [],
"uuid": "0050562c-70da-6765-eb0d-00000000000a",
"vars": {},
"when": []
}
}
TASK [ansible_failed_result の値] ************************************************************************************
ok: [node-c0706] => {
"ansible_failed_result": {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"cmd": "diff ~/file-a ~/file-b",
"delta": "0:00:00.006094",
"end": "2019-05-26 20:17:47.858342",
"failed": true,
"invocation": {
"module_args": {
"_raw_params": "diff ~/file-a ~/file-b",
"_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": 1,
"start": "2019-05-26 20:17:47.852248",
"stderr": "",
"stderr_lines": [],
"stdout": "1c1\n< abc\n---\n> xyz",
"stdout_lines": [
"1c1",
"< abc",
"---",
"> xyz"
]
}
}
TASK [block の外のタスク] ************************************************************************************************
ok: [node-c0706] => {
"msg": "block の外"
}
ok: [node-u1804] => {
"msg": "block の外"
}
PLAY RECAP *********************************************************************************************************
node-c0706 : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=1 ignored=0
node-u1804 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ansibleman@ubuntu-pc:~/ansible/block$
参考までに node-c0706 および node-u1804 で、file-a と file-b を同じ内容にした例です。
--- - hosts: all gather_facts: no tasks: - name: block 内でエラーが発生する例 block: - name: 1 つ目のタスク debug: msg: "1 つ目" - name: 2 つ目のタスク shell: diff ~/file-a ~/file-b - name: 3 つ目のタスク debug: msg: "3 つ目" rescue: - name: block 内でエラーが発生したときの処理 debug: msg: "ファイルの内容が異なります" - name: block の外のタスク debug: msg: "block の外"block 内でエラーが発生していないので rescue で定義したタスクは実行されません。
ansibleman@ubuntu-pc:~/ansible/block$ ansible-playbook -i hosts.yml site.yml
PLAY [all] *********************************************************************************************************
TASK [1 つ目のタスク] ****************************************************************************************************
ok: [node-c0706] => {
"msg": "1 つ目"
}
ok: [node-u1804] => {
"msg": "1 つ目"
}
TASK [2 つ目のタスク] ****************************************************************************************************
changed: [node-c0706]
changed: [node-u1804]
TASK [3 つ目のタスク] ****************************************************************************************************
ok: [node-c0706] => {
"msg": "3 つ目"
}
ok: [node-u1804] => {
"msg": "3 つ目"
}
TASK [block の外のタスク] ************************************************************************************************
ok: [node-c0706] => {
"msg": "block の外"
}
ok: [node-u1804] => {
"msg": "block の外"
}
PLAY RECAP *********************************************************************************************************
node-c0706 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node-u1804 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ansibleman@ubuntu-pc:~/ansible/block$
always
always を使用して block 内のタスクの状況(成功 / 失敗)に関わらず実行するタスクを定義します。always 内のタスクが実行されるのは、block 内のすべてのタスクの実行が終了した後になります。--- - hosts: all gather_facts: no tasks: - name: block 内でエラーが発生する例 block: - name: 1 つ目のタスク debug: msg: "1 つ目" - name: 2 つ目のタスク shell: diff ~/file-a ~/file-b - name: 3 つ目のタスク debug: msg: "3 つ目" always: - name: block 内の状況に関係なく実行するタスク debug: msg: "必ず実行されるタスク" - name: block の外のタスク debug: msg: "block の外"node-u1804 は block 内でエラーが発生していないので、block内 / always 内 / blockの外のすべてのタスクを実行しています。node-c0706 は block 内の 2 つ目のタスクの実行でエラーが発生したため、always 内のタスクを実行した後に終了しています。
ansibleman@ubuntu-pc:~/ansible/block$ ansible-playbook -i hosts.yml site.yml
PLAY [all] *********************************************************************************************************
TASK [1 つ目のタスク] ****************************************************************************************************
ok: [node-c0706] => {
"msg": "1 つ目"
}
ok: [node-u1804] => {
"msg": "1 つ目"
}
TASK [2 つ目のタスク] ****************************************************************************************************
fatal: [node-c0706]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "cmd": "diff ~/file-a ~/file-b", "delta": "0:00:00.006702", "end": "2019-05-26 21:06:40.921524", "msg": "non-zero return code", "rc": 1, "start": "2019-05-26 21:06:40.914822", "stderr": "", "stderr_lines": [], "stdout": "1c1\n< abc\n---\n> xyz", "stdout_lines": ["1c1", "< abc", "---", "> xyz"]}
changed: [node-u1804]
TASK [3 つ目のタスク] ****************************************************************************************************
ok: [node-u1804] => {
"msg": "3 つ目"
}
TASK [block 内の状況に関係なく実行するタスク] **************************************************************************************
ok: [node-c0706] => {
"msg": "必ず実行されるタスク"
}
ok: [node-u1804] => {
"msg": "必ず実行されるタスク"
}
TASK [block の外のタスク] ************************************************************************************************
ok: [node-u1804] => {
"msg": "block の外"
}
PLAY RECAP *********************************************************************************************************
node-c0706 : ok=2 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
node-u1804 : ok=5 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ansibleman@ubuntu-pc:~/ansible/block$
rescue と always
rescue と always は併用できます。--- - hosts: all gather_facts: no tasks: - name: block 内でエラーが発生する例 block: - name: 1 つ目のタスク debug: msg: "1 つ目" - name: 2 つ目のタスク shell: diff ~/file-a ~/file-b - name: 3 つ目のタスク debug: msg: "3 つ目" always: - name: block 内の状況に関係なく実行するタスク debug: msg: "必ず実行されるタスク" rescue: - name: block 内でエラーが発生したときの処理 debug: msg: "ファイルの内容が異なります" - name: block の外のタスク debug: msg: "block の外"実行結果です。block 内のタスク → rescue 内のタスク → always 内のタスク の順に実行されています。
ansibleman@ubuntu-pc:~/ansible/block$ ansible-playbook -i hosts.yml site.yml
PLAY [all] *********************************************************************************************************
TASK [1 つ目のタスク] ****************************************************************************************************
ok: [node-c0706] => {
"msg": "1 つ目"
}
ok: [node-u1804] => {
"msg": "1 つ目"
}
TASK [2 つ目のタスク] ****************************************************************************************************
fatal: [node-c0706]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "cmd": "diff ~/file-a ~/file-b", "delta": "0:00:00.006588", "end": "2019-05-26 21:22:59.901297", "msg": "non-zero return code", "rc": 1, "start": "2019-05-26 21:22:59.894709", "stderr": "", "stderr_lines": [], "stdout": "1c1\n< abc\n---\n> xyz", "stdout_lines": ["1c1", "< abc", "---", "> xyz"]}
changed: [node-u1804]
TASK [3 つ目のタスク] ****************************************************************************************************
ok: [node-u1804] => {
"msg": "3 つ目"
}
TASK [block 内でエラーが発生したときの処理] ***************************************************************************************
ok: [node-c0706] => {
"msg": "ファイルの内容が異なります"
}
TASK [block 内の状況に関係なく実行するタスク] **************************************************************************************
ok: [node-c0706] => {
"msg": "必ず実行されるタスク"
}
ok: [node-u1804] => {
"msg": "必ず実行されるタスク"
}
TASK [block の外のタスク] ************************************************************************************************
ok: [node-c0706] => {
"msg": "block の外"
}
ok: [node-u1804] => {
"msg": "block の外"
}
PLAY RECAP *********************************************************************************************************
node-c0706 : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=1 ignored=0
node-u1804 : ok=5 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ansibleman@ubuntu-pc:~/ansible/block$