はじめに
タイトルの通り。両方指定した場合、どのように動作するのか気になったので検証した。
ignore_errorsとfailed_whenについて
- ignore_errors タスクがエラーになっても無視し処理を継続する。
- failed_when
条件式を記述し、条件を満たした時にタスクの結果に関わらずステータスを
failed
にする。
環境
面倒なので全部。
root@84212b237d2f:~/ansible# ansible --version ansible [core 2.17.6] config file = /root/ansible/ansible.cfg configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /usr/local/lib/python3.11/site-packages/ansible ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections executable location = /usr/local/bin/ansible python version = 3.11.10 (main, Nov 12 2024, 06:03:56) [GCC 12.2.0] (/usr/local/bin/python3.11) jinja version = 3.1.4 libyaml = True
検証用Playbook
--- - hosts: localhost connection: local gather_facts: false vars: error: "true" # failed_whenをコントールする用の変数 tasks: - name: failed ansible.builtin.command: cmd: echo "hoge" # 実行に成功するコマンド failed_when: error == "true" # 変数"error"が"true"ならfailedとなるように指定 ignore_errors: true # ignore_errorsを有効化 register: res_echo # コマンドの出力表示用 - name: debug ansible.builtin.debug: msg: "{{ res_echo.stdout_lines }}"
実行
root@84212b237d2f:~/ansible# ansible-playbook blog_test/ignore_when.yml PLAY [localhost] ****************************************************************************************************** TASK [failed] ********************************************************************************************************* fatal: [localhost]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/local/bin/python3.11"}, "changed": true, "cmd": ["echo", "hoge"], "delta": "0:00:00.003392", "end": "2024-12-04 02:47:13.959671", "failed_when_result": true, "msg": "", "rc": 0, "start": "2024-12-04 02:47:13.956279", "stderr": "", "stderr_lines": [], "stdout": "hoge", "stdout_lines": ["hoge"]} ...ignoring TASK [debug] ********************************************************************************************************** ok: [localhost] => { "msg": [ "hoge" ] } PLAY RECAP ************************************************************************************************************ localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
failed_when
がヒットするため該当のタスクはfailed
となる。 しかしignore_errors
が有効化されているため処理は継続される。
タスクがfailed
となっている理由はコマンドの失敗ではなくfailed_when
であるためコマンドの実行は成功している。なので後続のdebug
モジュールではecho "hoge"
の結果を格納した変数から値を取り出せている。
おわりに
ignore_errors
とfailed_when
の両方を有効にした際の挙動について知ることができた。
ignore_errors
はモジュールのエラーとfailed_when
のエラーを区別せず、すべてのエラーを無視するディレクティブであることが分かった。
疑問点
主旨とズレてる気がするので折りたたむ(クリックで展開)
疑問というより、不思議に思ったのは検証用Playbookの実行結果でchanged
が1になっている点。
コマンドを実行するタスクにてchanged: true
となっているのでここのchanged
がカウントされていそう。
ignore_errors
を外して実行してみる。
root@84212b237d2f:~/ansible# ansible-playbook blog_test/ignore_when.yml PLAY [localhost] ****************************************************************************************************** TASK [failed] ********************************************************************************************************* fatal: [localhost]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/local/bin/python3.11"}, "changed": true, "cmd": ["echo", "hoge"], "delta": "0:00:00.003515", "end": "2024-12-04 03:05:26.835896", "failed_when_result": true, "msg": "", "rc": 0, "start": "2024-12-04 03:05:26.832381", "stderr": "", "stderr_lines": [], "stdout": "hoge", "stdout_lines": ["hoge"]} PLAY RECAP ************************************************************************************************************ localhost : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
stdout
を見る分にはちゃんとコマンド実行できてそうだし、changed:true
となっているのにRECAPのchanged
は1にならない。
failed_when
を外し、実行するコマンドを実行不可なものに変更してみる。
root@84212b237d2f:~/ansible# ansible-playbook blog_test/ignore_when.yml PLAY [localhost] ****************************************************************************************************** TASK [failed] ********************************************************************************************************* fatal: [localhost]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/local/bin/python3.11"}, "changed": false, "cmd": "foo", "msg": "[Errno 2] No such file or directory: b'foo'", "rc": 2, "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []} ...ignoring TASK [debug] ********************************************************************************************************** ok: [localhost] => { "msg": [] } PLAY RECAP ************************************************************************************************************ localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
そもそもコマンド実行でこけるのでstdout
が空なのは当然、changed: false
になっているためRECAPのchanged
も0なのは納得がいく。
failed_when
とignore_errors
が組み合わさることであのchanged
が出てきたのかな。
ここから更に深堀する元気は今はないのでここまでにする。(気力が出てきたら追記するかも)