Files
ansible_proxmox_VM/ARCHITECTURE.md
Jose f62750fe2f 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.
2025-11-15 17:22:21 +01:00

17 KiB

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