はじめに
Excelでのインベントリ管理に疲れていませんか?機器が増えるたびにインベントリファイルを手で修正するのは大変かと思います。
以前の記事(【AWS】Amazon EC2にNetBoxコンテナを構築したい)でAWS上にNetBoxのコンテナ環境を構築しました。
今回はその環境を使い、NetBoxに登録されたデバイスの情報をAnsibleのインベントリとして動的に使用します。
これができるようになると、インベントリ管理を 「信頼できる唯一の情報源(SSoT)」であるNetBoxに一元化 し、手動でのインベントリファイル更新作業から解放されます。この記事では、NetBoxに登録済みのメーカー(manufacturers)が異なるデバイスの情報を、Ansible Playbookで取得する方法を解説します。
TL;DR
この記事を読めば、以下のことができるようになります
- NetBoxをAnsibleの動的インベントリとして利用する方法
-
netbox.netbox.nb_inventory
プラグインを使い、デバイス情報をメーカー(manufacturers)などの属性で自動的にグループ化する方法 - NetBoxから取得してグループ化されたホストに対し、
group_vars
を使ってそれぞれ異なる接続情報を割り当てる方法
前提条件
- NetBoxで以下が作成済みであること
-
APIトークン: NetBoxへのAPIアクセスに必要です
-
デバイス: 以下のデバイスが作成済みであること(未記載の情報の設定は任意)
device manufacturers IP Address(※1) cisco01 cisco 192.168.0.1/24 cisco02 cisco 192.168.1.1/24 juniper01 juniper 192.168.2.1/24 juniper02 juniper 192.168.3.1/24 ※1:IP AddressはプライマリIPに設定しておくこと
-
実行環境
- NetBox: v4.2.8
- Ansible実行環境
- ansible-core: 2.15.13
- Python: 3.9.21
- netbox.netbox: 3.21.0
詳細
1. サンプル実装
フォルダ構成
なるべく最小構成にしたいので以下のようにしました。これはAnsibleプロジェクトの基本的な構成でもあるため、他の場面でも応用できます。
-
inventory
-
group_vars
-
manufacturers_cisco.yml
-
manufacturers_juniper.yml
-
-
inventory.yml
-
-
display_host_info.yml
-
ansible-navigator.yml
補足説明
- inventory.yml:NetBoxへの接続情報と、取得したホストをどのようにグループ分けするかを記載したファイル
- manufacturers_cisco.yml:
manufacturers_cisco
グループ専用の変数を記載したファイル - manufacturers_juniper.yml:
manufacturers_juniper
グループ専用の変数を記載したファイル - display_host_info.yml:Netboxから取得した情報を表示するPlaybook
- ansible-navigator.yml:
ansible-navigator
の設定ファイル
inventory.yml
今回の記事で一番大事なのがこのファイルです。このファイルに記載された内容に応じてAnsibleはNetBoxにアクセスし、必要な情報の取得・分類を実施します。
書き方の詳細は、netbox.netbox.nb_inventory inventoryを参考にして下さい。
今回作成したファイルのポイントは下記の通りです。
-
plugin
にnetbox.netbox.nb_inventory
を指定するので、実行環境にはnetbox.netbox Collectionが必要となる -
group_by
に指定した項目で、NetBoxに登録されたデバイスがインベントリでグループ化される- グループ名は、
<group_byに指定した項目>_<デバイスの設定>
になる - 例)
manufacturers
がcisco
のデバイスは、インベントリでmanufacturers_cisco
グループ所属になる - 他にもサイトやデバイスロールなど、NetBoxの様々な情報でグループ化が可能です
- グループ名は、
---
plugin: netbox.netbox.nb_inventory
api_endpoint: http://XXX.XXX.XXX.XXX # NetBoxのURL
token: netbox_token # NetBoxのAPIトークン
group_by:
- manufacturers
manufacturers_cisco.yml
manufacturers_cisco
グループが使用する変数です。
以下はサンプルであり、実際にcisco機器にアクセスする場合はこれ以外の変数も必要なのでご注意ください。
---
ansible_user: cisco_user
ansible_password: cisco_password
![]()
group_vars
の仕組み
Ansibleは、inventory/group_vars
ディレクトリ配下に<グループ名>.yml
というファイル名で変数ファイルを置くと、そのグループに所属するホストに対して 自動的に変数を読み込んでくれます
manufacturers_juniper.yml
manufacturers_juniper
グループが使用する変数です。
以下はサンプルであり、実際にjuniper機器にアクセスする場合はこれ以外の変数も必要なのでご注意ください。
---
ansible_user: juniper_user
ansible_password: juniper_password
display_host_info.yml
NetBoxから取得したホスト情報を表示するPlaybookです。
Username
とPassword
は、manufacturers
に応じて変化します。
詳細は、後述の2. コマンド実行
で確認してください。
---
- name: Display host info
hosts: all
gather_facts: false
tasks:
- name: Debug
ansible.builtin.debug:
msg:
- "Hostname: {{ inventory_hostname }}" # NetBoxのデバイス名が自動で設定されます
- "IP Address: {{ ansible_host }}" # NetBoxのプライマリIPが自動で設定されます
- "Username: {{ ansible_user }}" # group_vars/manufacturers_cisco.yml などから読み込まれます
- "Password: {{ ansible_password }}" # 同上
ansible-navigator.yml
ansible-navigator.ymlについては、最低限の記述をしています。
書き方については、ansible-navigator settingsを参照してください。
---
ansible-navigator:
execution-environment:
container-engine: docker
enabled: true
image: netbox-ee:tag
pull:
policy: never
mode: stdout
2. コマンド実行
インベントリの確認
ansible-navigator inventory
コマンドでホストの情報を取得します。
inventory.yml
のgroup_by
でmanufacturers
を指定したことで、メーカーごとにグループ分けされているのがわかります。
$ ansible-navigator inventory -i inventory/inventory.yml --graph
@all:
|--@ungrouped:
|--@manufacturers_cisco:
| |--cisco01
| |--cisco02
|--@manufacturers_juniper:
| |--juniper01
| |--juniper02
ホスト情報表示用Playbook(display_host_info.yml)実行
Playbookを実行すると、AnsibleはNetBoxに登録されたホストが所属するグループ
(manufacturers_cisco/manufacturers_juniper)に応じて、グループ変数の内容(今回はansible_userとansible_password)を識別していることがわかります。
$ ansible-navigator run display_host_info.yml -i inventory/inventory.yml
PLAY [Display host info] *******************************************************
TASK [Debug] *******************************************************************
ok: [cisco01] => {
"msg": [
"Hostname: cisco01",
"IP Address: 192.168.0.1",
"Username: cisco_user",
"Password: cisco_password"
]
}
ok: [cisco02] => {
"msg": [
"Hostname: cisco02",
"IP Address: 192.168.1.1",
"Username: cisco_user",
"Password: cisco_password"
]
}
ok: [juniper01] => {
"msg": [
"Hostname: juniper01",
"IP Address: 192.168.2.1",
"Username: juniper_user",
"Password: juniper_password"
]
}
ok: [juniper02] => {
"msg": [
"Hostname: juniper02",
"IP Address: 192.168.3.1",
"Username: juniper_user",
"Password: juniper_password"
]
}
PLAY RECAP *********************************************************************
cisco01 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
cisco02 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
juniper01 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
juniper02 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
さいごに
今回は、NetBoxに登録されたデバイス情報をAnsibleの動的インベントリとして利用する方法をご紹介しました。inventory.yml
にgroup_by
を指定するだけで、デバイスの属性に基づいて簡単にホストをグループ化し、それぞれのグループに異なる変数を適用できることがおわかりいただけたかと思います。
これにより、インベントリ情報を「信頼できる唯一の情報源(Single Source of Truth)」であるNetBoxに集約でき、手作業でのインベントリファイル管理の手間を大幅に削減できます!
この記事をきっかけに、ぜひあなたの環境でもネットワーク自動化の第一歩を踏み出してみてください。