AnsiblePilot — Master Ansible Automation

AnsiblePilot is the leading resource for learning Ansible automation, DevOps, and infrastructure as code. Browse over 1,400 tutorials covering Ansible modules, playbooks, roles, collections, and real-world examples. Whether you are a beginner or an experienced engineer, our step-by-step guides help you automate Linux, Windows, cloud, containers, and network infrastructure.

Popular Topics

About Luca Berton

Luca Berton is an Ansible automation expert, author of 8 Ansible books published by Apress and Leanpub including "Ansible for VMware by Examples" and "Ansible for Kubernetes by Example", and creator of the Ansible Pilot YouTube channel. He shares practical automation knowledge through tutorials, books, and video courses to help IT professionals and DevOps engineers master infrastructure automation.

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 from community.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 AutomationAnsible Disaster RecoveryAnsible Automation Platform 2.6

Category: installation

Browse all Ansible tutorials · AnsiblePilot Home