Ansible VMware Automation: Manage vSphere, ESXi, and Virtual Machines at Scale
By Luca Berton · Published 2024-01-01 · Category: installation
Automate VMware vSphere with Ansible. Manage virtual machines, snapshots, templates, networks, and datastores using the vmware.vmware and community.vmware.
Introduction
VMware vSphere remains the dominant enterprise virtualization platform, and automating it with Ansible eliminates the manual vCenter click-ops that slow down VM provisioning, patching, and lifecycle management. The vmware.vmware and community.vmware collections provide comprehensive modules for managing every aspect of your vSphere environment.
See also: Ansible VMware Dynamic Inventory: Complete Guide (2026)
Install Collections
# New official collection (recommended for new projects)
ansible-galaxy collection install vmware.vmware
# Community collection (mature, feature-rich)
ansible-galaxy collection install community.vmware
# Python dependencies
pip install pyvmomi vSphere-Automation-SDK-Python
Note: community.vmware.vmware_vm_inventory was deprecated in v5.4.0 and removed in v7.0.0. Migrate to vmware.vmware.vms for dynamic inventory.
Authentication
# Group vars for vCenter connection
# group_vars/vmware.yml
vcenter_hostname: vcenter.example.com
vcenter_username: "{{ vault_vcenter_user }}"
vcenter_password: "{{ vault_vcenter_pass }}"
vcenter_validate_certs: true
vcenter_datacenter: DC01
See also: How to Add a Disk to a VMware VM Using Ansible Playbook
VM Provisioning
Create VM from Template
---
- name: Provision virtual machines
hosts: localhost
connection: local
vars:
vm_template: ubuntu-2404-template
vm_folder: /DC01/vm/Production
vm_datastore: datastore-ssd-01
vm_cluster: Production-Cluster
vm_network: VLAN-100-Production
tasks:
- name: Clone VM from template
community.vmware.vmware_guest:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: "{{ vcenter_validate_certs }}"
datacenter: "{{ vcenter_datacenter }}"
folder: "{{ vm_folder }}"
name: "{{ item.name }}"
template: "{{ vm_template }}"
cluster: "{{ vm_cluster }}"
datastore: "{{ vm_datastore }}"
state: poweredon
hardware:
memory_mb: "{{ item.memory }}"
num_cpus: "{{ item.cpus }}"
num_cpu_cores_per_socket: "{{ item.cores }}"
disk:
- size_gb: "{{ item.disk }}"
type: thin
datastore: "{{ vm_datastore }}"
networks:
- name: "{{ vm_network }}"
ip: "{{ item.ip }}"
netmask: 255.255.255.0
gateway: 10.0.100.1
dns_servers:
- 10.0.0.10
- 10.0.0.11
domain: example.com
type: static
customization:
hostname: "{{ item.name }}"
domain: example.com
dns_servers:
- 10.0.0.10
- 10.0.0.11
wait_for_customization: true
wait_for_customization_timeout: 600
wait_for_ip_address: true
loop:
- { name: web-01, memory: 4096, cpus: 2, cores: 2, disk: 50, ip: 10.0.100.10 }
- { name: web-02, memory: 4096, cpus: 2, cores: 2, disk: 50, ip: 10.0.100.11 }
- { name: db-01, memory: 8192, cpus: 4, cores: 2, disk: 200, ip: 10.0.100.20 }
register: vm_results
- name: Add new VMs to inventory
ansible.builtin.add_host:
name: "{{ item.item.ip }}"
groups: new_vms
ansible_user: ubuntu
loop: "{{ vm_results.results }}"
Bulk VM Provisioning from CSV
- name: Read VM specifications
ansible.builtin.read_csv:
path: vm-specs.csv
register: vm_specs
- name: Provision all VMs
community.vmware.vmware_guest:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: "{{ vcenter_validate_certs }}"
name: "{{ item.name }}"
template: "{{ item.template }}"
datacenter: "{{ vcenter_datacenter }}"
cluster: "{{ item.cluster }}"
folder: "{{ item.folder }}"
state: poweredon
hardware:
memory_mb: "{{ item.memory_mb }}"
num_cpus: "{{ item.cpus }}"
loop: "{{ vm_specs.list }}"
Snapshot Management
- name: VM snapshot management
hosts: localhost
connection: local
tasks:
- name: Create pre-patch snapshot
community.vmware.vmware_guest_snapshot:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: "{{ vcenter_validate_certs }}"
datacenter: "{{ vcenter_datacenter }}"
folder: "{{ vm_folder }}"
name: "{{ item }}"
state: present
snapshot_name: "pre-patch-{{ ansible_date_time.date }}"
description: "Snapshot before monthly patching"
quiesce: true
loop: "{{ groups['patch_targets'] }}"
- name: Remove old snapshots (>7 days)
community.vmware.vmware_guest_snapshot:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: "{{ vcenter_validate_certs }}"
datacenter: "{{ vcenter_datacenter }}"
name: "{{ item }}"
state: absent
snapshot_name: "pre-patch-*"
loop: "{{ groups['patch_targets'] }}"
See also: Configure Ansible Dynamic Inventory for VMware in Simple Steps
Dynamic Inventory
New vmware.vmware.vms Plugin
# inventory/vmware.yml
plugin: vmware.vmware.vms
hostname: vcenter.example.com
username: "{{ lookup('env', 'VMWARE_USER') }}"
password: "{{ lookup('env', 'VMWARE_PASSWORD') }}"
validate_certs: true
resources:
- datacenter:
- DC01
groups:
webservers: "'web' in inventory_hostname"
databases: "'db' in inventory_hostname"
filters:
- runtime.powerState == "POWERED_ON"
Legacy community.vmware Plugin
# inventory/vmware_legacy.yml
plugin: community.vmware.vmware_vm_inventory
strict: false
hostname: vcenter.example.com
username: "{{ lookup('env', 'VMWARE_USER') }}"
password: "{{ lookup('env', 'VMWARE_PASSWORD') }}"
validate_certs: true
with_nested_properties: true
properties:
- name
- guest.ipAddress
- config.cpuCount
- config.memorySizeMB
- runtime.powerState
hostnames:
- config.name
groups:
production: "'Production' in config.folder"
VM Lifecycle Management
- name: Power operations
community.vmware.vmware_guest_powerstate:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: "{{ vcenter_validate_certs }}"
name: "{{ vm_name }}"
state: "{{ desired_state }}" # powered-on, powered-off, restarted, suspended
- name: Resize VM (CPU/RAM)
community.vmware.vmware_guest:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: "{{ vcenter_validate_certs }}"
name: "{{ vm_name }}"
hardware:
memory_mb: 8192
num_cpus: 4
- name: Add disk to VM
community.vmware.vmware_guest_disk:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: "{{ vcenter_validate_certs }}"
datacenter: "{{ vcenter_datacenter }}"
name: "{{ vm_name }}"
disk:
- size_gb: 100
type: thin
datastore: "{{ vm_datastore }}"
scsi_controller: 0
unit_number: 2
- name: Delete decommissioned VMs
community.vmware.vmware_guest:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: "{{ vcenter_validate_certs }}"
name: "{{ item }}"
state: absent
force: true
loop: "{{ decommission_list }}"
Template Management
- name: Convert VM to template
community.vmware.vmware_guest:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: "{{ vcenter_validate_certs }}"
name: ubuntu-2404-base
is_template: true
- name: Create VM from template with content library
community.vmware.vmware_content_deploy_template:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
template: ubuntu-2404-gold
library: Production-Templates
name: new-web-server
datacenter: DC01
datastore: datastore-ssd-01
folder: /DC01/vm/Production
cluster: Production-Cluster
state: present
Best Practices
Use templates — Never build VMs from ISO; always clone from hardened templates Validate certs in production — Only disable for lab environments Dynamic inventory — Migrate fromcommunity.vmware.vmware_vm_inventory to vmware.vmware.vms
Snapshot before changes — Always snapshot before patching or upgrades
Thin provisioning — Use thin disks to optimize storage usage
Wait for customization — Always set wait_for_customization: true for reliable provisioning
Service account — Dedicated vCenter service account with minimum required permissions
Tag VMs — Use vSphere tags for organizing and filtering VMs
FAQ
community.vmware vs vmware.vmware — which to use?
vmware.vmware is the new official collection by Broadcom (VMware). Use it for new projects. community.vmware is more mature with more modules. Both work; migration is recommended for long-term support.
Can I manage ESXi hosts directly?
Yes — connect directly to ESXi with the hostname parameter pointing to the ESXi host instead of vCenter.
How to handle vMotion during automation?
The modules use vCenter API which handles vMotion transparently. VMs are addressed by name, not host location.
Conclusion
Ansible VMware automation transforms vSphere management from manual vCenter operations into repeatable, version-controlled playbooks. From VM provisioning through lifecycle management to decommissioning, every operation becomes auditable and scalable.
Related Articles
• Ansible Multi-Cloud Automation • Ansible Disaster Recovery • Ansible Automation Platform 2.6Category: installation