てくなべ (tekunabe)

ansible / network automation / 学習メモ

[Ansible] モジュールの指定などを FQCN 表記に移行する手順

はじめに

Ansible 2.10 から、多くのモジュールやプラグインなどが Collection へ移行しました。

collection は cisco.ios のようなドット区切りの名前空間が設けられます。その中のモジュールを利用する場合は、cisco.ios.ios_configのように指定します。このような表記を FQCN と呼びます。

少なくとも Ansible 2.9 に標準で同梱されていたモジュールについては、装飾なしの名前(例: ios_config)の指定でも、ansible_builtin_runtime.ymlというファイルの対応付けによって FQCN(例: cisco.ios.ios_config)へリダイレクトされる仕組みになっています。

親切な仕組みではありますが、なんとなく自動的にリダイレクトされることに頼りたくない、という気持ちになることはないでしょうか。

この記事では、リダイレクトに頼った Playbook を FQCN に変更するための手順を記載します。

もっと確実でスマートな手順があるかもしれませんが、自分が分かる範囲で現状はこうするのがいいのではないか、という位置づけです。 Playbook とansible_builtin_runtime.ymlの両方を眺めながら修正するよりはいくらか良いと思います。

動作確認環境: ansible-base 2.10.1



■ 前提環境

ansible-base 2.10.1 に cisco.ioscommunity.general collection をインストールしてある環境です。

  • collection インストール手順
$ ansible-galaxy collection install cisco.ios
$ ansible-galaxy collection install community.general

明示的にインストールした collection 以外にも、依存している別の collection もインストールされています。

$ ansible-galaxy collection list    

# /Users/sakana/.ansible/collections/ansible_collections
Collection           Version
-------------------- -------
ansible.netcommon    1.2.1  
ansible.posix        1.1.1  
cisco.ios            1.0.0  
community.general    1.1.0  
community.kubernetes 1.0.0  
google.cloud         1.0.0 


■ 対象Playbook など

Cisco IOS の機器に簡単な設定変更をする Playbook を前提とします。まだ FQCN はどこにも登場しません。

インベントリファイル(inventory.ini

rt01 というホストを1台定義した ios グループがある状態です。

[ios]
rt01 ansible_host=192.168.1.11

変数定義ファイル(group_vars/ios.yml

利用するコネクションプラグインやOSを指定します。

---
ansible_network_os: ios
ansible_connection: network_cli
ansible_user: ansible
ansible_password: password
ansible_become: true
ansible_become_method: enable
ansible_become_password: secret

モジュールではないから FQCN とは関係ないのではないかと思われるかも知れませんが実は関係あります。あとで修正します。

Playbook(tofqcn.yml

変数 ntp_serverIPv4 アドレスらしいことを ipv4 フィルターと assert モジュールで確認し、ios_config モジュールでコンフィグ投入する Playbook です。

---
- hosts: ios
  gather_facts: false

  vars:
    ntp_server: 10.0.0.123
    
  tasks:
    - name: assert ntp server
      assert:
        that: ntp_server | ipv4

    - name: ios test
      ios_config:
        lines:
          - "ntp server {{ ntp_server }}"

(ここでは処理の妥当性はあまり優先していません。たとえば NTP サーバー設定であれば、専用の ios_ntp モジュールが別途あったりします。)

設定ファイル(ansible.cfg

コールバックプラグインyaml を指定します。これも実はあとで修正することになります。

[defaults]
stdout_callback = yaml


■ 1. リダイレクトの様子を確認する

ひとまず、装飾なし表記のままで Playbook を実行します。ansible-playbook-vvv をつけると FQCN へリダイレクトする様子がログに出力されます。(厳密には、-vv での出力するものと、-vvv で出力するものがあるようです)

実行結果(リダイレクト部分を中心に抜粋)

redirecting というログとともに、リダイレクトの様子が表示されます。ios_config モジュールだけでないことも分かります。

$ ansible-playbook -i inventory.ini tofqcn.yml -vvv  
ansible-playbook 2.10.1
...(略)...
redirecting (type: modules) ansible.builtin.ios_config to cisco.ios.ios_config
redirecting (type: callback) ansible.builtin.yaml to community.general.yaml
redirecting (type: callback) ansible.builtin.yaml to community.general.yaml

PLAYBOOK: tofqcn.yml *****************************************************************************************************
1 plays in tofqcn.yml

PLAY [ios] ***************************************************************************************************************
META: ran handlers

TASK [assert ntp server] *************************************************************************************************
task path: /Users/sakana/ansible/tofqcn.yml:9
redirecting (type: connection) ansible.builtin.network_cli to ansible.netcommon.network_cli
redirecting (type: terminal) ansible.builtin.ios to cisco.ios.ios
redirecting (type: cliconf) ansible.builtin.ios to cisco.ios.ios
redirecting (type: become) ansible.builtin.enable to ansible.netcommon.enable
redirecting filter ansible.builtin.ipv4 to ansible.netcommon.ipv4
redirecting filter ansible.builtin.ipv4 to ansible.netcommon.ipv4
redirecting filter ansible.builtin.ipv4 to ansible.netcommon.ipv4
ok: [rt01] => changed=false 
  msg: All assertions passed

TASK [ios test] **********************************************************************************************************
task path: /Users/sakana/ansible/tofqcn.yml:13
redirecting (type: connection) ansible.builtin.network_cli to ansible.netcommon.network_cli
redirecting (type: terminal) ansible.builtin.ios to cisco.ios.ios
redirecting (type: cliconf) ansible.builtin.ios to cisco.ios.ios
redirecting (type: become) ansible.builtin.enable to ansible.netcommon.enable
redirecting (type: action) ansible.builtin.ios to cisco.ios.ios
redirecting (type: action) ansible.builtin.ios to cisco.ios.ios
...(略)...
redirecting (type: modules) ansible.builtin.ios_config to cisco.ios.ios_config
...(略)...
ok: [rt01] => changed=false 
...(略)...
META: ran handlers
META: ran handlers

PLAY RECAP ***************************************************************************************************************
rt01                       : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

最初見たときは、思いの外たくさんリダイレクトされると感じました。装飾なしの表記は、ansible.builtin.hogehoge として内部で扱われるようです。

今回の場合、リダイレクト先の collection 単位でまとめると以下の通りです。

  • cisco.ios collection

    • redirecting (type: modules) ansible.builtin.ios_config to cisco.ios.ios_config
    • redirecting (type: terminal) ansible.builtin.ios to cisco.ios.ios
    • redirecting (type: cliconf) ansible.builtin.ios to cisco.ios.ios
    • redirecting (type: cliconf) ansible.builtin.ios to cisco.ios.ios
    • redirecting (type: action) ansible.builtin.ios to cisco.ios.ios
  • ansible.netcommon collection

    • redirecting (type: connection) ansible.builtin.network_cli to ansible.netcommon.network_cli
    • redirecting (type: become) ansible.builtin.enable to ansible.netcommon.enable
    • redirecting filter ansible.builtin.ipv4 to ansible.netcommon.ipv4
  • community.general collection
    • redirecting (type: callback) ansible.builtin.yaml to community.general.yaml

なお、Playbook をチェックモードで実行してもリダイレクトの様子は確認できます。

リダイレクトを無効にするとエラーに

前述どおり、リダイレクト先の定義 は ansible_builtin_runtime.yml というファイルにあります。

自分の環境の、[python環境]/lib/python3.X/site-packages/ansible/config/ansible_builtin_runtime.yml をすべてコメントアウトすると、リダイレクト機能を無効できます。(設定で変更できても良さそうですが、それらしい項目はありませんでした)

現状の、装飾なし表記の Playbook で、リダイレクトを無効にして 実行すると以下のようなエラーになります。

$ ansible-playbook -i inventory.ini tofqcn.yml -vvv                                       
...(略)...

The error appears to be in '/Users/sakana/ansible/tofqcn.yml': line 13, column 7, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:


    - name: ios test
      ^ here

逆に、リダイレクトを無効にしても正常実行されれば、FQCN 化ができたと言えます(あとで試します)。

いったん、ansible_builtin_runtime.yml はもとに戻してリダイレクトは有効にします。


■ 2. FQCN に修正して再実行

先程、リダイレクトされた様子が確認できましたので、その内容に沿って FQCN に各ファイルを修正しています。

FQCN 版変数定義ファイル(group_vars/ios.yml

変数定義ファイルを修正します、iosnetwork_clienable をそれぞれ以下のように FQCN にします。

---
ansible_network_os: cisco.ios.ios                   # FQCN 化
ansible_connection: ansible.netcommon.network_cli   # FQCN 化
ansible_user: ansible
ansible_password: password
ansible_become: true
ansible_become_method: ansible.netcommon.enable     # FQCN 化
ansible_become_password: secret

FQCN 版 Playbook(tofqcn.yml

Playbook を修正します。ipv4ios_config をそれぞれ以下のように FQCN にします。

---
- hosts: ios
  gather_facts: false

  vars:
    ntp_server: 10.0.0.123
    
  tasks:
    - name: assert ntp server
      assert:
        that: ntp_server | ansible.netcommon.ipv4    # FQCN 化

    - name: ios test
      cisco.ios.ios_config:     # FQCN 化
        lines:
          - "ntp server {{ ntp_server }}"

FQCN 版設定ファイル(ansible.cfg

設定ファイルを修正します。 コールバックプラグインyaml は、community.general 配下なので以下のように修正します。

[defaults]
; FQCN 化
stdout_callback=community.general.yaml

他、インベントリファイル はそのままです。

実行結果(リダイレクト部分を中心に抜粋)

再度実行します。

$ ansible-playbook -i inventory.ini tofqcn.yml -vvv
ansible-playbook 2.10.1
...(略)...
redirecting (type: action) cisco.ios.ios_config to cisco.ios.ios

PLAYBOOK: tofqcn.yml *****************************************************************************************************
1 plays in tofqcn.yml

PLAY [ios] ***************************************************************************************************************
META: ran handlers

TASK [assert ntp server] *************************************************************************************************
task path: /Users/sakana/ansible/tofqcn.yml:24
ok: [rt01] => changed=false 
  msg: All assertions passed
redirecting (type: action) cisco.ios.ios_config to cisco.ios.ios

TASK [ios test] **********************************************************************************************************
task path: /Users/sakana/ansible/tofqcn.yml:28
redirecting (type: action) cisco.ios.ios_config to cisco.ios.ios
redirecting (type: action) cisco.ios.ios_config to cisco.ios.ios
<...(略)...
ok: [rt01] => changed=false 
...(略)...
META: ran handlers
META: ran handlers

PLAY RECAP ***************************************************************************************************************
rt01                       : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

いくつか redirecting というログが表示されましたが、さきほどは ansible.builtin.ios to cisco.ios.ios だったのが、cisco.ios.ios_config to cisco.ios.ios になりました。

リダイレクトを無効にしても正常終了

ansible_builtin_runtime.yml の内容をすべてコメントアウトし、リダイレクトを無効にして実行しても、正常に実行できました。ログは同じでした。

これで FQCN 化ができたようです。

(補足)collection の名前空間をまとめて指定する collections ディレクティブ

cisco.ios.ios_config のように、タスクでモジュール名を指定するたびに FQCN 表記にしてもよいのですが、まとめて指定する[ collections ディレクティブ]](https://docs.ansible.com/ansible/latest/user_guide/collections_using.html#using-collections-in-a-playbook)があります。

具体的には、以下のように指定します。この指定により、装飾なしの ios_configcisco.ios collection として探索する処理が有効になります。リダイレクトも不要です。

- hosts: ios
  gather_facts: false
  collections:      # collection の指定
    - cisco.ios 
    
  vars:
    ntp_server: 10.0.0.123
    
  tasks:
    - name: assert ntp server
      assert:
        that: ntp_server | ansible.netcommon.ipv4

    - name: ios test
      ios_config:   # 装飾なし
        lines:
          - "ntp server {{ ntp_server }}"

ただし、フィルターなど(上記では ipv4)には効かないのでご注意ください。

Using collections — Ansible Documentation

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


おわりに

FQCN 化して、リダイレクトに頼らない Playbook にする手順をご紹介しました。

リダイレクトを使う、使わないに限らず、モジュールがどの collection に所属しているかを今後は意識する機会が増えてくると思いますので、ansible_builtin_runtime.ymlは要チェックです。