NTNX>日記

個人的な趣味による Nutanix Community Edition 日記。Japanese のみですみません。

Nutanix から仮想マシンを取得する Ansible Dynamic Inventory を作成してみる。(REST API v2)

Ansible で、Prism Element から仮想マシンを取得する Dynamic Inventory スクリプトを作成して、パワーオン / パワーオフの仮想マシンをグループ化できるようにしてみました。

Nuatnix の Ansible モジュールは nutanix.ncp コレクションが用意されていますが、この Dynamic Inventory スクリプトは古い(2019 年に作成した)ものなので nutanix.ncp とは関係していません。

今回の内容です。

今回の実行環境

Ansible

今回の Ansible は、Oracle Linux 8 で実行します。

[root@demo-ansible-01 ~]# cat /etc/oracle-release
Oracle Linux Server release 8.7

Ansible を RPM でインストールします。

[root@demo-ansible-01 ~]# dnf install oracle-epel-release-el8 -yq
[root@demo-ansible-01 ~]# dnf install ansible -yq
[root@demo-ansible-01 ~]# dnf install python3-requests -yq
[root@demo-ansible-01 ~]# alternatives --set python /usr/bin/python3

インストールされた Ansible と Python のバージョンです。

[root@demo-ansible-01 ~]# ansible --version
ansible 2.9.27
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.6/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.6.8 (default, Feb 21 2023, 05:30:22) [GCC 8.5.0 20210514 (Red Hat 8.5.0-16.0.2)]
[root@demo-ansible-01 ~]# python -V
Python 3.6.8

Nutanix

Nutanix は Community Edition 2.0(fraser-6.5.2-stable)を利用しています。nutanix.ncp では基本的に Prism Central に接続しますが、今回のスクリプトでの接続先は Prism Element を指定しています。

Dynamic Inventory の Python スクリプト

下記のような Python スクリプトを作成しました。

ahv_inventory.py

gist.github.com

スクリプトには、実行権限を付与しておきます。

$ chmod +x ./ahv_inventory.py

prism-config.json

Prism Element への接続情報を記載したファイルを作成しておきます。このファイルのパスは、スクリプトの10行目に記載してあります。

{
    "prism_address": "lab-nxce-01.go-lab.jp",
    "user_name": "admin",
    "password": "nutanix/4u"
}

インベントリ情報の様子

作成したスクリプトを ansible、ansible-inventory、ansible-playbook コマンドのインベントリとして指定すると、下記のように all / poweroff_vms / poweron_vms でグループ化された仮想マシンが取得できます。

ansible-inventory --graph の様子です。このとき、インベントリに CVM は含まれませんが、Prism Central の CVM は含まれています。

$ ansible-inventory --graph -i ./ahv_inventory.py
@all:
  |--@poweroff_vms:
  |  |--ol87-min-01
  |  |--ol91-min-01
  |  |--vm03
  |--@poweron_vms:
  |  |--demo-ansible-01
  |  |--lab-nxpc-01
  |  |--vm01
  |  |--vm02
  |--@ungrouped:

ansible-inventory --list の様子です。

$ ansible-inventory --list -i ./ahv_inventory.py
{
    "_meta": {
        "hostvars": {
            "demo-ansible-01": {
                "ansible_host": "192.168.11.129",
                "power_state": "on"
            },
            "lab-nxpc-01": {
                "ansible_host": "192.168.20.15",
                "power_state": "on"
            },
            "ol87-min-01": {
                "ansible_host": "192.168.11.116",
                "power_state": "off"
            },
            "ol91-min-01": {
                "ansible_host": "192.168.11.139",
                "power_state": "off"
            },
            "vm01": {
                "ansible_host": "192.168.11.115",
                "power_state": "on"
            },
            "vm02": {
                "ansible_host": "192.168.11.102",
                "power_state": "on"
            },
            "vm03": {
                "ansible_host": "192.168.11.103",
                "power_state": "off"
            }
        }
    },
    "all": {
        "children": [
            "poweroff_vms",
            "poweron_vms",
            "ungrouped"
        ]
    },
    "poweroff_vms": {
        "hosts": [
            "ol87-min-01",
            "ol91-min-01",
            "vm03"
        ]
    },
    "poweron_vms": {
        "hosts": [
            "demo-ansible-01",
            "lab-nxpc-01",
            "vm01",
            "vm02"
        ]
    }
}

ansible-inventory --host の様子です。

$ ansible-inventory -i ./ahv_inventory.py --host vm01
{
    "ansible_host": "192.168.11.115",
    "power_state": "on"
}

Playbook の実行例

今回は、パワーオン状態の仮想マシン(vm01、vm02)にタスクを実行してみます。

vm01 と vm02 には、あらかじめ ansible を実行するユーザの SSH 公開鍵をコピーしてあります。

Playbook 実行時のエラーと警告を抑止するため、ansible.cfg を作成して下記を記載しておきます。

ansible.cfg

[defaults]
host_key_checking = false
action_warnings = false

パワーオンされている仮想マシンから、Prism Central と、Ansible 実行元マシンを除外するため、静的なインベントリのファイルも作成しておきます。ここでは、management_vms グループに除外対象の仮想マシン名を記載しておきます。

inventory.ini

[management_vms]
lab-nxpc-01
demo-ansible-01

ping モジュールで SSH 接続確認する Playbook を作成して実行してみます。この Playbook の hosts では、Dynamic Inventory による poweron_vms グループから、management_vms グループを除外します。

ping.yml

- name: test
  hosts: poweron_vms:!management_vms
  remote_user: root
  tasks:
  - name: ping test
    ping:

Playbook を実行すると、vm01 と vm02 にタスクが実行されました。

$ ansible-playbook -i ./ahv_inventory.py -i ./inventory.ini ./ping.yml

PLAY [test] ************************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************
ok: [vm01]
ok: [vm02]

TASK [ping test] *******************************************************************************************************
ok: [vm01]
ok: [vm02]

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

インベントリファイルとスクリプトを inventory ディレクトリに集約しておきます。ファイル名の拡張子が .ini だと読み飛ばされてしまうため、inventory.ini ファイルはリネームしておきます。

$ mkdir inventory
$ mv ahv_inventory.py inventory/
$ mv inventory.ini inventory/management_vms

ansible.cfg でも、インベントリ ファイルを集約したディレクトリを指定(inventory = ./inventory)しておきます。

$ cat ansible.cfg
[defaults]
host_key_checking = false
action_warnings = false
inventory = inventory

動作確認として、bind-utils.yml ファイルを用意しておきます。management_vms を除くパワーオンの仮想マシンに、bind-utils をインストールしてみます。

$ cat ./bind-utils.yml
- name: Install bind-utils
  hosts: poweron_vms:!management_vms
  remote_user: root
  tasks:
  - name: Install bind-utils rpm
    dnf:
      name: bind-utils

Playbook を実行すると、さきほどの ping.yml と同様に hosts を指定していますが、-i オプションを省略してインベントリを取得できます。

$ ansible-playbook ./bind-utils.yml

PLAY [Install bind-utils] **********************************************************************************************

TASK [Gathering Facts] *************************************************************************************************
ok: [vm02]
ok: [vm01]

TASK [Install bind-utils rpm] ******************************************************************************************
changed: [vm02]
changed: [vm01]

PLAY RECAP *************************************************************************************************************
vm01                       : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
vm02                       : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

vm01 を確認すると、RPM がインストールされたことがわかります。

$ ansible-inventory --host vm01
{
    "ansible_host": "192.168.11.115",
    "power_state": "on"
}
$ ssh root@192.168.11.115 "uname -n; rpm -q bind-utils"
vm01
bind-utils-9.11.36-5.el8_7.2.x86_64
$ ansible vm01 -u root -m shell -a "uname -n; rpm -q bind-uti
ls"
vm01 | CHANGED | rc=0 >>
vm01
bind-utils-9.11.36-5.el8_7.2.x86_64

以上。

©2023 gowatana
クリエイティブ・コモンズ・ライセンスこの 作品 は クリエイティブ・コモンズ 表示 4.0 国際 ライセンスの下に提供されています。