■ はじめに
Ansible 2.7 で、ターゲットホストに到達不能の状態を無視する ignore_unreachable キーワードが追加されました。
New keyword ignore_unreachable for plays and blocks. Allows ignoring tasks that fail due to unreachable hosts, and check results with is unreachable test.
言葉では少し説明しにくいので、試した結果を紹介します。
■ 構成
以下のように、 Ansibleから到達できるホストとできないホストを想定して試します。
| ホスト | OS | Ansible からの到達性 |
|---|---|---|
| testsv1 | linux | ○:可 |
| testsv99 | linux | ×:不可 |
■ 基本 Playbook
2つのタスクがあり、1つめの yum モジュールでは、あえて存在しないパッケージ名を指定して エラーが発生するようにしてます。
- hosts: linux gather_facts: no tasks: - name: yum error yum: name: invalid_package_xxx # エラー - name: debug debug: msg: "Hello debug."
この Playook を基本として、ignore_unreachable を指定を変えて試してみます。
■ ignore_unreachable: no(デフォルト)の場合
- Playbook
- hosts: linux gather_facts: no tasks: - name: yum error yum: name: invalid_package_xxx # エラー ignore_unreachable: no # デフォルト - name: debug debug: msg: "Hello debug."
- 実行結果
$ ansible-playbook -i inventory iu_linux.yml
PLAY [linux] ********************************************************************
TASK [yum error] ****************************************************************
fatal: [testsv1]: FAILED! => {"ansible_facts": {"pkg_mgr": "yum"}, "changed": false, "msg": "No package matching 'invalid_package_xxx' found available, installedor updated", "rc": 126, "results": ["No package matching 'invalid_package_xxx' found available, installed or updated"]}
fatal: [testsv99]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 172.16.0.11 port 22: No route to host\r\n", "unreachable": true}
to retry, use: --limit @/vagrant/a27/iu_linux.retry
PLAY RECAP **********************************************************************
testsv1 : ok=0 changed=0 unreachable=0 failed=1
testsv99 : ok=0 changed=0 unreachable=1 failed=0
testsv1 では、1つめの yum モジュールのタスクでエラーが発生したためしたが、処理が中断されます。
一方、testsv99 では、1つめのタスクの時点で unreachable なので、処理が中断されます。
これがデフォルトの動作です。
このように、2つめのタスクが実行されなかった点では testsv1 も teest99 も同じですが、理由が異なります。
■ ignore_unreachable: yes の場合
次に、ignore_unreachable: yes に変更した Playbook を用意します、
- Playbook
- hosts: linux gather_facts: no tasks: - name: yum error yum: name: invalid_package_xxx # エラー ignore_unreachable: yes # point - name: debug debug: msg: "Hello debug."
- 実行結果
$ ansible-playbook -i inventory iu_linux.yml
PLAY [linux] ********************************************************************
TASK [yum error] ****************************************************************
fatal: [testsv99]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 172.16.0.11 port 22: No route to host\r\n", "skip_reason": "Host testsv99 is unreachable", "unreachable": true}
fatal: [testsv1]: FAILED! => {"ansible_facts": {"pkg_mgr": "yum"}, "changed": false, "msg": "No package matching 'invalid_package_xxx' found available, installedor updated", "rc": 126, "results": ["No package matching 'invalid_package_xxx' found available, installed or updated"]}
TASK [debug] ********************************************************************
ok: [testsv99] => {
"msg": "Hello debug."
}
to retry, use: --limit @/vagrant/a27/iu_linux.retry
PLAY RECAP **********************************************************************
testsv1 : ok=0 changed=0 unreachable=0 failed=1
testsv99 : ok=1 changed=0 unreachable=1 failed=0
先ほどと異なる点は、2つめの dubug モジュールのタスクが実行されるかどうかです。
testsv1 では、1つめの yum モジュールのタスクでエラーが発生したためしたが、処理が中断されます。
一方、testsv99 では、1つめのタスクの時点で unreachable です。ただし、ignore_unreachable: yes が指定されているので、2つめの debug モジュールのタスクが実行されました。
■ おまけ ignore_errors: yes の場合
比較をするため、Ansible 2.6 までにもあった、似たようなオプション ignore_errors: yes でも試します。
- Playbook
- hosts: linux gather_facts: no tasks: - name: yum error yum: name: invalid_package_xxx # エラー ignore_errors: yes # point - name: debug debug: msg: "Hello debug."
- 実行結果
$ ansible-playbook -i inventory iu_linux.yml
PLAY [linux] ********************************************************************
TASK [yum error] ****************************************************************
fatal: [testsv1]: FAILED! => {"ansible_facts": {"pkg_mgr": "yum"}, "changed": false, "msg": "No package matching 'invalid_package_xxx' found available, installedor updated", "rc": 126, "results": ["No package matching 'invalid_package_xxx' found available, installed or updated"]}
...ignoring
fatal: [testsv99]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 172.16.0.11 port 22: No route to host\r\n", "unreachable": true}
TASK [debug] ********************************************************************
ok: [testsv1] => {
"msg": "Hello debug."
}
to retry, use: --limit @/vagrant/a27/iu_linux.retry
PLAY RECAP **********************************************************************
testsv1 : ok=2 changed=0 unreachable=0 failed=0
testsv99 : ok=0 changed=0 unreachable=1 failed=0
testsv1 では、1つめの yum モジュールのタスクでエラーが発生しましたが、 ignore_error: yes のため、無視して2つめの debug モジュールのタスクが実行されました。
一方、testsv99 では、1つめのタスクの時点で unreachable なので、その時点で処理が終わっています。
■ 補足
ignore_unreachable を指定できる箇所
公式ドキュメントの Playbook Keywords によると、Play、Role、Block、Task のいずれにも指定できるようです。
例えば、Play に指定する場合はこのようになります。
- hosts: linux gather_facts: no ignore_unreachable: yes tasks: ...(略)...
利用できるコネクションプラグイン
試した限り、network_cli や netconf といったネットワークモジュール向けのコネクションプラグインでは、ignore_unreachable の指定が効かなかっです。
■ さいごに
ignore_unreachable、ignore_errors についてまとめると以下のようになります。
ignore_unreachable |
ignore_errors |
到達不能の場合 | 到達可能だが、モジュール実行エラーの場合 |
|---|---|---|---|
no (デフォルト) |
no (デフォルト) |
中断 | 中断 |
yes |
no (デフォルト) |
無視して継続 | 中断 |
yes |
yes |
無視して継続 | 無視して継続 |
no (デフォルト) |
yes |
中断 | 無視して継続 |
ignore_unreachable: yes を指定する必要がるケースは限定的かもしれませんが、何かのときに思い出していただければ幸いです。