以前REST APIを使った入力を試したけど、今回はAnsibleのNetboxモジュールを使った入力について。
準備
pynetbox のインストール
NetBoxをAnsibleから操作する場合は、基本的に(全部チェックしたわけじゃないけどたぶん)全てpynetbox
モジュールが必要。
pip
でインストールする。
$ pip install pynetbox
無いとエラー。
TASK [create vm sample] ******************************************************* An exception occurred during task execution. To see the full traceback, use -vvv. The error was: ModuleNotFoundError: No module named 'pynetbox' failed: [localhost] (item=k8s-master01) => changed=false ansible_loop_var: item item: k8s-master01 msg: Failed to import the required Python library (pynetbox) on cloud-dev's Python /home/zaki/src/ansible-sample/venv/a2.10/bin/python3. Please read the module documentation and install it in the appropriate location. If the required library is installed, but Ansible is using the wrong Python interpreter, please consult the documentation on ansible_python_interpreter
netbox.netboxコレクション
Ansible 2.10のフルセット(pip install ansible
でインストールした場合)はNetBoxのコレクションが含まれるので追加インストールは不要。
Ansible 2.10をansible-base
でインストールした場合、また、Ansible 2.9の場合は、netbox.netbox
コレクションが追加で必要なのでansible-galaxy
でインストールする。
ansible-galaxy collection install netbox.netbox
Playbookサンプル
全部をチェックしたわけじゃないけど、VMの作成を試してみた限りでは「REST APIをAnsibleモジュールでラッピングしている」感じ。
なので、RESTを使った操作をチェックすればAnsibleモジュールの使い方もそのまま行ける。
ただ、RESTと違ってIDでなくVM名とかをそのまま使うことができてわかりやすい。
また、既にある場合はok
となって冪等な処理になり、VM名はそのままで例えばstatusを変更すれば「更新」動作になるので使い勝手は良い。
APIエンドポイントとトークン
各モジュールで共通して以下のパラメタが用意されている。
netbox_url
netbox_token
書いてみればすぐわかるけど、さらにdata
といパラメタに、モジュールに対するパラメタ(つまりNetBoxへ操作を行いたいパラメタ)を指定していく。
基本的にNetBoxのweb上の画面とモジュールのドキュメントのExampleを見比べれば使い方は雰囲気でわかるはず。
VM作成
- name: create vm sample netbox.netbox.netbox_virtual_machine: netbox_url: "{{ netbox_url }}" netbox_token: "{{ netbox_token }}" data: name: "{{ item }}" cluster: vm network with_items: - k8s-master01
RESTだと必須だったclusterはドキュメントにはRequired設定されてないが、やっぱり必須。
cluster
を指定しなかったらこの通り。
TASK [create vm sample] ******************************************************* failed: [localhost] (item=k8s-master01) => changed=false ansible_loop_var: item item: k8s-master01 msg: '{"cluster":["This field is required."]}'
cluster
を指定(RESTの場合と異なり、clusterのIDでなくcluster名の文字列を指定)して実行すればこの通り。
(a2.10) [zaki@cloud-dev netbox (master)]$ ansible-playbook sample.yml -v Using /home/zaki/src/ansible-sample/netbox/ansible.cfg as config file [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' PLAY [localhost] ************************************************************** TASK [create vm sample] ******************************************************* changed: [localhost] => (item=k8s-master01) => changed=true ansible_loop_var: item item: k8s-master01 msg: virtual_machine k8s-master01 created virtual_machine: cluster: 3 comments: '' config_context: {} created: '2021-01-13' custom_fields: {} disk: null id: 7 last_updated: '2021-01-13T13:54:24.961868Z' local_context_data: null memory: null name: k8s-master01 platform: null primary_ip: null primary_ip4: null primary_ip6: null role: null site: 1 status: active tags: [] tenant: null url: http://192.168.0.19:28080/api/virtualization/virtual-machines/7/ vcpus: null PLAY RECAP ******************************************************************** localhost : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
VM情報が登録されたのち、同じPlaybookで再実行するとok
になり変化しない。
(a2.10) [zaki@cloud-dev netbox (master)]$ ansible-playbook sample.yml -v Using /home/zaki/src/ansible-sample/netbox/ansible.cfg as config file [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' PLAY [localhost] ************************************************************** TASK [create vm sample] ******************************************************* ok: [localhost] => (item=k8s-master01) => changed=false ansible_loop_var: item item: k8s-master01 msg: virtual_machine k8s-master01 already exists virtual_machine: cluster: 3 comments: '' config_context: {} created: '2021-01-13' custom_fields: {} disk: null id: 7 last_updated: '2021-01-13T13:54:24.961868Z' local_context_data: null memory: null name: k8s-master01 platform: null primary_ip: null primary_ip4: null primary_ip6: null role: null site: 1 status: active tags: [] tenant: null url: http://192.168.0.19:28080/api/virtualization/virtual-machines/7/ vcpus: null PLAY RECAP ******************************************************************** localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 (a2.10) [zaki@cloud-dev netbox (master)]$
以下についてもRESTのときとまったく同じ要領。
ただし前述の通り、IDでなく名前を指定する。
- ネットワークインタフェース作成 (
netbox_vm_interface_module
) - IPアドレス作成とインタフェースへアサイン (
netbox_ip_address
) - IPアドレスのPrimary設定 (
netbox_vm_interface_module
でprimary_ip4
指定)
インベントリ変数やvarsなどで変数化しておけば、Primary設定のための「VM情報の更新」を行うnetbox_virtual_machine
モジュール再実行も上記リンク先のサンプルのように簡単にできるはず。
Clusterの作成
せっかくなのでVM作成のパラメタのClusterも作成してみる。
Clusterの作成にはCluster Typeが必須なので、これもセットで作る。
作成に使用するパラメタをYAMLで変数定義しておく。
cluster: vm network cluster_type: name: ESXi slug: esxi
これに対して、「Cluster Type作成 (netbox_cluster_type
)」と「Cluster作成 (netbox_cluster
)」が順に実行されるようにplaybookを書けばOK。
- name: create cluster-type netbox.netbox.netbox_cluster_type: netbox_url: "{{ netbox_url }}" netbox_token: "{{ netbox_token }}" data: name: "{{ cluster_type.name }}" slug: "{{ cluster_type.slug }}" - name: create cluster netbox.netbox.netbox_cluster: netbox_url: "{{ netbox_url }}" netbox_token: "{{ netbox_token }}" data: name: "{{ cluster }}" cluster_type: "{{ cluster_type }}"
こんな感じ。
環境
NetBoxのバージョンはv2.10.3 (構築時と同じ)
Ansibleは以下の2パターンで確認。
Ansible 2.10
ansible 2.10.2 config file = /home/zaki/src/ansible-sample/netbox/ansible.cfg configured module search path = ['/home/zaki/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /home/zaki/src/ansible-sample/venv/a2.10/lib64/python3.6/site-packages/ansible executable location = /home/zaki/src/ansible-sample/venv/a2.10/bin/ansible python version = 3.6.8 (default, Nov 16 2020, 16:55:22) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
- pynetbox: 5.3.0
- netbox.netbox collections: 1.1.0
Ansible 2.9
ansible 2.9.16 config file = /home/zaki/src/ansible-sample/netbox/ansible.cfg configured module search path = ['/home/zaki/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /home/zaki/src/ansible-sample/venv/2.9/lib64/python3.6/site-packages/ansible executable location = /home/zaki/src/ansible-sample/venv/2.9/bin/ansible python version = 3.6.8 (default, Nov 16 2020, 16:55:22) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
- pynetbox: 5.3.1
- netbox.netbox collections: 2.0.0
あれ?いつのまにか2.0.0になってた。
サンプルコード
今回は「基本的に」が多いな。。触ってみたモジュールはだいたい同じ使い勝手だったけど、使い方が全く違うものが有るかもしれないし無いかもしれない(^^;
RESTを使った場合はこちら。