0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

vSphere上の仮想マシンのAnsibleインベントリをvCenter APIから自動作成してみる

Posted at

この投稿はvExperts Advent Calendar 2025 の9日目の記事です。

概要

最近Ansibleをかなりガッツリ触る機会があり、せっかく学んだので、自宅環境でも活用してみようかなと考えています。
自宅ではvSphereで仮想マシンをメインで利用していることもあり、マシン数がかなり多いので、その環境でまずは利用していこうと思いました。
ただし、Ansible では inventory というファイルで管理対象ホストの一覧やグループ分けを行いますが、結構マシンの増減が激しく、毎回手で書くのは少し面倒くさいなと思っています。

そこでまず思いついた方法としてAnsible公式のVMwareプラグイン(vmware_vm_inventory)を検討しました。
このプラグインではvCenter上の仮想マシン情報を引っ張ってきて、インベントリを自動で生成してくれます。

ただし、1つだけネックな点がありました。
私がやりたいこととしては、以下になります。

  • vCenter上の仮想マシンをinventoryファイルとして作成する
  • 「フォルダ名でグルーピング」だけでなく
  • 多層フォルダ構成を children 付きの階層グループとして表現したい

この中の多層フォルダ構成を上記プラグインでは実現できなさそうでした。
そのため、今回はvCenter APIから仮想マシンやフォルダ情報を取得してきて、inventoryを自動作成してみた、というお話です。

本記事の対象

  • vSphere / vCenter を使っている
  • Ansible でその VM 群を管理したい
  • vSphere のフォルダ構造=Ansible のグループ構造 にしたい

やりたいこと

やりたいことを具体的に整理してみると、例えば以下のようなフォルダ構成だったとします。
image.png

その場合に、以下inventoryファイルのように仮想マシンを列挙しつつ、フォルダ構造で親子階層を維持したい感じです。

[all]
unbound01 ansible_host=192.168.1.11
unbound02 ansible_host=192.168.1.12
vcsa00    ansible_host=192.168.1.20
vrops     ansible_host=192.168.1.21

[folder_vm]
unbound01
unbound02
vcsa00
vrops

[folder_vm_01_core]
unbound01
unbound02
vcsa00
vrops

[folder_vm_01_core_dns]
unbound01
unbound02

[folder_vm_01_core_vmware]
vcsa00
vrops

[folder_vm:children]
folder_vm_01_core

[folder_vm_01_core:children]
folder_vm_01_core_dns
folder_vm_01_core_vmware

inventory生成スクリプトの作成

それでは前述のようなinventoryを作るべく整理をしながら進めていきます。
今回はvCenter APIをPythonのライブラリのpyvmomiから利用していきます。

vCenterに接続する処理

それではまずvCenterに接続する処理を用意します。
ここはpyvmomiのお作法通りに作成を行っておきます。

import ssl
import atexit
import os
from pyVim.connect import SmartConnect, Disconnect
from pyVmomi import vim

VCENTER_HOST = os.getenv('VCENTER_HOST')
VCENTER_USER = os.getenv('VCENTER_USER')
VCENTER_PASSWORD = os.getenv('VCENTER_PASSWORD')
VERIFY_SSL = os.getenv('VERIFY_SSL', 'False').lower() in ('true', '1')

def connect_to_vcenter():
    """vCenter に接続して ServiceInstance を返す。"""
    context = None
    if not VERIFY_SSL:
        context = ssl._create_unverified_context()

    si = SmartConnect(
        host=VCENTER_HOST,
        user=VCENTER_USER,
        pwd=VCENTER_PASSWORD,
        sslContext=context,
    )
    atexit.register(Disconnect, si)
    return si

vCenterの認証情報は以下のようなフォーマットで環境変数にいれておけば問題ないです。

export VCENTER_HOST="vcsa.example.local"
export VCENTER_USER="administrator@vsphere.local"
export VCENTER_PASSWORD="xxxxx"
export VERIFY_SSL="0"

vCenter APIへの接続の動作確認をしておきます。
エラーがでず、接続した状態から仮想マシンの一覧が取れることを見ておきます。

si = connect_to_vcenter()
content = si.RetrieveContent()

view = content.viewManager.CreateContainerView(
    content.rootFolder, [vim.VirtualMachine], True
)
vms = list(view.view)
print(vms)
view.Destroy()

## 出力抜粋
['vim.VirtualMachine:vm-1022', 'vim.VirtualMachine:vm-1020', 'vim.VirtualMachine:vm-1028,....

vCenter APIを使ってのパラメータ取得などの一覧はBroadcomの公式サイトにまとまっているので、ぜひ用途に合わせて参考ください。

フォルダ構造の作成

それでは、各仮想マシンごとに所属しているフォルダ構造の取得の処理を準備していきます。
まず仮想マシンの親フォルダを一覧取得するための処理の作成を行っておきます。

def get_folder_chain(vm):
    chain = []
    parent = vm.parent
    while parent:
        if isinstance(parent, vim.Datacenter):
            break
        if isinstance(parent, vim.Folder):
            chain.append(parent.name)
        parent = parent.parent
    chain.reverse()
    return chain

動作確認しておきます。
先程のvmsから1つマシンを選んで渡してみます。

print(f"仮想マシン名:{vms[0].name}")
print(f"フォルダ構造:{get_folder_chain(vms[0])}")

# 出力例
仮想マシン名:k8s-cl02
フォルダ構造:['vm', '03_APP', 'k8s', 'Control']

上記の結果の場合、k8s-cl02という仮想マシンは、03_APP>k8s>Controlのフォルダ階層になっているという感じですね。
実際にvCenter上のフォルダとも一致しているので、一旦これでよさそうです。
image.png

ここまでvCenter APIから取得できていれば、あとは整形するのみになります。
そのため、残りはgithub掲載として、割愛させていただきます。

最終的な動作

一応作成したもので動作を見た結果、無事に望んでいたinventoryの形式が取得できたことも確認できました。

# 抜粋
[all]
k8s-cl01 ansible_host=192.168.0.236
・・・

[folder_vm]

[folder_vm_01_core]

[folder_vm_01_core_dns]
unbound01 ansible_host=192.168.0.201
・・・

[folder_vm_01_core_vmware]
vcsa00 ansible_host=192.168.0.102
・・・

[folder_vm:children]
folder_vm_01_core
folder_vm_02_work
folder_vm_03_app

[folder_vm_01_core:children]
folder_vm_01_core_dns
folder_vm_01_core_vmware

・・・

実際にansible環境に配置して、コマンドから見ても無事に認識していそうでした。

ansible-inventory -i generated_vcenter.ini --graph

## 出力例
@all:
  |--@ungrouped:
  |--@folder_vm:
  |  |--@folder_vm_01_core:
  |  |  |--@folder_vm_01_core_dns:
  |  |  |  |--unbound01
  |  |  |  |--unbound02
  |  |  |--@folder_vm_01_core_vmware:
  |  |  |  |--vcsa00
  |  |  |  |--vrops
  |  |--@folder_vm_02_work:
  |  |  |--@folder_vm_02_work_bastion:
  |  |  |  |--rhel-bastion
  |  |--@folder_vm_03_app:
  |  |  |--@folder_vm_03_app_k8s:
  |  |  |  |--@folder_vm_03_app_k8s_control:
  |  |  |  |  |--k8s-cl01
  |  |  |  |  |--k8s-cl02
  |  |  |  |  |--k8s-cl03
  |  |  |  |--@folder_vm_03_app_k8s_worker:
  |  |  |  |  |--k8s-wl01
  |  |  |  |  |--k8s-wl02

まとめ

今回はAnsibleのinventoryファイルをvCenter APIから自動生成してみました。
vSphere環境を持っている場合、vCenter APIを使えると何かと便利なのでぜひ活用してみてください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?