てくなべ (tekunabe)

ansible / network automation / 学習メモ

[Ansible] collections ディレクティブはフィルターに適用できない

はじめに

Ansible 2.10 あたりから、本格的に Collection によるモジュールなどの配布、運用がはじまりました。

docs.ansible.com

各モジュールやフィルターなどは、名前空間が設けられました。

たとえば、ios_config モジュールであれば、名前空間を含めると、cisco.ios.ios_config という表記になります。この表記を FQCN と呼びます。

都度 FQCN 表記するのは少々冗長なため、簡略化するために collections ディレクティブが用意されています。

collections ディレクティブを利用すると、モジュール名を FQCN 表記しなくて良くなります。

- hosts: ios
  collections:
    - cisco.ios
  tasks:
    - name: test
      ios_config:    # cisco.ios.ios_config とする必要がない
        # ...(略)...

ただし、collections ディレクティブは、フィルターやルックアッププラグインなどには適用できません。そのため、FQCN が原則となります。

Using collections — Ansible Documentation

Note that an FQCN is still required for non-action or module plugins (for example, lookups, filters, tests).

この記事では、collections ディレクティブがフィルターに適用できない仕様を動作確認します。

※なお、本件とは別に、Ansible 2.9 から 2.10 への移行容易性(おそらく)のため、従来からあるもについては装飾なし表記から FQCN 表記にリダイレクトする仕組みもあります。

  • 動作確認環境
    • ansible-base 2.10.1


サンプル

対象のフィルターは ansible.netcommon collection の ipv4 フィルターにします。FQCNansible.netcommon.ipv4 です。

パターン1: collections なし、装飾

Playbook

---
- hosts: localhost
  gather_facts: false

  tasks:
    - name: assert ipv4
      assert:
        that:
          - "'10.0.0.1' | ipv4"  # 装飾なしで ipv4

実行

$ ansible-playbook -i localhost, collections.yml -vvv
...(略)...
TASK [assert ipv4] *****************************************************************
task path: /Users/akira/Documents/git/general/vagrant/nwlab/blog/collections.yml:6
redirecting filter ansible.builtin.ipv4 to ansible.netcommon.ipv4
redirecting filter ansible.builtin.ipv4 to ansible.netcommon.ipv4
ok: [localhost] => {
    "changed": false,
    "msg": "All assertions passed"
}
META: ran handlers
META: ran handlers
...(略)...

装飾なしの ipv4 のため、redirecting filter ansible.builtin.ipv4 to ansible.netcommon.ipv4 とリダイレクトの仕組み救われていることが分かります。 なお、このログは ansible-playbook コマンドの -vvv 以上の v オプションをつけたときに表示されます。

パターン2: collections あり、装飾なし

今度は、collections ディレクティブを指定します。

Playbook

---
- hosts: localhost
  gather_facts: false
  collections:
    - ansible.netcommon
  tasks:
    - name: assert ipv4
      assert:
        that:
          - "'10.0.0.1' | ipv4"  # 装飾なしで ipv4

実行

$ ansible-playbook -i localhost, collections.yml -vvv
...(略)...
TASK [assert ipv4] *****************************************************************
task path: /Users/akira/Documents/git/general/vagrant/nwlab/blog/collections.yml:6
redirecting filter ansible.builtin.ipv4 to ansible.netcommon.ipv4
redirecting filter ansible.builtin.ipv4 to ansible.netcommon.ipv4
ok: [localhost] => {
    "changed": false,
    "msg": "All assertions passed"
}
META: ran handlers
META: ran handlers
...(略)...

相変わらず、redirecting filter ansible.builtin.ipv4 to ansible.netcommon.ipv4 とリダイレクトの仕組み救われていることが分かります。 このことにより、collections ディレクティブはフィルターに適用できないことが確認できます。

パターン3: collections なし、FQCN

最後に念の為、FQCNで指定した場合を確認します。 Playbook

---
- hosts: localhost
  gather_facts: false
  collections:

  tasks:
    - name: assert ipv4
      assert:
        that:
          - "'10.0.0.1' | ansible.netcommon.ipv4"  # FQCN

実行

$ ansible-playbook -i localhost, collections.yml -vvv
...(略)...
TASK [assert ipv4] ******************************************************************
task path: /Users/akira/Documents/git/general/vagrant/nwlab/blog/collections.yml:6
ok: [localhost] => {
    "changed": false,
    "msg": "All assertions passed"
}
META: ran handlers
...(略)...

redirecting filter ansible.builtin.ipv4 to ansible.netcommon.ipv4 というリダイレクトのログが表示されなくなりました。素直に FQCN に従って利用するフィルターが呼び出されたパターンです。


おわりに

collectiions ディレクティブと、リダイレクトの仕組みがでてきて少し複雑にかんじました。

なお、ドキュメントにあった

Note that an FQCN is still required for non-action or module plugins (for example, lookups, filters, tests).

は、リダイレクトの仕組みとは棲み分けされた説明なのだと思います。

あまりリダイレクトに頼りすぎていると、リダイレクトされない新しいフィルターを利用しようとするときにハマりそうな気がするので注意しようと思います。

謝辞

情報ありがとうございます!(リプ欄)