devel ブランチで開発中のコードで動作検証が必要な場合、pip では以下のコマンドでインストールします。
pip install git+https://github.com/ansible/ansible.git@devel
・引用元
devel ブランチで開発中のコードで動作検証が必要な場合、pip では以下のコマンドでインストールします。
pip install git+https://github.com/ansible/ansible.git@devel
・引用元
Ansible 2.4 から、ネットワークモジュールに、設定だけでなく「意図した状態か」チェックする Declarative Intent という機能が追加されました。
参考 https://www.ansible.com/blog/networking-features-in-ansible-2-4
Ansible 2.4 時点では、 例えば ios_interfae
や、junos_interface
モジュールなどの、以下のオプションによりチェックすることができます。
neighbors
: CDP/LLDPのホスト、ポート情報state
: インターフェースの状態(present
、absent
、up
、down
)rx_rate
: 受信レート(bps)がとの程度かtx_rate
: 送信レート(bps)がとの程度かあくまで、チェックするためのオプションであるため、指定した通りに設定するという機能ではりません。
この記事では、Ansible 2.5 でios_vlan
モジュールに追加された、associated_interfaces
オプションを利用し、想定したインターフェースが特定の VLAN に所属されているかチェックする方法をご紹介します。
ネットワーク機器側の VLAN と インターフェースの所属関係は以下の状態とします。
Switch13(config)#do sh vlan VLAN Name Status Ports ---- -------------------------------- --------- ------------------------------- 1 default active Gi1/0/1, Gi1/0/2, Gi1/0/3, Gi1/0/4 Gi1/0/5, Gi1/0/6, Gi1/0/7, Gi1/0/8 Gi1/0/9, Gi1/0/12, Gi1/0/14 Gi1/0/15, Gi1/0/16, Gi1/0/17 Gi1/0/18, Gi1/0/19, Gi1/0/20 Gi1/0/21, Gi1/0/22, Gi1/0/23 13 VLAN0013 active Gi1/0/13 99 VLAN0099 active Gi1/0/10, Gi1/0/11 192 VLAN0192 active Gi1/0/24
(コンフィグ抜粋)
interface GigabitEthernet1/0/9 ! interface GigabitEthernet1/0/10 switchport access vlan 99 switchport mode access ! interface GigabitEthernet1/0/11 switchport access vlan 99 switchport mode access ! interface GigabitEthernet1/0/12 !
今回は、vlan99(Gi1/0/10, Gi1/0/11)をチェック対象とします。
チェックが成功するような Playbook で試します。
先程ネットワーク機器側で確認したように、vlan99 に GigabitEthernet1/0/10
と GigabitEthernet1/0/11
が所属していることをチェックします。
所属インターフェースの指定には、 associated_interfaces
オプションを利用します。
- hosts: ios gather_facts: no - name: check vlan ios_vlan: vlan_id: 99 associated_interfaces: - GigabitEthernet1/0/10 - GigabitEthernet1/0/11
以下のように、ok
となります。
(ansible25) [vagrant@centos7 vagrant]$ ansible-playbook -i inventory ios_test.yml PLAY [ios] ************************************************************************************************************** TASK [check vlan] ******************************************************************************************************* ok: [192.168.1.13] PLAY RECAP ************************************************************************************************************** 192.168.1.13 : ok=1 changed=0 unreachable=0 failed=0
今度は、チェックが失敗するような Playbook で試します。
先程とは異なり、 GigabitEthernet1/0/12
という vlan99 に所属しないインターフェースを追加で指定してみます。
- hosts: ios gather_facts: no - name: check vlan ios_vlan: vlan_id: 99 associated_interfaces: - GigabitEthernet1/0/10 - GigabitEthernet1/0/11 - GigabitEthernet1/0/12 # not vlan99
今度は、failed
となります。"Interface GigabitEthernet1/0/12 not configured on vlan 99"
というていねいなエラーメッセージが確認できます。
(ansible25) [vagrant@centos7 vagrant]$ ansible-playbook -i inventory ios_test.yml PLAY [ios] ************************************************************************************************************** TASK [check vlan] ******************************************************************************************************* fatal: [192.168.1.13]: FAILED! => {"changed": false, "msg": "Interface GigabitEthernet1/0/12 not configured on vlan 99"} to retry, use: --limit @/vagrant/ios_test.retry PLAY RECAP ************************************************************************************************************** 192.168.1.13 : ok=0 changed=0 unreachable=0 failed=1
2点ほど注意点をあげます。
associated_interfaces
オプションで指定するインターフェース名は、コンフィグ上の表記通りにする必要があります。
associated_interfaces: - GigabitEthernet1/0/10 - GigabitEthernet1/0/11
associated_interfaces: - Gi1/0/10 - Gi1/0/11
誤った表記の指定の仕方をすると、正しくチェックができませんので注意が必要です。
例えば、vlan99に GigabitEthernet1/0/10
と GigabitEthernet1/0/11
が所属している状態で、以下のように associated_interfaces
オプションで GigabitEthernet1/0/10
のみを指定した場合でも、チェック結果は ok
となります。
- name: check vlan ios_vlan: vlan_id: 99 associated_interfaces: - GigabitEthernet1/0/10
そのため、チェックの意味合いとしては、
associated_interfaces
オプションで指定したインターフェースが vlan_id
オプションで指定した vlan に所属していることになります。
vlan_id
オプションで指定した vlan に associated_interfaces
オプションで指定したインターフェースが過不足なく所属していることではないので注意が必要です。
現段階ではチェックできるオプションは多くないですが、今後増えてくるかもしれません。 チェックしたいオプションがある場合は、利用を検討してみてはいかがでしょうか。
また、チェック(テスト)するという観点では、napalm_validate
というサードパーティモジュールを利用する方法もあります。詳細は、AnsibleとNAPALMでネットワークをテストする をご参照下さい。
Ansible のネットワークモジュールは、通常のモジュールとは facts の扱いが異なります。 この記事では、ネットワークモジュール固有の facts の扱い方についてご紹介します。 想定バージョンは Ansible 2.5.2 です。
ios_command
、junos_config
などのネットワークモジュールは、Ansible ホスト側で Python スクリプトが実行されます。
そのため、 gather_facts: yes
(デフォルト) で取得される facts は、操作対象のネットワーク機器側ではなく、Ansible ホスト側の facts になります。
ネットワーク機器側のホスト名や、インターフェース情報などの facts を取得するにためには、 ios_facts
や junos_facts
など、ネットワークプラットフォームごとに用意された専用の *_facts
モジュールを利用します。
Junosの facts を取得するjunos_facts
モジュールを利用するサンプルです。
gather_subset
オプションを省略した場合は、コンフィグ以外の facts を取得します。
- hosts: junos connection: netconf gather_facts: no tasks: - name: facts junos_facts: - name: debug debug: msg: "{{ ansible_facts }}"
ここでは、Ansible ホスト側の facts は必要ないとしているので、 gather_facts: no
にしています。
また、msg: "{{ ansible_facts }}"
と指定しているように、Ansible 2.5 から facts は ansible_facts.* という名前空間配下でも参照可能です。
(ansible25) [vagrant@centos7 vagrant]$ ansible-playbook -i inventory junos_test.yml --tag=d PLAY [junos] ************************************************************************************************* TASK [facts] ************************************************************************************************* ok: [172.16.0.1] TASK [debug] ************************************************************************************************* ok: [172.16.0.1] => { "msg": { "net_filesystems": [ "/dev/ad0s1a", "devfs", "/dev/md0", "/cf", "devfs", "procfs", "/dev/bo0s1e", "/dev/md1", "/cf/var/jail", "/cf/var/log", "devfs", "/dev/md2" ], "net_gather_subset": [ "hardware", "default", "interfaces" ], "net_has_2RE": false, "net_hostname": "vsrx1", "net_interfaces": { ".local.": { "admin-status": "up", "macaddress": "Unspecified", "mtu": "Unlimited", "oper-status": "up", "speed": "Unlimited", "type": "Loopback" }, "dsc": { "admin-status": "up", "macaddress": "Unspecified", "mtu": "Unlimited", "oper-status": "up", "speed": "Unspecified", "type": "Software-Pseudo" }, "ge-0/0/0": { "admin-status": "up", "macaddress": "08:00:27:ae:**:**", "mtu": "1514", "oper-status": "up", "speed": "1000mbps", "type": null }, "ge-0/0/1": { "admin-status": "up", "macaddress": "08:00:27:af:**:**", "mtu": "1514", "oper-status": "up", "speed": "1000mbps", "type": null }, (略) } }, "net_memfree_mb": 76448, "net_memtotal_mb": 1031572, "net_model": "firefly-perimeter", "net_modules": [ { "name": "Midplane" }, { "name": "System IO" }, { "description": "FIREFLY-PERIMETER RE", "name": "Routing Engine" }, { "description": "Virtual FPC", "name": "FPC 0" }, { "name": "Power Supply 0" } ], "net_routing_engines": { "null": { "cpu_background": "0", "cpu_idle": "100", "cpu_interrupt": "0", "cpu_system": "0", "cpu_user": "0", "last_reboot_reason": "Router rebooted after a normal shutdown.", "load_average_fifteen": "0.00", "load_average_five": "0.02", "load_average_one": "0.00", "memory_control_plane": "594", "memory_control_plane_used": "321", "memory_control_plane_util": "54", "memory_data_plane": "430", "memory_data_plane_used": "211", "memory_data_plane_util": "49", "memory_system_total": "1024", "memory_system_total_used": "532", "memory_system_total_util": "52", "model": "FIREFLY-PERIMETER RE", "slot": null, "start_time": "2018-04-11 13:23:07 UTC", "status": "Testing", "up_time": "1 day, 17 hours, 40 minutes, 58 seconds" } }, "net_serialnum": "a9039f******", "net_version": null } } PLAY RECAP *************************************************************************************************** 172.16.0.1 : ok=2 changed=0 unreachable=0 failed=0 (ansible25) [vagrant@centos7 vagrant]$
ホスト名 vsrx1
や、インターフェースの情報などが facts として取得できたことが分かります。
https://www.ansible.com/blog/coming-soon-networking-features-in-ansible-2.5 上記の Ansible 2.5 正式リリース前の公式ブログに、
Fact gathering for network_cli and netconf connection methods are not turned on by default.
という記述がありますが、実際は異なるようです。ネットワークモジュールのベストプラクティスはあくまでも、必要でない限りは、gather_facts: no
を指定しておくことのようです。
Ansible 2.5 から facts は ansible_facts.* という名前空間配下でも参照可能になりました。
ansilbe_distribution
であれば
ansible_facts.distribution
でも参照可能ansilbe_nodename
であれば
ansible_facts.nodename
でも参照可能そのため、ansible_facts
を参照すると、配下の facts の一覧を取得できます。
- hosts: webservers gather_facts: yes tasks: - name: facts debug: msg: "{{ ansible_facts }}"
$ ansible-playbook -i inventory junos_test.yml --tag=d PLAY [webservers] *************************************************** TASK [Gathering Facts] ******************************************************* ok: [172.16.0.1] TASK [facts list] ************************************************************ ok: [172.16.0.1] => { "msg": { "all_ipv4_addresses": [ "172.17.0.1", "172.16.0.9", "10.0.2.15" ], "all_ipv6_addresses": [ "fe80::42:75ff:fe85:****", "fe80::a00:27ff:fe74:****", "fe80::5054:ff:feda:****" ], "ansible_local": {}, "apparmor": { "status": "disabled" }, "architecture": "x86_64", "bios_date": "12/01/2006", "bios_version": "VirtualBox", (略) "userspace_bits": "64", "virtualization_role": "guest", "virtualization_type": "virtualbox" } } PLAY RECAP ***************************************************************** 172.16.0.1 : ok=2 changed=0 unreachable=0 failed=0
既存の ansible_
というプレフィックよりも ansible_facts
という名前空間で整理されているほうが、まとめて処理がしやすいので使いやすいと感じました。
Ansible Network Team によってメンテナンスされているネットワークモジュール一覧は以下のページにまとめられています。
Modules Maintained by the Ansible Network Team — Ansible Documentation
(参考リンク)
なお、サポートされないものも含めたネットワークモジュールは以下のページにまとめられています。
Ansible 2.4 から、ネットワークモジュールの一部で、繰り返しを伴う設定を効率的に投入できる aggregate
というオプションが利用できるようになりました。 この記事では、既存の with_items
による繰り返しとの比較を通じて、動作の紹介をします。
検証環境は Ansible 2.5.2 です。
aggregate
オプションは以下のような利用の仕方になります。(junos_static_route
モジュールでの例)
- name: set static route junos_static_route: aggregate: - { address: 172.16.1.0/24, next_hop: 10.0.0.1 } - { address: 172.16.2.0/24, next_hop: 10.0.0.2 } - { address: 172.16.3.0/24, next_hop: 10.0.0.3 }
雰囲気である程度予想できるかもしれませんが、上記の場合3つのスタティックルートが追加されます。
junos_static_route
モジュールにはもともと、 address
や next_hop
などのオプションがあり、それらを繰り返し指定するために、 aggregate
オプション配下に指定する形になります。
(ansible25) [vagrant@centos7 vagrant]$ ansible-playbook -i inventory junos_test.yml PLAY [junos] **************************************************************************** TASK [set static route (aggregate)] ***************************************************** changed: [172.16.0.1] PLAY RECAP ****************************************************************************** 172.16.0.1 : ok=1 changed=1 unreachable=0 failed=0 (ansible25) [vagrant@centos7 vagrant]$
ポイントは、スタティックルートを追加する処理を3回繰り返すのではなく、1回の処理で完了 している点です。 これは、繰り返し分のコンフィグを生成してから、1つのタスクとしていっぺんにコンフィグ投入するためです。 仮に、特定の1つのスタティックルートにパラメータエラーがあった場合は、3つのスタティックルートとも設定が入りません。
念のため確認します。
root@vsrx1# show routing-options static | display set set routing-options static route 172.16.1.0/24 next-hop 10.0.0.1 set routing-options static route 172.16.2.0/24 next-hop 10.0.0.2 set routing-options static route 172.16.3.0/24 next-hop 10.0.0.3
無事に追加されました。
一例ですが、以下のようなモジュールで aggregate
オプションが利用できます。
公式ドキュメント内に一覧は見当たりませんでしたが、*_config
や *_commmand
のように、コンフィグをそのまま指定するタイプのモジュールではなく、コンフィグのオプションがオプションとして抽象化されたモジュールが対象のようです。
繰り返し処理というと with_items
や loop
(Asnible2.5から利用可)を思い浮かべると思います。先程のサンプルを with_itmes
で記載すると以下のようになります。
- name: set static route (with_items) junos_static_route: address: "{{item.address}}" next_hop: "{{item.next_hop}}" with_items: - { address: 172.16.1.0/24, next_hop: 10.0.0.1 } - { address: 172.16.2.0/24, next_hop: 10.0.0.2 } - { address: 172.16.3.0/24, next_hop: 10.0.0.3 }
(ansible25) [vagrant@centos7 vagrant]$ ansible-playbook -i inventory junos_test.yml PLAY [junos] **************************************************************************** TASK with_items) *********************************************************************** changed: [172.16.0.1] => (item={u'next_hop': u'10.0.0.1', u'address': u'172.16.1.0/24'}) changed: [172.16.0.1] => (item={u'next_hop': u'10.0.0.2', u'address': u'172.16.2.0/24'}) changed: [172.16.0.1] => (item={u'next_hop': u'10.0.0.3', u'address': u'172.16.3.0/24'}) PLAY RECAP ****************************************************************************** 172.16.0.1 : ok=1 changed=1 unreachable=0 failed=0 (ansible25) [vagrant@centos7 vagrant]$
おなじみの with_items
らしいログとなりました。
仮に、特定の1つのスタティックルートにパラメータエラーがあった場合は、そのスタティックルート以外は設定されます。
まとめると以下のようになります。
比較項目 | aggregate | with_items |
---|---|---|
利用可能バージョン | 2.4以上 | |
利用可能モジュール | 一部 | すべて |
処理速度 | 早い | 遅い |
パラメータエラー時 (junos_static_route で確認) |
1つも設定されない | エラー分のみスキップ |
個人的には aggregate
オプションのほうが早いですし、よりフェールファーストらしい挙動になるので、利用できるモジュールの場合は特徴を理解した上で、 aggregate
オプションを利用したほうが良いと思いました。
2018/04/26 に開催された Ansible Night in Tokyo 2018.04 で「Junosモジュールのコネクションタイプの使い分け」という発表をさせていただきました。
Ansible 2.5 で、ネットワークモジュール向けに network_cli
、 netconf
という2つのコネクションタイプが追加され、Junos モジュールではどちらも使用できます。
今回の発表ではこれらのコネクションタイプの使い分け方をご紹介しました。
この記事では私の発表資料の共有や、他の方の発表資料、ブロガー枠の方の記事の紹介などをまとめます。
私が発表に使用した資料はこちらです。
www.slideshare.net
他の方の資料は以下のページにアップされています。
www.slideshare.net
www.slideshare.net
ブロガー枠(一般参加枠より倍率が低く参加しやすい)で参加された方のレポート記事です。 smallpalace.hatenablog.com
来日されていた Red Hat の Sean Cavanaugh さんによる通常セッション「Ansible 2.5 のアップデートとネットワーク自動化」の内容と一部被ってしまうではないかと、内心ハラハラしていたのですが、 結果的には Sean さんの発表の一部を深掘りして日本語でお届けでできた、とかたちになったのでホッとしました。
そしてコメント頂き嬉しかったです。
Some great slides from @akira6592 on JunOS and @ansible pic.twitter.com/Ab7SUrBRaA
— Sean Cavanaugh (@IPvSean) 2018年4月26日