feat: Implement Debian VM template creation and cloning on Proxmox
- Added default configuration for VM creation in defaults/main.yml. - Created tasks for configuring the VM with UEFI, TPM, disks, GPU, and Cloud-Init in tasks/configure-vm.yml. - Implemented clone creation and configuration logic in tasks/create-clones.yml. - Added template conversion functionality in tasks/create-template.yml. - Developed base VM creation logic in tasks/create-vm.yml. - Included image download and caching tasks in tasks/download-image.yml. - Introduced utility tasks for common operations in tasks/helpers.yml. - Organized main orchestration logic in tasks/main.yml, with clear stages for each operation. - Added pre-flight checks to validate the environment before execution in tasks/preflight-checks.yml.
This commit is contained in:
289
ARCHITECTURE.md
Normal file
289
ARCHITECTURE.md
Normal file
@@ -0,0 +1,289 @@
|
||||
# Architecture Diagram & Flow
|
||||
|
||||
## Overall Playbook Flow
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ ansible-playbook tasks/main.yml │
|
||||
│ │
|
||||
│ ┌────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ PRE_TASKS: Display banner │ │
|
||||
│ └────────────────────────────────────────────────────────────────┘ │
|
||||
│ ↓ │
|
||||
│ ┌────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ STAGE 1: preflight-checks.yml │ │
|
||||
│ │ ✓ Proxmox installed? │ │
|
||||
│ │ ✓ Storage pool exists? │ │
|
||||
│ │ ✓ SSH key available? │ │
|
||||
│ │ ✓ IP addresses valid? │ │
|
||||
│ │ ✓ Permissions okay? │ │
|
||||
│ └────────────────────────────────────────────────────────────────┘ │
|
||||
│ ↓ │
|
||||
│ ┌────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ STAGE 2: download-image.yml │ │
|
||||
│ │ ├─ Check if image cached │ │
|
||||
│ │ ├─ Download if missing (with retry) │ │
|
||||
│ │ ├─ Verify integrity │ │
|
||||
│ │ └─ Display image info │ │
|
||||
│ └────────────────────────────────────────────────────────────────┘ │
|
||||
│ ↓ │
|
||||
│ ┌────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ STAGE 3: create-vm.yml │ │
|
||||
│ │ ├─ Check if VM exists (skip if yes) │ │
|
||||
│ │ ├─ Create VM with qm │ │
|
||||
│ │ ├─ Verify creation │ │
|
||||
│ │ └─ Display status │ │
|
||||
│ └────────────────────────────────────────────────────────────────┘ │
|
||||
│ ↓ │
|
||||
│ ┌────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ STAGE 4: configure-vm.yml │ │
|
||||
│ │ ├─ Configure UEFI + TPM (if enabled) │ │
|
||||
│ │ ├─ Import & attach disk (with retry) │ │
|
||||
│ │ ├─ Resize disk (if enabled) │ │
|
||||
│ │ ├─ Configure GPU (if enabled) │ │
|
||||
│ │ └─ Apply Cloud-Init config │ │
|
||||
│ │ ├─ Create snippets │ │
|
||||
│ │ ├─ Verify SSH key │ │
|
||||
│ │ └─ Apply Cloud-Init │ │
|
||||
│ └────────────────────────────────────────────────────────────────┘ │
|
||||
│ ↓ │
|
||||
│ ┌────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ STAGE 5: create-template.yml │ │
|
||||
│ │ ├─ Check if already templated (skip if yes) │ │
|
||||
│ │ ├─ Stop VM if running │ │
|
||||
│ │ ├─ Convert to template │ │
|
||||
│ │ └─ Verify conversion │ │
|
||||
│ │ │ │
|
||||
│ │ 🔄 IDEMPOTENT: Skips if already templated! │ │
|
||||
│ └────────────────────────────────────────────────────────────────┘ │
|
||||
│ ↓ │
|
||||
│ ┌────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ STAGE 6: create-clones.yml (if enabled) │ │
|
||||
│ │ │ │
|
||||
│ │ For each clone in list: │ │
|
||||
│ │ ├─ Check if clone exists (skip if yes) │ │
|
||||
│ │ ├─ Clone from template │ │
|
||||
│ │ ├─ Configure clone (hostname, IP) │ │
|
||||
│ │ ├─ Start clone │ │
|
||||
│ │ └─ ⚠️ Error doesn't stop other clones │ │
|
||||
│ │ │ │
|
||||
│ │ 🔄 IDEMPOTENT: Skips existing clones! │ │
|
||||
│ └────────────────────────────────────────────────────────────────┘ │
|
||||
│ ↓ │
|
||||
│ ┌────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ POST_TASKS: Display completion summary │ │
|
||||
│ │ ✓ VMs created │ │
|
||||
│ │ ✓ Template converted │ │
|
||||
│ │ ✓ Clones deployed │ │
|
||||
│ │ Next steps... │ │
|
||||
│ └────────────────────────────────────────────────────────────────┘ │
|
||||
│ ↓ │
|
||||
│ ┌────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ RESCUE: Handle errors (if any) │ │
|
||||
│ │ ✗ Playbook execution failed │ │
|
||||
│ │ Check messages above for details │ │
|
||||
│ └────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Error Handling Strategy
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────┐
|
||||
│ Task Execution │
|
||||
└──────────────────────────────┬────────────┘
|
||||
│
|
||||
┌────────┴────────┐
|
||||
│ │
|
||||
Success Failure
|
||||
│ │
|
||||
▼ ▼
|
||||
┌─────────────────┐ ┌──────────────────┐
|
||||
│ Continue with │ │ block/rescue │
|
||||
│ next task │ │ │
|
||||
└─────────────────┘ ├──────────────────┤
|
||||
│ Try recovery? │
|
||||
└────┬─────────────┘
|
||||
│
|
||||
┌──────┴────────┐
|
||||
│ │
|
||||
Recoverable Unrecoverable
|
||||
│ │
|
||||
▼ ▼
|
||||
┌─────────────────┐ ┌──────────────┐
|
||||
│ Warn/continue │ │ fail_msg + │
|
||||
│ to next clone │ │ detailed ctx │
|
||||
└─────────────────┘ └──────────────┘
|
||||
```
|
||||
|
||||
## Idempotency Checks
|
||||
|
||||
```
|
||||
Operation Check Result
|
||||
─────────────────────────────────────────────────────────────
|
||||
Download Image File exists? Skip if cached
|
||||
Create VM /etc/pve/qemu-server/VM_ID.conf exists? Skip if exists
|
||||
Configure Disk Disk already attached? Skip if yes
|
||||
Template Conversion grep 'template: 1' Skip if already template
|
||||
Clone Creation Clone config exists? Skip if exists
|
||||
```
|
||||
|
||||
## Task Dependency Graph
|
||||
|
||||
```
|
||||
preflight-checks
|
||||
↓
|
||||
download-image
|
||||
↓
|
||||
create-vm
|
||||
↓
|
||||
configure-vm
|
||||
├─→ [TPM config]
|
||||
├─→ [Disk import]
|
||||
├─→ [GPU config]
|
||||
└─→ [Cloud-Init]
|
||||
↓
|
||||
create-template (when: make_template)
|
||||
↓
|
||||
create-clones (when: create_clones)
|
||||
└─→ For each clone:
|
||||
├─ Check if exists
|
||||
├─ Clone VM
|
||||
├─ Configure
|
||||
├─ Start
|
||||
└─ Error: warn, continue
|
||||
```
|
||||
|
||||
## Tag Structure
|
||||
|
||||
```
|
||||
All tasks tagged:
|
||||
|
||||
--tags preflight Stage 1 only
|
||||
--tags image Stage 2 only
|
||||
--tags vm,create Stage 3 only
|
||||
--tags vm,configure Stage 4 only
|
||||
--tags template,create Stage 5 only
|
||||
--tags clones,create Stage 6 only
|
||||
|
||||
--tags image,always Stages 1-2 (image download)
|
||||
--tags vm Stages 3-4 (VM creation & config)
|
||||
--tags template Stages 5-6 (template & clones)
|
||||
|
||||
--skip-tags template Skip template conversion
|
||||
--skip-tags clones Skip clone deployment
|
||||
--skip-tags image Don't re-download image
|
||||
```
|
||||
|
||||
## Error Recovery Flow
|
||||
|
||||
```
|
||||
┌─────────────────────────┐
|
||||
│ Task fails │
|
||||
└────────────┬────────────┘
|
||||
│
|
||||
┌──────┴──────┐
|
||||
│ │
|
||||
▼ ▼
|
||||
Retry? Rescue?
|
||||
│ │
|
||||
(3x) Handle
|
||||
│ │
|
||||
▼ ▼
|
||||
Success Continue/Fail?
|
||||
or │
|
||||
Fail ┌──┴──┐
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
Continue Continue Fail
|
||||
to next to next +
|
||||
task (warn) Msg
|
||||
```
|
||||
|
||||
## Idempotency Timeline
|
||||
|
||||
```
|
||||
Run 1 (First execution):
|
||||
preflight ✓ pass
|
||||
image ✓ download
|
||||
create-vm ✓ create
|
||||
configure-vm ✓ configure
|
||||
create-template ✓ convert to template
|
||||
create-clones ✓ create clones
|
||||
|
||||
Run 2 (Re-run):
|
||||
preflight ✓ pass
|
||||
image → skip (cached)
|
||||
create-vm → skip (exists)
|
||||
configure-vm → skip (disk exists)
|
||||
create-template → skip (already template!)
|
||||
create-clones → skip (clones exist)
|
||||
|
||||
⏱️ Much faster! ⚡
|
||||
```
|
||||
|
||||
## Pre-flight Checks Detail
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ Preflight Checks (Early failure detection) │
|
||||
├─────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Environment: │
|
||||
│ ✓ /etc/pve/nodes exists (Proxmox check) │
|
||||
│ ✓ qm command available │
|
||||
│ ✓ qm version readable │
|
||||
│ │
|
||||
│ Permissions: │
|
||||
│ ✓ Can run qm commands (sudo/root) │
|
||||
│ ✓ Can access storage │
|
||||
│ │
|
||||
│ Resources: │
|
||||
│ ✓ Storage pool {{ storage }} exists │
|
||||
│ ✓ Snippets directory exists │
|
||||
│ │
|
||||
│ Configuration: │
|
||||
│ ✓ SSH key file exists & readable │
|
||||
│ ✓ VM ID {{ vm_id }} unique │
|
||||
│ ✓ Clone IDs unique (if create_clones) │
|
||||
│ ✓ IP addresses valid (if static) │
|
||||
│ ✓ Gateway IP valid │
|
||||
│ ✓ DNS servers valid │
|
||||
│ │
|
||||
│ Result: Fail early with context if any check fails │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Cloud-Init Configuration Flow
|
||||
|
||||
```
|
||||
┌──────────────────────────────┐
|
||||
│ Cloud-Init Application │
|
||||
├──────────────────────────────┤
|
||||
│ │
|
||||
│ Validate SSH key │
|
||||
│ ↓ │
|
||||
│ Create vendor snippet │
|
||||
│ ↓ │
|
||||
│ Create user snippet │
|
||||
│ ↓ │
|
||||
│ Copy SSH key to snippets │
|
||||
│ ↓ │
|
||||
│ Apply cicustom config │
|
||||
│ with nocloud datasource │
|
||||
│ ↓ │
|
||||
│ Set ipconfig0 (DHCP/static) │
|
||||
│ ↓ │
|
||||
│ Result: VM ready for boot │
|
||||
│ │
|
||||
└──────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Legend:**
|
||||
- `✓` = Success/Validation passed
|
||||
- `✗` = Failure
|
||||
- `→` = Skip (idempotent)
|
||||
- `⚠️` = Warning (non-fatal)
|
||||
- `🔄` = Idempotent operation
|
||||
Reference in New Issue
Block a user