Instead of clicking around vCenter, we write a single Ansible playbook that handles any VM. AWX gives it a web form (called a survey) so anyone can run it without touching the command line.

Each playbook does one thing. No hardcoded VM names and everything comes in as a variable at runtime so we will add playbooks in this format.
playbooks/
├── get_all_vms.yml ← inventory
├── get_vm_info.yml ← VM details
├── vm_hardware.yml ← change RAM/CPU
├── vm_snapshot.yml ← snapshot management
├── vm_power.yml ← power on/off/restart
├── vm_deploy.yml ← deploy from template
├── vm_delete.yml ← delete VM
├── vm_network.yml ← change network
└── vm_disk.yml ← add/expand disk
Add a new playbook to vm_deploy.yml
---
- name: Deploy VM from Template
hosts: localhost
gather_facts: false
connection: local
become: false
vars:
sizes:
small: { cpu: 2, ram_mb: 4096 }
medium: { cpu: 4, ram_mb: 8192 }
large: { cpu: 8, ram_mb: 16384 }
xlarge: { cpu: 16, ram_mb: 32768 }
tasks:
- name: Validate template
fail:
msg: "Invalid template! Must be: windows2019_template, windows2022_template"
when: template_name not in ['windows2019_template', 'windows2022_template']
- name: Validate size
fail:
msg: "Invalid size! Must be: small, medium, large, xlarge"
when: size not in ['small', 'medium', 'large', 'xlarge']
- name: Set hardware from size
set_fact:
vm_cpu: "{{ sizes[size].cpu }}"
vm_ram_mb: "{{ sizes[size].ram_mb }}"
- name: Show deployment plan
debug:
msg:
- "=== DEPLOYMENT PLAN ==="
- "New VM Name : {{ vm_name }}"
- "Template : {{ template_name }}"
- "Size : {{ size }}"
- "CPUs : {{ vm_cpu }}"
- "RAM (GB) : {{ (vm_ram_mb | int / 1024) | int }}GB"
- "Datastore : {{ datastore | default('NVMe -01') }}"
- "Customization : vm_customization"
- name: Deploy VM from template
community.vmware.vmware_guest:
hostname: "{{ lookup('env', 'VMWARE_HOST') }}"
username: "{{ lookup('env', 'VMWARE_USER') }}"
password: "{{ lookup('env', 'VMWARE_PASSWORD') }}"
validate_certs: false
datacenter: "Datacenter"
cluster: "Cluster"
folder: "/Datacenter/vm"
name: "{{ vm_name }}"
template: "{{ template_name }}"
datastore: "{{ datastore | default('SmallDatastore') }}"
customization_spec: "vm_customization"
hardware:
memory_mb: "{{ vm_ram_mb }}"
num_cpus: "{{ vm_cpu }}"
state: poweredoff
register: deploy_result
- name: Show result
debug:
msg:
- "=== VM DEPLOYED ==="
- "VM Name : {{ vm_name }}"
- "Template : {{ template_name }}"
- "Size : {{ size }} ({{ vm_cpu }}CPU / {{ (vm_ram_mb | int / 1024) | int }}GB RAM)"
- "Status : {{ deploy_result.instance.hw_power_status }}"
Deploy a VM via our Windows 2022 template
ansible-playbook /etc/ansible/playbooks/vm_deploy.yml -e "vm_name=test-vm-03 template_name=windows2022_template size=small"Deploy a VM via our Windows 2019 template
ansible-playbook /etc/ansible/playbooks/vm_deploy.yml -e "vm_name=test-vm-04 template_name=windows2019_template size=small"
That is a clean install

Lets run the git and push it all

AWX → Projects → VMware Automation → Sync


