Files
hyperv-demo/playbooks/README-provision.md
2026-04-28 22:45:25 -04:00

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:

  1. ✓ Create the VM with specified resources
  2. ✓ Generate autounattend.xml for unattended installation
  3. ✓ Attach Windows Server ISO
  4. ✓ Start the VM
  5. ⏸ 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_gb
  • default_vm_switch - Hyper-V virtual switch name
  • vm_storage_path - Base path for VM files
  • iso_storage_path - Path to ISO files
  • windows_server_iso - Path to Windows Server ISO
  • dns_servers - Default DNS servers
  • timezone - 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 timezone variable
  • Administrator Password: From vm_admin_password
  • Network: Static IP if vm_ip_address is 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:

  1. Root of installation media (requires rebuilding ISO)
  2. Root of removable media (floppy, USB, second CD drive)
  3. Mounted as additional DVD drive (easiest for Hyper-V)
# 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:

  1. Provision VM → provision-vm.yml
  2. Wait for Installation → Manual approval
  3. Windows Baseline → windows-baseline.yml
  4. Deploy Application → install-iis.yml
  5. 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:

  1. Verify autounattend.xml is in correct location
  2. Check XML is valid (use XMLLint or online validator)
  3. 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:

  1. Increase VM memory (minimum 2GB for Windows Server)
  2. Verify ISO integrity
  3. Check Hyper-V event logs
  4. 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:

  1. ✓ Add VM to inventory
  2. Run baseline configuration (security, monitoring, agents)
  3. Join to domain (if required)
  4. Deploy applications
  5. Update CMDB
  6. Configure backup
  7. Document in ServiceNow

References