9.2 KiB
VM Provisioning Workflow
This directory contains playbooks for provisioning Windows Server VMs on Hyper-V with automated installation.
Quick Start
1. Provision a new VM
# Activate virtual environment
source ~/.venv/ansible/bin/activate
# Run with ansible-navigator (recommended for development)
ansible-navigator run playbooks/provision-vm.yml \
--execution-environment-image aap.toal.ca/ee-demo \
--extra-vars "vm_name=WEB01 vm_ip_address=192.168.1.101"
# Or run directly with ansible-playbook
ansible-playbook playbooks/provision-vm.yml \
-e vm_name=WEB01 \
-e vm_ip_address=192.168.1.101 \
-e vm_cpu_count=4 \
-e vm_memory_gb=8
2. Monitor Installation
The playbook will:
- ✓ Create the VM with specified resources
- ✓ Generate autounattend.xml for unattended installation
- ✓ Attach Windows Server ISO
- ✓ Start the VM
- ⏸ Pause for manual verification of installation
Manual Steps:
- Watch VM through Hyper-V Manager or connect via console
- Verify Windows installation progresses automatically
- Wait for system to reach login screen (15-30 minutes)
- Verify WinRM is configured (check if port 5985 is listening)
3. Verify VM
# Test WinRM connectivity
ansible WEB01 -i "192.168.1.101," -m ansible.windows.win_ping
# Or run verification tag
ansible-playbook playbooks/provision-vm.yml -e vm_name=WEB01 --tags verify
4. Add to Inventory
# Edit the inventory file
vi /home/ptoal/Dev/inventories/toallab-inventory/static.yml
# Add under appropriate group (web_servers, app_servers, db_servers):
web_servers:
hosts:
WEB01:
ansible_host: 192.168.1.101
5. Run Baseline Configuration
# Apply Windows baseline configuration (future)
ansible-playbook playbooks/windows-baseline.yml --limit WEB01
# Deploy applications
ansible-playbook playbooks/install-iis.yml --limit WEB01
Variables
Required Variables
| Variable | Description | Example |
|---|---|---|
vm_name |
Name of the VM to create | WEB01 |
Optional Variables
| Variable | Description | Default | Example |
|---|---|---|---|
vm_ip_address |
Static IP address | DHCP | 192.168.1.101 |
vm_cpu_count |
Number of CPU cores | 2 |
4 |
vm_memory_gb |
Memory in GB | 4 |
8 |
vm_disk_size_gb |
Disk size in GB | 60 |
100 |
vm_admin_password |
Initial admin password | P@ssw0rd123! |
SecureP@ss! |
vm_gateway |
Default gateway | 192.168.1.1 |
192.168.1.1 |
vm_subnet_prefix |
Subnet prefix length | 24 |
24 |
dns_servers |
DNS server list | From group_vars | ['8.8.8.8'] |
Variables from Group Vars
The following are automatically loaded from group_vars:
default_vm_cpu_count,default_vm_memory_gb,default_vm_disk_size_gbdefault_vm_switch- Hyper-V virtual switch namevm_storage_path- Base path for VM filesiso_storage_path- Path to ISO fileswindows_server_iso- Path to Windows Server ISOdns_servers- Default DNS serverstimezone- Windows timezone setting
Playbook Tags
Run specific parts of the playbook using tags:
# Only create VM configuration (skip installation)
ansible-playbook provision-vm.yml -e vm_name=WEB01 --tags create
# Only install/start VM
ansible-playbook provision-vm.yml -e vm_name=WEB01 --tags install
# Only verify VM status
ansible-playbook provision-vm.yml -e vm_name=WEB01 --tags verify
AutoUnattend.xml
The playbook generates an autounattend.xml file that automates Windows installation with:
- Partitioning: Automatic disk partitioning (500MB system, rest for Windows)
- Locale: en-US language and keyboard
- Computer Name: Set to
vm_name - Timezone: From
timezonevariable - Administrator Password: From
vm_admin_password - Network: Static IP if
vm_ip_addressis provided - RDP: Enabled with firewall rules
- WinRM: Enabled with firewall rules
- Firewall: Initially disabled for setup
Using AutoUnattend.xml
Windows Setup will automatically use autounattend.xml if it's found in one of these locations:
- Root of installation media (requires rebuilding ISO)
- Root of removable media (floppy, USB, second CD drive)
- Mounted as additional DVD drive (easiest for Hyper-V)
Method 1: Second DVD Drive (Recommended)
# Run helper playbook to create and mount autounattend ISO
ansible-playbook playbooks/create-autounattend-iso.yml -e vm_name=WEB01
Method 2: Manual ISO Creation
# On Hyper-V host
# 1. Create ISO with autounattend.xml in root
# Use oscdimg (from Windows ADK) or ImgBurn
# 2. Mount as second DVD drive
Add-VMDvdDrive -VMName "WEB01" -Path "D:\VMs\WEB01\autounattend.iso"
Method 3: Custom Windows ISO
Rebuild Windows ISO with autounattend.xml embedded:
- Extract Windows ISO
- Copy autounattend.xml to root
- Rebuild ISO with oscdimg
- Use custom ISO for installation
Ansible Automation Platform Integration
Job Template Configuration
Name: Provision Windows VM
Playbook: playbooks/provision-vm.yml
Inventory: ToalLab
Credentials:
- Machine Credential:
Hyper-V WinRM
Limit: hyperv
Survey:
| Prompt | Variable | Type | Default | Required |
|---|---|---|---|---|
| VM Name | vm_name |
Text | - | Yes |
| IP Address | vm_ip_address |
Text | - | No |
| CPU Count | vm_cpu_count |
Integer | 2 | No |
| Memory (GB) | vm_memory_gb |
Integer | 4 | No |
| Disk Size (GB) | vm_disk_size_gb |
Integer | 60 | No |
Webhook: Enable for GitOps workflow
Workflow Template (Future)
Name: Full VM Lifecycle
Nodes:
- Provision VM →
provision-vm.yml - Wait for Installation → Manual approval
- Windows Baseline →
windows-baseline.yml - Deploy Application →
install-iis.yml - Update CMDB →
sync-cmdb.yml
Troubleshooting
VM Creation Failed
# Check Hyper-V host connectivity
ansible hyperv -m ansible.windows.win_ping
# Verify paths exist
ansible hyperv -m ansible.windows.win_file -a "path=D:\\VMs state=directory"
# Check ISO exists
ansible hyperv -m ansible.windows.win_stat -a "path=D:\\ISOs\\Windows_Server_2022.iso"
AutoUnattend.xml Not Working
Symptoms: Windows installation shows interactive prompts
Causes:
- AutoUnattend.xml not found by Windows Setup
- XML syntax error
- Missing required sections
Solutions:
- Verify autounattend.xml is in correct location
- Check XML is valid (use XMLLint or online validator)
- Review Windows Setup logs in VM:
C:\Windows\Panther\setupact.log
WinRM Not Available After Installation
Symptoms: Cannot connect via win_ping
Causes:
- First logon commands didn't run
- Firewall blocking WinRM
- Wrong credentials
Solutions:
# Connect to VM console through Hyper-V Manager
# Check if first logon commands ran:
Get-Service WinRM
Test-WSMan
# Manually enable WinRM if needed:
Enable-PSRemoting -Force
Set-Item WSMan:\localhost\Service\Auth\Basic -Value $true
# Check firewall:
Get-NetFirewallRule -Name "WINRM-HTTP-In-TCP"
Installation Hangs
Symptoms: VM stuck at Windows Setup screen
Causes:
- ISO not bootable
- Insufficient resources
- Hardware compatibility issues
Solutions:
- Increase VM memory (minimum 2GB for Windows Server)
- Verify ISO integrity
- Check Hyper-V event logs
- Try Generation 1 VM instead of Generation 2
Advanced Usage
Provision Multiple VMs
# Create a loop or use separate job templates in AAP
for vm in WEB01 WEB02 WEB03; do
ansible-playbook provision-vm.yml -e vm_name=$vm -e vm_ip_address=192.168.1.$((100 + ${vm: -1}))
done
Custom Windows Edition
Edit the ISO or autounattend.xml to specify edition:
<ImageInstall>
<OSImage>
<InstallFrom>
<MetaData wcm:action="add">
<Key>/IMAGE/NAME</Key>
<Value>Windows Server 2022 SERVERDATACENTER</Value>
</MetaData>
</InstallFrom>
</OSImage>
</ImageInstall>
Domain Join During Installation
Add to autounattend.xml under <Identification>:
<Credentials>
<Domain>example.com</Domain>
<Password>DomainJoinPassword</Password>
<Username>DomainJoinUser</Username>
</Credentials>
<JoinDomain>example.com</JoinDomain>
Files Generated
After running provision-vm.yml, these files are created on the Hyper-V host:
D:\VMs\<vm_name>\
├── <vm_name>.vhdx # Virtual hard disk
├── autounattend.xml # Unattended installation answer file
└── Virtual Machines\ # VM configuration files (created by Hyper-V)
Next Steps
After successful provisioning:
- ✓ Add VM to inventory
- Run baseline configuration (security, monitoring, agents)
- Join to domain (if required)
- Deploy applications
- Update CMDB
- Configure backup
- Document in ServiceNow