てくなべ (tekunabe)

ansible / network automation / 学習メモ

[Ansible] assert モジュールと ansible.utils.fact_diff フィルターを組み合わせてエラーメッセージをわかりやすくする

はじめに

以前の記事でもご紹介した、ansible.utils.fact_diff フィルター のちょっとした活用方法です。

ansible.utils.fact_diff 「モジュール」ではなく「フィルター」なので、別のモジュールのオプションに組み込めます。

この特性を活用して、ansible.builtin.assert モジュールとの組わせ例を試します。

  • 検証環境
    • ansible-core 2.16.0
    • ansible.utils 3.0.0

サンプル

Playbook は以下の通り。 ディクショナリー dict1dict2 を定義し、それが同じかどうかを ansible.builtin.assert モジュール で確認します。

デフォルトでは条件を満たさなかった(ここでは同じでない場合)場合は、割とシンプルなエラーメッセージになります。

そこで、ansible.utils.fact_diff フィルターを利用して、どこが異なるかの差分をエラーメッセージとして表示します。

---
- hosts: localhost
  gather_facts: false
  connection: local

  vars:
    dict1:
      name: sakana
      size: 23
      memo: hoghoge
    dict2:
      name: sakana
      size: 24
      memo: hoghoge

  tasks:
    - name: assert test
      ansible.builtin.assert:
        that:
          - dict1 == dict2
        fail_msg: "{{ dict1 | ansible.utils.fact_diff(dict2) }}"

結果は以下の通りです。両 ディクショナリ内の size が異なることが分かります。

TASK [assert test] ********************************************************************************************************
fatal: [localhost]: FAILED! => {
    "assertion": "dict1 == dict2",
    "changed": false,
    "evaluated_to": false,
    "msg": [
        "--- before",
        "+++ after",
        "@@ -1,5 +1,5 @@",
        " {",
        "     \"memo\": \"hoghoge\",",
        "     \"name\": \"sakana\",",
        "-    \"size\": 23",
        "+    \"size\": 24",
        " }",
        ""
    ]
}

なお、failed_msg を定義しない場合は以下のようなメッセージになります。

TASK [assert test] *********************************************************
fatal: [localhost]: FAILED! => {
    "assertion": "dict1 == dict2",
    "changed": false,
    "evaluated_to": false,
    "msg": "Assertion failed"
}