Skip to main content

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

  1. Infracast authenticates to vCenter's SOAP/REST API using a read-only service account
  2. govmomi traverses the vCenter inventory hierarchy (Datacenter → Cluster → Host → VM)
  3. Resource configurations and metrics are collected
  4. Results are normalized and written to the Infracast graph
info

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:

  1. Go to Menu → Administration → Access Control → Roles
  2. Click + Add to create a new role named Infracast Discovery
  3. Add the following privileges:
Privilege CategoryRequired Privileges
GlobalGlobal.GlobalTag, Global.SystemTag
DatastoreDatastore.Browse
HostHost.Config.NetInfo (read network config)
NetworkNetwork.Assign (read network assignments)
ResourceResource.QueryVMotionCompatibility
SessionSessions.ValidateSession
vAppvApp.ApplicationConfig
Virtual MachineVirtualMachine.Config.QueryFTCompatibility, VirtualMachine.Config.Settings
tip

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:

  1. Go to Menu → Administration → Single Sign On → Users and Groups
  2. Select your domain (or use vsphere.local for local accounts)
  3. 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:

  1. Select the vCenter object in the inventory
  2. Go to Permissions tab
  3. Click + to add a permission
  4. 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

infracast.yaml
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

CategoryResource Types
Virtual MachinesName, UUID, power state, CPU/memory config, guest OS, VMware Tools version, IP addresses (via Guest Info), disk layout, snapshots, annotations/tags
ESXi HostsHostname, version, build, CPU model/cores, total memory, power state, maintenance mode, hardware vendor/model, NIC inventory
ClustersCluster name, DRS config, HA config, member hosts, resource utilization
Resource PoolsName, CPU/memory limits and reservations, shares, parent pool
DatastoresName, type (VMFS/NFS/vSAN), capacity, free space, host mounts, accessibility
NetworksStandard port groups, Distributed Virtual Switches (DVS), DVS port groups, VLAN assignments, uplink configuration
FoldersFolder hierarchy (VM folders, host folders, network folders, datastore folders)
vSANCluster config, disk groups, capacity (if vSAN enabled)
SnapshotsVM snapshots — name, creation date, size, snapshot chain depth
TagsvSphere 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:

  1. Identify the privilege from the error message
  2. Add it to the Infracast Discovery role:
$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"]