VMware vSphere Discovery
The Infracast vSphere plugin connects to VMware vCenter Server using the vSphere API and the govmomi Go library. It discovers the full virtual infrastructure hierarchy — from the vCenter inventory down to individual VM configurations.
How It Works
- Infracast authenticates to vCenter's SOAP/REST API using a read-only service account
- govmomi traverses the vCenter inventory hierarchy (Datacenter → Cluster → Host → VM)
- Resource configurations and metrics are collected
- Results are normalized and written to the Infracast graph
govmomi is VMware's official Go client library for the vSphere API. Infracast uses it to ensure compatibility with vCenter versions from 6.7 through 8.x.
vCenter Read-Only User Setup
Step 1: Create a Read-Only Role
While vCenter includes a built-in Read-Only role, Infracast benefits from a slightly expanded role to access some metadata.
Via vSphere Client:
- Go to Menu → Administration → Access Control → Roles
- Click + Add to create a new role named
Infracast Discovery - Add the following privileges:
| Privilege Category | Required Privileges |
|---|---|
| Global | Global.GlobalTag, Global.SystemTag |
| Datastore | Datastore.Browse |
| Host | Host.Config.NetInfo (read network config) |
| Network | Network.Assign (read network assignments) |
| Resource | Resource.QueryVMotionCompatibility |
| Session | Sessions.ValidateSession |
| vApp | vApp.ApplicationConfig |
| Virtual Machine | VirtualMachine.Config.QueryFTCompatibility, VirtualMachine.Config.Settings |
In practice, the built-in Read-Only role covers 95% of what Infracast needs. Start with that and add specific privileges only if you see NoPermission errors in the logs.
Via CLI (PowerCLI):
# Connect to vCenter
Connect-VIServer -Server vcenter.example.com -User administrator@vsphere.local
# Create the role (Read-Only is privilege ID 1)
$role = New-VIRole -Name "Infracast Discovery" -Privilege (Get-VIPrivilege -Id 1)
Step 2: Create the Service Account
Via vSphere Client:
- Go to Menu → Administration → Single Sign On → Users and Groups
- Select your domain (or use
vsphere.localfor local accounts) - Click Add User: username
infracast, strong password
Via CLI (PowerCLI):
# Add user to vsphere.local domain
$ssoServer = Get-SsoAdminService
$ssoServer.CreateLocalUser("infracast", "SecurePassword123!", "Infracast", "Discovery", "infracast@vsphere.local")
Step 3: Assign the Role to the User
Assign the Infracast Discovery role to the infracast user at the vCenter root level with Propagate to children enabled. This gives read access to all datacenters, clusters, hosts, and VMs.
Via vSphere Client:
- Select the vCenter object in the inventory
- Go to Permissions tab
- Click + to add a permission
- User:
infracast@vsphere.local, Role:Infracast Discovery, check Propagate to children
Via CLI (PowerCLI):
$role = Get-VIRole -Name "Infracast Discovery"
$vcenter = Get-Folder -Type Datacenter | Get-Inventory -NoRecursion | Get-View -Property Name | Where-Object {$_.Name -eq "vcenter.example.com"}
New-VIPermission -Entity (Get-Inventory -Name $vcenter.Name) `
-Principal "VSPHERE.LOCAL\infracast" `
-Role $role `
-Propagate $true
Registering the Credential in Infracast
infracast creds add \
--plugin vmware-vsphere \
--name "vcenter-prod" \
--type vsphere-basic \
--host "vcenter.example.com" \
--username "infracast@vsphere.local" \
--password-file /run/secrets/vcenter-infracast-password \
--tls-verify true \
--ca-cert-file /run/secrets/vcenter-ca.pem # optional
Configuring the Discovery Job
discovery:
jobs:
- name: vsphere-prod
plugin: vmware-vsphere
credential: vcenter-prod
schedule: "0 */6 * * *"
config:
vcenter_url: "https://vcenter.example.com"
port: 443
tls_verify: true
# Scope to specific datacenters (leave empty for all)
datacenters:
- "Production-DC"
- "DR-DC"
# What to collect
collect:
virtual_machines: true
hosts: true
clusters: true
datastores: true
networks: true
resource_pools: true
folders: true
distributed_switches: true
snapshots: true # VM snapshot inventory
vm_guest_info: true # OS type, tools version, IP addresses
host_hardware: true # CPU, memory, NIC details
datastore_usage: true # used/free space metrics
What Gets Discovered
| Category | Resource Types |
|---|---|
| Virtual Machines | Name, UUID, power state, CPU/memory config, guest OS, VMware Tools version, IP addresses (via Guest Info), disk layout, snapshots, annotations/tags |
| ESXi Hosts | Hostname, version, build, CPU model/cores, total memory, power state, maintenance mode, hardware vendor/model, NIC inventory |
| Clusters | Cluster name, DRS config, HA config, member hosts, resource utilization |
| Resource Pools | Name, CPU/memory limits and reservations, shares, parent pool |
| Datastores | Name, type (VMFS/NFS/vSAN), capacity, free space, host mounts, accessibility |
| Networks | Standard port groups, Distributed Virtual Switches (DVS), DVS port groups, VLAN assignments, uplink configuration |
| Folders | Folder hierarchy (VM folders, host folders, network folders, datastore folders) |
| vSAN | Cluster config, disk groups, capacity (if vSAN enabled) |
| Snapshots | VM snapshots — name, creation date, size, snapshot chain depth |
| Tags | vSphere tags and tag categories applied to any inventory object |
govmomi Under the Hood
Infracast uses govmomi's property collector — a highly efficient vSphere API mechanism that retrieves multiple properties from multiple objects in a single network round-trip.
Instead of querying each VM individually:
for each VM:
GET /api/vms/{id}/config # 1 call per VM
GET /api/vms/{id}/network # 1 call per VM
...
govmomi's property collector retrieves everything in bulk:
RetrieveProperties([
{objectType: VirtualMachine, properties: ["config", "network", "guest", ...]},
{objectType: HostSystem, properties: ["hardware", "config", "runtime", ...]},
...
])
# Returns all properties for all objects in one response
This makes discovery significantly faster for large environments — a vCenter with 5,000 VMs can typically be fully enumerated in under 2 minutes.
Troubleshooting
NoPermission errors in logs
Symptom: Discovery partially completes; logs contain NoPermission: 'infracast@vsphere.local' on 'vim.Folder:group-xx'
Cause: The Infracast user is missing a privilege on a specific object.
Fix:
- Identify the privilege from the error message
- Add it to the
Infracast Discoveryrole:
$role = Get-VIRole -Name "Infracast Discovery"
$priv = Get-VIPrivilege -Id "Datastore.Browse"
Set-VIRole -Role $role -AddPrivilege $priv
Certificate/TLS errors
Symptom: Error: x509: certificate has expired or certificate signed by unknown authority
Fix:
# Export vCenter's certificate
echo | openssl s_client -connect vcenter.example.com:443 2>/dev/null | openssl x509 > vcenter-cert.pem
# Update the credential with the cert
infracast creds update --name "vcenter-prod" \
--ca-cert-file vcenter-cert.pem
Or for environments using self-signed certificates where full trust is acceptable:
config:
tls_verify: false
Session timeout during large inventory discovery
Symptom: Discovery fails partway through with NotAuthenticated error
Cause: vCenter sessions expire after a period of inactivity (default: 30 minutes).
Fix: Infracast automatically refreshes sessions, but you can also increase the vCenter session timeout:
# Increase session timeout to 2 hours (in minutes)
$sessionManager = Get-View SessionManager
$sessionManager.UpdateServiceMessage($null, 120)
Or configure Infracast to use keepalive pings:
config:
session_keepalive_interval_seconds: 300
VMs with missing IP addresses
Symptom: VMs appear in the inventory but have no IP addresses
Cause: VMware Tools must be running in the VM for the Guest Info API to return IP data.
Fix: This is an expected limitation. IPs are only available for VMs where:
- VMware Tools (or open-vm-tools) is installed and running
- The VM is powered on
Infracast will still discover the VM's MAC addresses and can correlate with ARP data from network discovery.
Slow discovery on large inventories
Symptom: Discovery jobs run for more than 30 minutes
Fix: Narrow the scope to specific datacenters:
config:
datacenters:
- "Production-DC" # exclude DR and dev
collect:
snapshots: false # snapshots can be slow to enumerate
vm_guest_info: true
Also verify that vCenter's database isn't under heavy load — vCenter performance impacts API response times.
Linked Mode vCenter
For Linked Mode vCenter deployments (multiple vCenter servers joined), connect to each vCenter individually with separate jobs:
discovery:
jobs:
- name: vsphere-vcenter-01
plugin: vmware-vsphere
credential: vcenter-01-cred
config:
vcenter_url: "https://vcenter01.example.com"
datacenters: ["East-DC"]
- name: vsphere-vcenter-02
plugin: vmware-vsphere
credential: vcenter-02-cred
config:
vcenter_url: "https://vcenter02.example.com"
datacenters: ["West-DC"]