この投稿は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 のグループ構造 にしたい
やりたいこと
やりたいことを具体的に整理してみると、例えば以下のようなフォルダ構成だったとします。

その場合に、以下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上のフォルダとも一致しているので、一旦これでよさそうです。

ここまで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を使えると何かと便利なのでぜひ活用してみてください。