Initial hyper-v demo skeleton

This commit is contained in:
2026-04-28 15:59:50 -04:00
commit 1759682aef
14 changed files with 737 additions and 0 deletions

35
.gitignore vendored Normal file
View File

@@ -0,0 +1,35 @@
# Ansible
*.retry
ansible.log
*.pyc
__pycache__/
# Collections
collections/ansible_collections/
# Sensitive files
*vault*
*secret*
*password*
*.key
*.pem
# Environment files
.env
*.env
# IDE
.vscode/
.idea/
*.swp
*.swo
*~
# OS
.DS_Store
Thumbs.db
# Temporary files
*.tmp
*.bak
*.old

346
CLAUDE.md Normal file
View File

@@ -0,0 +1,346 @@
# Hyper-V Windows Server Automation - Project Documentation
## Project Overview
This project demonstrates enterprise-grade automation for the complete lifecycle of Windows Server VMs on Hyper-V using Ansible Automation Platform (AAP), implementing GitOps and Infrastructure as Code (IaC) principles.
**Target Audience**: Enterprise IT operations teams, infrastructure engineers, platform engineers
**Deployment Platform**: Ansible Automation Platform 2.x (formerly Ansible Tower)
**Future Roadmap**: Event-Driven Ansible (EDA) integration for reactive automation
## Architecture
### Technology Stack
- **Automation Engine**: Ansible Core 2.15+
- **Platform**: Ansible Automation Platform 2.4+
- **Hypervisor**: Microsoft Hyper-V (Windows Server 2019/2022)
- **Guest OS**: Windows Server 2019/2022
- **CMDB**: ServiceNow ITSM
- **Version Control**: Git (GitOps workflow)
- **Authentication**: Active Directory / Kerberos
### Connectivity Model
```
Ansible Automation Platform
↓ (WinRM over HTTPS/Kerberos)
Windows Hyper-V Host(s)
↓ (Hyper-V PowerShell)
Windows Server VMs
↓ (REST API)
ServiceNow CMDB
```
### Core Use Cases
1. **VM Provisioning**: Automated creation of Windows Server VMs using unattended installation (autounattend.xml)
2. **Patch Management**: Automated Windows Update deployment triggered by git commits
3. **Application Deployment**: Install and configure applications (IIS demonstration)
4. **Configuration Management**: Day-2 operations and drift remediation
5. **CMDB Synchronization**: Bidirectional sync with ServiceNow CMDB
## Project Structure
```
.
├── ansible.cfg # Ansible configuration with Windows/WinRM defaults
├── collections/
│ └── requirements.yml # Required Ansible collections
├── inventory/
│ ├── production/
│ │ └── hosts.yml # Production inventory
│ └── staging/
│ └── hosts.yml # Staging inventory (future)
├── group_vars/
│ ├── all.yml # Global variables
│ ├── hyperv_hosts.yml # Hyper-V host configuration
│ ├── windows_servers.yml # Windows Server defaults
│ └── web_servers.yml # IIS/web server configuration
├── host_vars/ # Host-specific variables (future)
├── playbooks/
│ ├── provision-vm.yml # VM provisioning workflow
│ ├── patch-vms.yml # Windows Update automation
│ ├── install-iis.yml # IIS deployment
│ └── sync-cmdb.yml # ServiceNow CMDB sync
├── roles/ # Custom roles (future development)
│ ├── windows_baseline/ # Windows hardening & baseline config
│ ├── hyperv_vm/ # Hyper-V VM management
│ ├── iis_webapp/ # IIS application deployment
│ └── servicenow_sync/ # ServiceNow integration
├── templates/ # Jinja2 templates (future)
│ └── autounattend.xml.j2 # Windows unattended install template
└── README.md # Quick start guide
```
## Key Design Patterns
### GitOps Workflow
All infrastructure changes flow through Git:
1. Engineer creates feature branch
2. Updates inventory or group_vars to define desired state
3. Commits and creates pull request
4. AAP webhook triggers job template for validation
5. After merge, AAP webhook triggers deployment
### Idempotency
All playbooks must be idempotent - safe to run multiple times without side effects. Use:
- `state: present` vs `state: absent`
- Conditional tasks with `when:`
- Changed/failed handlers
- Check mode support (`--check`)
### Credential Management
- **Never commit secrets to Git**
- Use AAP credential types for:
- Machine credentials (WinRM)
- ServiceNow credentials
- Domain join credentials
- Use Ansible Vault for sensitive variables in development
### Role-Based Organization
Future development should extract common patterns into roles:
- `roles/windows_baseline/`: Base Windows configuration
- `roles/hyperv_vm/`: VM lifecycle management
- `roles/iis_webapp/`: IIS deployment patterns
## Technical Requirements
### Prerequisites
1. **Ansible Automation Platform**
- AAP 2.4 or later
- Controller configured with Windows machine credentials
- Execution environment with Windows collections
2. **Hyper-V Environment**
- Windows Server 2019/2022 with Hyper-V role
- WinRM enabled and configured
- Kerberos authentication configured
- Sufficient storage for VM images
3. **Network Requirements**
- WinRM ports (5985/5986) open from AAP to Hyper-V hosts
- WinRM ports open from AAP to managed Windows VMs
- DNS resolution for all hosts
- Active Directory domain membership
4. **ServiceNow**
- ServiceNow instance with CMDB
- API user credentials
- CMDB table structure defined
### Windows Remote Management Setup
On all Windows hosts (Hyper-V and VMs):
```powershell
# Enable WinRM with HTTPS
winrm quickconfig -transport:https
winrm set winrm/config/service/auth '@{Kerberos="true"}'
winrm set winrm/config/service '@{AllowUnencrypted="false"}'
```
## Development Guidelines
### Adding New Playbooks
1. Create playbook in `playbooks/` directory
2. Use descriptive names: `verb-noun.yml` (e.g., `deploy-webapp.yml`)
3. Include proper documentation in header
4. Add tags for selective execution
5. Implement check mode support
6. Test in staging environment first
### Variable Precedence
Follow this hierarchy (least to most specific):
1. `group_vars/all.yml` - Global defaults
2. `group_vars/<group>.yml` - Group-specific
3. `host_vars/<host>.yml` - Host-specific
4. Playbook `vars:` - Playbook overrides
5. Extra vars (`-e`) - Runtime overrides
### Testing Strategy
1. **Syntax Check**: `ansible-playbook --syntax-check playbook.yml`
2. **Check Mode**: `ansible-playbook --check playbook.yml`
3. **Limit Scope**: `--limit` to test on single host first
4. **Verbose Output**: Use `-v`, `-vv`, `-vvv` for debugging
5. **Staging First**: Always test in staging before production
### Windows Module Best Practices
- Use `ansible.windows.*` modules (not deprecated `win_*`)
- Always handle reboots explicitly with `ansible.windows.win_reboot`
- Use `register:` to capture task output
- Check `reboot_required` in results
- Use `failed_when:` for expected error conditions
## AAP Integration
### Job Templates to Create
1. **Provision VM** - `playbooks/provision-vm.yml`
- Survey for VM name, IP, CPU, RAM
- Credential: Hyper-V machine credential
- Webhook enabled for GitOps
2. **Patch VMs** - `playbooks/patch-vms.yml`
- Limit pattern for selective patching
- Scheduled for maintenance windows
- Credential: Windows machine credential
3. **Deploy IIS** - `playbooks/install-iis.yml`
- Limit to web_servers group
- Credential: Windows machine credential
4. **Sync CMDB** - `playbooks/sync-cmdb.yml`
- Scheduled daily
- Credentials: Windows + ServiceNow
### Workflow Templates (Future)
Create workflows for complex orchestration:
- **Full VM Lifecycle**: Provision → Configure → Deploy App → Update CMDB
- **Patch & Compliance**: Patch → Verify → Update CMDB → Generate Report
### Event-Driven Ansible (Future)
Planned EDA integrations:
- ServiceNow incident triggers remediation playbook
- Windows Event Log monitoring triggers security response
- Hyper-V alerts trigger capacity management
- Git webhook triggers deployment pipeline
## Common Tasks
### Bootstrap a New VM
```bash
# Provision VM
ansible-playbook playbooks/provision-vm.yml \
-e vm_name=DEMO-WEB01 \
-e vm_ip_address=192.168.1.101
# Configure baseline
ansible-playbook playbooks/windows-baseline.yml --limit DEMO-WEB01
# Deploy application
ansible-playbook playbooks/install-iis.yml --limit DEMO-WEB01
# Update CMDB
ansible-playbook playbooks/sync-cmdb.yml --limit DEMO-WEB01
```
### Patch All Windows Servers
```bash
ansible-playbook playbooks/patch-vms.yml --limit windows_servers
```
### Update Specific Group
```bash
ansible-playbook playbooks/patch-vms.yml --limit web_servers
```
## Troubleshooting
### WinRM Connection Issues
```bash
# Test WinRM connectivity
ansible hyperv_hosts -m ansible.windows.win_ping
# Check with verbose output
ansible hyperv_hosts -m ansible.windows.win_ping -vvv
```
### Common Issues
1. **Kerberos Authentication Failure**
- Verify DNS resolution (forward and reverse)
- Check domain join status
- Verify time synchronization
- Check Kerberos ticket: `klist`
2. **Module Not Found**
- Install collections: `ansible-galaxy collection install -r collections/requirements.yml`
- Verify in AAP execution environment
3. **Timeout Issues**
- Increase timeout in `ansible.cfg`
- Check network connectivity
- Verify WinRM service running
## Security Considerations
### Credential Storage
- Use AAP credential vault (not Ansible Vault in production)
- Rotate credentials regularly
- Use least-privilege service accounts
- Separate credentials per environment
### Network Security
- Use WinRM over HTTPS (port 5986)
- Enable Kerberos encryption
- Implement network segmentation
- Use jump hosts/bastion for AAP
### Compliance
- Enable audit logging in AAP
- Log all playbook runs
- Track changes in ServiceNow CMDB
- Implement change approval workflow
## Future Enhancements
### Phase 2 - Advanced Features
- [ ] Custom execution environment with all dependencies
- [ ] Ansible Vault integration for secrets
- [ ] Enhanced autounattend.xml templating
- [ ] VM template/image management
- [ ] Backup and DR automation
### Phase 3 - EDA Integration
- [ ] ServiceNow incident-driven remediation
- [ ] Windows Event Log monitoring
- [ ] Hyper-V performance monitoring
- [ ] Self-healing automation
### Phase 4 - Enterprise Scale
- [ ] Multi-region Hyper-V clusters
- [ ] RBAC and delegation model
- [ ] Compliance scanning and remediation
- [ ] Cost tracking and optimization
- [ ] Disaster recovery automation
## Contributing
This is a demonstration project. When extending:
1. Follow existing patterns and structure
2. Test thoroughly in staging
3. Document all variables in group_vars
4. Use semantic versioning for releases
5. Update this CLAUDE.md with architectural changes
## References
- [Ansible Windows Guide](https://docs.ansible.com/ansible/latest/os_guide/windows_usage.html)
- [Ansible Automation Platform Docs](https://access.redhat.com/documentation/en-us/red_hat_ansible_automation_platform)
- [ServiceNow ITSM Collection](https://github.com/ansible-collections/servicenow.itsm)
- [Event-Driven Ansible](https://www.ansible.com/products/event-driven-ansible)

61
README.md Normal file
View File

@@ -0,0 +1,61 @@
# Hyper-V Windows Server Automation
Enterprise-grade automation for Windows Server VM lifecycle management on Hyper-V using Ansible Automation Platform, GitOps, and Infrastructure as Code practices.
## Overview
This project demonstrates automated Windows Server VM management including:
- **Provisioning**: Automated VM creation using autounattend.xml
- **Configuration Management**: Day-2 operations and application deployment
- **Patch Management**: Automated Windows updates via git commits
- **CMDB Integration**: ServiceNow CMDB synchronization
- **Event-Driven Automation**: Future EDA integration
## Quick Start
```bash
# Install required collections
ansible-galaxy collection install -r collections/requirements.yml
# Run VM provisioning
ansible-playbook playbooks/provision-vm.yml -e vm_name=DEMO-WEB01
# Patch management
ansible-playbook playbooks/patch-vms.yml --limit windows_servers
# Install IIS demo application
ansible-playbook playbooks/install-iis.yml --limit web_servers
```
## Project Structure
```
.
├── ansible.cfg # Ansible configuration
├── inventory/ # Inventory files
│ ├── production/
│ └── staging/
├── playbooks/ # Playbooks by use case
│ ├── provision-vm.yml
│ ├── patch-vms.yml
│ ├── install-iis.yml
│ └── sync-cmdb.yml
├── roles/ # Custom roles
├── group_vars/ # Group variables
├── host_vars/ # Host-specific variables
└── collections/ # Ansible collections
└── requirements.yml
```
## Prerequisites
- Ansible Automation Platform 2.x
- Hyper-V Server or Windows Server with Hyper-V role
- Windows Server ISO images
- ServiceNow instance (for CMDB integration)
- Active Directory domain (for authentication)
## Documentation
See [CLAUDE.md](CLAUDE.md) for detailed architectural documentation and development guidance.

24
ansible.cfg Normal file
View File

@@ -0,0 +1,24 @@
[defaults]
inventory = inventory/production
host_key_checking = False
retry_files_enabled = False
roles_path = roles
collections_path = collections
interpreter_python = auto_silent
timeout = 30
# Windows-specific settings
ansible_connection = winrm
ansible_winrm_transport = kerberos
ansible_winrm_server_cert_validation = ignore
# Logging
log_path = ./ansible.log
[privilege_escalation]
become = True
become_method = runas
become_user = Administrator
[ssh_connection]
pipelining = True

View File

@@ -0,0 +1,21 @@
---
collections:
# Windows management
- name: ansible.windows
version: ">=2.0.0"
# Community Windows modules
- name: community.windows
version: ">=2.0.0"
# General utilities
- name: ansible.builtin
version: ">=2.0.0"
# ServiceNow integration
- name: servicenow.itsm
version: ">=2.0.0"
# Event-Driven Ansible (future)
- name: ansible.eda
version: ">=1.0.0"

15
group_vars/all.yml Normal file
View File

@@ -0,0 +1,15 @@
---
# Global variables for all hosts
# Domain settings
domain_name: example.com
domain_netbios: EXAMPLE
# ServiceNow CMDB integration
servicenow_instance: dev12345.service-now.com
servicenow_table: cmdb_ci_win_server
# Tagging and metadata
project_name: hyperv-automation
environment: "{{ inventory_dir | basename }}"
managed_by: ansible

View File

@@ -0,0 +1,18 @@
---
# Hyper-V host configuration
# Default VM settings
default_vm_cpu_count: 2
default_vm_memory_gb: 4
default_vm_disk_size_gb: 60
# Network settings
default_vm_switch: "Internal Switch"
default_vm_vlan: 100
# VM storage paths
vm_storage_path: "D:\\VMs"
iso_storage_path: "D:\\ISOs"
# Windows Server ISO
windows_server_iso: "{{ iso_storage_path }}\\Windows_Server_2022.iso"

View File

@@ -0,0 +1,31 @@
---
# Web server configuration
# IIS features to install
iis_features:
- Web-Server
- Web-WebServer
- Web-Common-Http
- Web-Default-Doc
- Web-Dir-Browsing
- Web-Http-Errors
- Web-Static-Content
- Web-Http-Redirect
- Web-Health
- Web-Http-Logging
- Web-Performance
- Web-Stat-Compression
- Web-Dyn-Compression
- Web-Security
- Web-Filtering
- Web-Mgmt-Tools
- Web-Mgmt-Console
# Application pool settings
iis_app_pool_name: DefaultAppPool
iis_app_pool_identity: ApplicationPoolIdentity
# Website settings
iis_website_name: Default Web Site
iis_website_port: 80
iis_website_path: C:\inetpub\wwwroot

View File

@@ -0,0 +1,20 @@
---
# Windows Server configuration
# Windows Update settings
windows_update_categories:
- CriticalUpdates
- SecurityUpdates
- UpdateRollups
# Common Windows features
windows_features_remove:
- Windows-Defender
# Timezone
timezone: "Eastern Standard Time"
# DNS servers
dns_servers:
- 192.168.1.1
- 192.168.1.2

View File

@@ -0,0 +1,30 @@
---
all:
children:
hyperv_hosts:
hosts:
hyperv01.example.com:
ansible_host: 192.168.1.10
windows_servers:
children:
web_servers:
hosts:
# Provisioned VMs will be added here
# DEMO-WEB01:
# ansible_host: 192.168.1.101
app_servers:
hosts:
# Application servers
db_servers:
hosts:
# Database servers
vars:
# Windows connection settings
ansible_connection: winrm
ansible_winrm_transport: kerberos
ansible_winrm_server_cert_validation: ignore
ansible_port: 5986

43
playbooks/install-iis.yml Normal file
View File

@@ -0,0 +1,43 @@
---
- name: Install and configure IIS
hosts: web_servers
gather_facts: true
tasks:
- name: Install IIS features
ansible.windows.win_feature:
name: "{{ iis_features }}"
state: present
register: iis_install
- name: Reboot if required
ansible.windows.win_reboot:
reboot_timeout: 3600
when: iis_install.reboot_required
- name: Create demo web content
ansible.windows.win_copy:
content: |
<!DOCTYPE html>
<html>
<head>
<title>Demo IIS Site - {{ inventory_hostname }}</title>
</head>
<body>
<h1>Welcome to {{ inventory_hostname }}</h1>
<p>This server was configured by Ansible Automation Platform</p>
<p>Deployment Date: {{ ansible_date_time.iso8601 }}</p>
</body>
</html>
dest: "{{ iis_website_path }}\\index.html"
- name: Ensure IIS service is running
ansible.windows.win_service:
name: W3SVC
state: started
start_mode: auto
- name: Update CMDB with IIS installation
ansible.builtin.debug:
msg: "Would update ServiceNow CMDB with IIS installation"
# TODO: Implement ServiceNow CMDB update

29
playbooks/patch-vms.yml Normal file
View File

@@ -0,0 +1,29 @@
---
- name: Patch Windows Servers
hosts: windows_servers
gather_facts: true
tasks:
- name: Search for Windows updates
ansible.windows.win_updates:
category_names: "{{ windows_update_categories }}"
state: searched
register: update_search
- name: Display available updates
ansible.builtin.debug:
msg: "{{ update_search.found_update_count }} updates available"
- name: Install Windows updates
ansible.windows.win_updates:
category_names: "{{ windows_update_categories }}"
state: installed
reboot: true
reboot_timeout: 3600
when: update_search.found_update_count > 0
register: update_result
- name: Update CMDB with patch status
ansible.builtin.debug:
msg: "Would update ServiceNow CMDB with patch status"
# TODO: Implement ServiceNow CMDB update

View File

@@ -0,0 +1,25 @@
---
- name: Provision Windows Server VM on Hyper-V
hosts: hyperv_hosts
gather_facts: false
vars_prompt:
- name: vm_name
prompt: "Enter VM name"
private: false
- name: vm_ip_address
prompt: "Enter IP address for VM"
private: false
tasks:
- name: Placeholder - Create VM
ansible.builtin.debug:
msg: "Will create VM {{ vm_name }} with IP {{ vm_ip_address }}"
# TODO: Implement VM creation using hyper-v modules
# TODO: Generate autounattend.xml from template
# TODO: Attach autounattend.xml to VM
# TODO: Start VM and wait for provisioning
# TODO: Add VM to inventory
# TODO: Update ServiceNow CMDB

39
playbooks/sync-cmdb.yml Normal file
View File

@@ -0,0 +1,39 @@
---
- name: Synchronize VM information to ServiceNow CMDB
hosts: windows_servers
gather_facts: true
tasks:
- name: Gather Windows facts
ansible.builtin.setup:
gather_subset:
- hardware
- network
- virtual
- name: Prepare CMDB data
ansible.builtin.set_fact:
cmdb_data:
name: "{{ inventory_hostname }}"
ip_address: "{{ ansible_ip_addresses[0] | default('') }}"
os: "{{ ansible_os_family }}"
os_version: "{{ ansible_distribution_version }}"
cpu_count: "{{ ansible_processor_vcpus }}"
ram: "{{ ansible_memtotal_mb }}"
managed_by: "{{ managed_by }}"
environment: "{{ environment }}"
- name: Display CMDB data
ansible.builtin.debug:
var: cmdb_data
# TODO: Implement actual ServiceNow CMDB update using servicenow.itsm collection
# - name: Update ServiceNow CMDB
# servicenow.itsm.configuration_item:
# instance:
# host: "{{ servicenow_instance }}"
# username: "{{ servicenow_username }}"
# password: "{{ servicenow_password }}"
# state: present
# sys_class_name: "{{ servicenow_table }}"
# data: "{{ cmdb_data }}"