diff --git a/README.md b/README.md index e9f120f..ff43762 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ This project demonstrates automated Windows Server VM management including: ## Quick Start +**New to this project?** See [QUICKSTART.md](QUICKSTART.md) for a complete step-by-step guide from fresh Hyper-V install to running VMs. + ### Development Environment ```bash @@ -117,12 +119,26 @@ ansible-playbook playbooks/sync-cmdb.yml ## Documentation +- **[HANDOFF.md](HANDOFF.md)** - Project status, next steps, and quick reference +- **[QUICKSTART.md](QUICKSTART.md)** - Complete step-by-step guide from scratch - [CLAUDE.md](CLAUDE.md) - Architecture and development guidelines - [playbooks/README-provision.md](playbooks/README-provision.md) - VM provisioning guide - [templates/autounattend.xml.j2](templates/autounattend.xml.j2) - Windows unattended install template ## Common Tasks +### First-Time Setup + +```bash +# 1. Configure fresh Hyper-V host +ansible-playbook playbooks/provision-hyperv-host.yml + +# 2. Verify switches are available +ansible-playbook playbooks/list-hyperv-switches.yml + +# 3. Upload Windows ISO to D:\ISOs\ on Hyper-V host +``` + ### Provision a VM ```bash ansible-playbook playbooks/provision-vm.yml -e vm_name=WEB01 -e vm_ip_address=192.168.1.101 diff --git a/ansible.cfg b/ansible.cfg deleted file mode 100644 index 404c949..0000000 --- a/ansible.cfg +++ /dev/null @@ -1,11 +0,0 @@ -[defaults] -inventory = /home/ptoal/Dev/inventories/toallab-inventory -host_key_checking = False -retry_files_enabled = False -roles_path = roles -collections_path = collections -interpreter_python = auto_silent -timeout = 30 - -[ssh_connection] -pipelining = True diff --git a/group_vars/hyperv_hosts.yml b/group_vars/hyperv_hosts.yml index 3f056b4..a60dd14 100644 --- a/group_vars/hyperv_hosts.yml +++ b/group_vars/hyperv_hosts.yml @@ -4,15 +4,16 @@ # Default VM settings default_vm_cpu_count: 2 default_vm_memory_gb: 4 -default_vm_disk_size_gb: 60 +default_vm_disk_size_gb: 20 # Network settings default_vm_switch: "Internal Switch" default_vm_vlan: 100 # VM storage paths -vm_storage_path: "D:\\VMs" -iso_storage_path: "D:\\ISOs" +vm_storage_drive: "C:" +vm_storage_path: "C:\\VMs" +iso_storage_path: "C:\\ISOs" # Windows Server ISO windows_server_iso: "{{ iso_storage_path }}\\Windows_Server_2022.iso" diff --git a/playbooks/provision-vm.yml b/playbooks/provision-vm.yml index a399684..7a491e1 100644 --- a/playbooks/provision-vm.yml +++ b/playbooks/provision-vm.yml @@ -24,18 +24,58 @@ gather_facts: false vars: - # Use defaults from group_vars if not specified - vm_cpu_count: "{{ vm_cpu_count | default(default_vm_cpu_count) }}" - vm_memory_gb: "{{ vm_memory_gb | default(default_vm_memory_gb) }}" - vm_disk_size_gb: "{{ vm_disk_size_gb | default(default_vm_disk_size_gb) }}" - vm_switch: "{{ vm_switch | default(default_vm_switch) }}" - # Derived paths vm_path: "{{ vm_storage_path }}\\{{ vm_name }}" vm_vhd_path: "{{ vm_storage_path }}\\{{ vm_name }}\\{{ vm_name }}.vhdx" autounattend_path: "{{ vm_storage_path }}\\{{ vm_name }}\\autounattend.xml" pre_tasks: + - name: Set VM configuration with defaults + ansible.builtin.set_fact: + vm_cpu_count: "{{ vm_cpu_count | default(default_vm_cpu_count) }}" + vm_memory_gb: "{{ vm_memory_gb | default(default_vm_memory_gb) }}" + vm_disk_size_gb: "{{ vm_disk_size_gb | default(default_vm_disk_size_gb) }}" + vm_switch: "{{ vm_switch | default(default_vm_switch) }}" + + - name: Get available Hyper-V virtual switches + ansible.windows.win_shell: | + Get-VMSwitch | Select-Object Name, SwitchType | ConvertTo-Json + register: available_switches + changed_when: false + tags: [create, verify] + + - name: Parse available switches + ansible.builtin.set_fact: + switch_list: "{{ available_switches.stdout | from_json }}" + when: available_switches.stdout | trim | length > 0 + tags: [create, verify] + + - name: Display available switches + ansible.builtin.debug: + msg: + - "Available Hyper-V switches:" + - "{{ switch_list | default([]) | map(attribute='Name') | list }}" + - "" + - "Configured switch: {{ vm_switch }}" + tags: [create, verify] + + - name: Validate virtual switch exists + ansible.builtin.assert: + that: + - switch_list is defined + - switch_list | selectattr('Name', 'equalto', vm_switch) | list | length > 0 + fail_msg: | + Virtual switch '{{ vm_switch }}' not found on Hyper-V host. + Available switches: {{ switch_list | default([]) | map(attribute='Name') | list | join(', ') }} + + To fix this: + 1. Update the vm_switch variable: -e vm_switch="" + 2. Or update default in group_vars/hyperv/vars.yml + 3. Or create the switch on Hyper-V host: + New-VMSwitch -Name "{{ vm_switch }}" -SwitchType Internal + success_msg: "Virtual switch '{{ vm_switch }}' is available" + tags: [create] + - name: Validate required variables ansible.builtin.assert: that: