これは Ansible 3 Advent Calendar 2019 の21日目の記事です。
■ はじめに
以前「[Ansible] NetBox モジュールで Site や Device を登録する(Collection モジュール編) - てくなべ (tekunabe)」で、Ansible から NetBox の Device を登録する方法をご紹介しました。
今回は NetBox に登録された Device を、Ansible のインベントリーとして利用する方法をご紹介します。 Ansible 2.8 で追加された、NetBox Inventory Plugin を利用します。 YAML で簡単な設定ファイルを書くだけで、動的なインベントリとして扱えるようになります。
■ NeBox上の状態
まず、今回インベントリとして利用する NetBox 上の Device 登録状態を示します。
前回の記事の「目指すゴール」で示した内容です。
念のため表でも示します。
Name | Site | Role | Manufacture | Type | IP Address |
---|---|---|---|---|---|
cat1 | my_site | core | Cisco | Catalyst | 10.0.1.1 |
cat2 | my_site | core | Cisco | Catalyst | 10.0.1.2 |
veos1 | my_site | aggregation | Arista | veos | 10.0.3.1 |
veos2 | my_site | aggregation | Arista | veos | 10.0.3.2 |
ポイントは、IP Address
の列で示されているアドレスです。これは 各 Device でPrimary Address として選出したアドレスです。このアドレスが、インベントリ変数の ansible_host
に変換され、Ansible が接続する先の情報として利用されます。
■ 環境の準備
以下のものを利用します。
- Ansible 2.9.1
- NetBox 2.6.7
- pynetbox 4.2.2
- Python 3.6
NetBox は、以前の記事の「NetBox の準備」で構築済みです。
Ansible 側には pip install pynetbox
で pynetbox
をインストールしておきます。
なお、Ansible で利用するのはあくまでも NetBox Inventory Plugin であるため、標準、Collection に関わらず NetBox モジュールは利用しません。
■ インベントリ設定ファイルの準備
NetBox をインベントリーとして利用するために、NetBox Inventory Plugin のお作法に従って簡単なインベントリ設定ファイルを準備します。この設定ファイルを ansible-playbook
コマンドの -i
オプションに指定するという流れです。
以下、簡単なサンプルです。ファイル名は任意です。
- netbox.yml
--- plugin: netbox api_endpoint: http://localhost:32768 token: 0123456789abcdef0123456789abcdef01234567 group_by: - manufacturers
各設定の意味は以下の通りです。
設定名 | 必須 | 概要 |
---|---|---|
plugin |
必須 | NetBox をインベントリーとして利用する場合は netbox 固定 |
api_endpoint |
必須 | NetBox API のベースURL |
token |
必須 | NetBox API の接続に必要なトークン |
group_by |
グループ化する単位を指定、site 、manufacturers などを指定可 |
他にも、https で接続する際の証明書検証の有無を指定する validate_certs
や、フィルターする query_filters
などのオプションもあります。詳細は公式ドキュメントの NetBox Inventory Plugin を参照して下さい。
基本的な準備はここまでです。
■ ansible-inventory
コマンドによる確認
正しく NetBox をインベントリーとして利用できるか確認します。
ここではいきなり Playbook で試さずに、インベントリー単体の確認するためのコマンド ansible-inventory
を利用します。
ホストリストの確認
ansible-inventory
コマンドに --list
をプションをつけると、インベントリのリストを確認できます。
どのような変数が割り当てられているかも確認できます。
- 実行例
$ ansible-inventory -i inventory_nb.yml --list { "_meta": { "hostvars": { "cat1": { "ansible_host": "10.0.1.1", "device_roles": [ "core" ], "device_types": [ "Catalyst" ], "manufacturers": [ "Cisco" ], "primary_ip4": "10.0.1.1", "sites": [ "my_site" ] }, "cat2": { "ansible_host": "10.0.1.2", "device_roles": [ "core" ], "device_types": [ "Catalyst" ], "manufacturers": [ "Cisco" ], "primary_ip4": "10.0.1.2", "sites": [ "my_site" ] }, "veos1": { "ansible_host": "10.0.3.1", "device_roles": [ "aggregation" ], "device_types": [ "veos" ], "manufacturers": [ "Arista" ], "primary_ip4": "10.0.3.1", "sites": [ "my_site" ] }, "veos2": { "ansible_host": "10.0.3.2", "device_roles": [ "aggregation" ], "device_types": [ "veos" ], "manufacturers": [ "Arista" ], "primary_ip4": "10.0.3.2", "sites": [ "my_site" ] } } }, "all": { "children": [ "manufacturers_Arista", "manufacturers_Cisco", "ungrouped" ] }, "manufacturers_Arista": { "hosts": [ "veos1", "veos2" ] }, "manufacturers_Cisco": { "hosts": [ "cat1", "cat2" ] } }
cat1
、cat2
、veos1
、veos2
という 4つの Device があり、それぞれ ansible_host
や device_roles
などの経数が割り当てられていることが確認できます。ansible_host
変数の値が、Ansible が接続に利用する宛先です。
また、インベントリー設定ファイルの group_by
で manufacturers
を指定したことから、manufacturers_Arista
、manufacturers_Cisco
グループと所属ホストの定義がされていることも確認できます。
グループ化の確認
ansible-inventory
コマンドに --graph
をプションをつけると、グループと所属ホストを確認できます。
- 実行例
$ ansible-inventory -i inventory_nb.yml --graph @all: |--@manufacturers_Arista: | |--veos1 | |--veos2 |--@manufacturers_Cisco: | |--cat1 | |--cat2
スタティックなインベントリファイルで表すと
イメージを湧きやすくするため、NetBox で定義されて動的なインベントリを、スタティックなインベントリファイル(ini形式)で表してみます。変数は抜粋してます。
[manufacturers_Arista] veos1 ansible_host=10.0.3.1 veos2 ansible_host=10.0.3.2 [manufacturers_Cisco] cat1 ansible_host=10.0.1.1 cat2 ansible_host=10.0.1.2
ここまでで、ansible-inventory
コマンドによって、正常にインベントリとして認識できていることが確認できました。
■ ansible-playbook
コマンドによる利用
今度は、インベントリを Playbook 実行時に利用します。
変数ファイルによる補足
ここまでの作業で、インベントリ名や ansible_host
変数などは NetBox 上の情報を利用できようになしました。しかし、まだパスワードなど接続に必要な情報がありません。NetBox 本体や、NetBox Inventory Plugin を活用すれば、NetBox 上に情報を集約できるかもしれません。ただ、現時点で実現方法がまだ分からなかったので、Ansible 側に別途変数ファイルを準備して補足することにします。
ここでは、manufacturers_Cisco
グループに所属するホストを対象とします。
group_vars/manufacturers_Cisco.yml
--- ansible_network_os: ios ansible_connection: network_cli ansible_user: testuserxxx ansible_password: testpaswordxxx
Playbook の作成
manufacturers_Cisco
グループを対象にした簡単な Playbook を作成します。
- iso_show.yml
- hosts: manufacturers_Cisco gather_facts: no tasks: - name: show test ios_command: commands: - show version # show version を実行 register: result - name: debug test debug: msg: "{{ result }}" # コマンド実行結果を表示
Playbook の実行
それでは、Playbook を実行します。
$ ansible-playbook -i inventory_nb.yml ios_show.yml PLAY [manufacturers_Cisco] ****************************************************************************************** TASK [show test] **************************************************************************************************** ok: [cat2] ok: [cat1] TASK [debug test] *************************************************************************************************** ok: [cat1] => { "msg": { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "failed": false, "stdout": [ "Cisco IOS XE Software, Version 16.11.01a\n...(略)... ], "stdout_lines": [ [ "Cisco IOS XE Software, Version 16.11.01a", "Cisco IOS Software [Gibraltar], Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 16.11.1a, RELEASE SOFTWARE (fc1)", "Technical Support: http://www.cisco.com/techsupport", "Copyright (c) 1986-2019 by Cisco Systems, Inc.", "Compiled Thu 11-Apr-19 23:59 by mcpre", ...(略)... ] ], "warnings": [ "Platform darwin on host cat1 is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could change this. See https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information." ] } } ok: [cat2] => { "msg": { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "failed": false, "stdout": [ "Cisco IOS XE Software, Version 16.11.01a\n...(略)... ], "stdout_lines": [ [ "Cisco IOS XE Software, Version 16.11.01a", "Cisco IOS Software [Gibraltar], Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 16.11.1a, RELEASE SOFTWARE (fc1)", "Technical Support: http://www.cisco.com/techsupport", "Copyright (c) 1986-2019 by Cisco Systems, Inc.", "Compiled Thu 11-Apr-19 23:59 by mcpre", ...(略)... ] ], "warnings": [ "Platform darwin on host cat2 is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could change this. See https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information." ] } } PLAY RECAP ********************************************************************************************************** cat1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 cat2 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 $
無事に、NetBox 上の Device 情報をインベントリとして利用して Playbook を実行できました。
■ おわりに
NetBox Inventory Plugin を利用することで、NetBox をインベントリとして利用できました。
今回の私のやり方ですが、情報を NetBox に集約しきれなかったのでいまいちかもしれませんが、もっと活用すると良い感じになるかも知れません。
参考 (2020/12/24 追記)
以下の記事では、インベントリに加えて、Config Context を活用してホスト変数も扱う方法が紹介されています。