346 lines
9.2 KiB
Markdown
346 lines
9.2 KiB
Markdown
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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:
|
|
|
|
```bash
|
|
# 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)
|
|
|
|
#### Method 1: Second DVD Drive (Recommended)
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```powershell
|
|
# 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
|
|
|
|
```bash
|
|
# 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:**
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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:
|
|
|
|
```xml
|
|
<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>`:
|
|
|
|
```xml
|
|
<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
|
|
|
|
- [Windows Unattended Installation Guide](https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/automate-windows-setup)
|
|
- [Hyper-V PowerShell Reference](https://docs.microsoft.com/en-us/powershell/module/hyper-v/)
|
|
- [Ansible Windows Guide](https://docs.ansible.com/ansible/latest/os_guide/windows_usage.html)
|