2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AnsibleAdvent Calendar 2021

Day 13

[小ネタ] ignore_errorsの罠

Last updated at Posted at 2021-12-12

概要

なにかのモジュールでエラーが発生する際にそのエラーハンドリングとしてignore_errorsを利用することがある(エラーを無視して、次の処理で戻り値を基に処理分岐するような実装)と思いますが、以下のようにモジュールの実行時エラーがスルーされる場合もあるので、追加の確認処理を設けるとより安全になるかと思います。

コード

以下ではdebugモジュールのパラメータmsgmsgsにし、あえて実行時エラーを発生させます。
後続の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」の値を返す必要がある場合にのみ機能します

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?