Skip to content

Architecture Overview

This page explains how the Solti-Platforms collection components work together to automate infrastructure provisioning.

High-Level Architecture

graph TB
    User[User/CI Pipeline]
    Scripts[Management Scripts]
    Template[proxmox_template Role]
    VM[proxmox_vm Role]
    Proxmox[Proxmox VE Host]
    CloudImage[Cloud Images]

    User -->|./manage-platform.sh| Scripts
    Scripts --> Template
    Scripts --> VM
    Template -->|Downloads| CloudImage
    Template -->|Creates| Proxmox
    VM -->|Clones| Proxmox

    style Template fill:#e1f5ff
    style VM fill:#fff4e1
    style Proxmox fill:#f0f0f0

Role Responsibilities

proxmox_template

Purpose: Create reusable VM templates from cloud images

Input: - Distribution name (rocky9, debian12, etc.) - Hardware configuration (CPU, RAM, disk) - Storage backend

Process: 1. Download official cloud image 2. Verify checksum 3. Resize disk image 4. Create VM with hardware configuration 5. Import disk to Proxmox storage 6. Configure UEFI/Secure Boot 7. Setup cloud-init drive 8. Convert VM to template 9. Assign VMID in 9000-9999 range

Output: - Template VM ready for cloning - Metadata tracking (version, checksum, date)

proxmox_vm

Purpose: Create VMs from templates with smart automation

Input: - Template selection (by distribution, name, or VMID) - Optional: VM name, VMID, resources

Process: 1. Template Lookup (priority: VMID > name > distribution) - If vm_template_vmid provided → use directly - Else if vm_template_name provided → lookup by name - Else if vm_template_distribution provided → lookup {dist}-template 2. VMID Assignment - If vm_vmid provided → validate not in use - Else → find next available in range 500-8999 3. Name Generation - If vm_name provided → use directly - Else → generate {distribution}-{YYMMDD} 4. Clone Template - Linked clone (default) or full clone 5. Resize Disk (if needed) - Current size < vm_disk_min_size → resize - Current size >= vm_disk_min_size → no resize 6. Configure cloud-init - Inject SSH key - Set username - Configure network (DHCP default)

Output: - VM ready to start - Cloud-init configured for passwordless SSH

VMID Numbering Strategy

The collection uses a structured VMID allocation strategy:

Range Purpose Example
9000-9999 Templates (all distributions) 9000: rocky9-template
9001: rocky10-template
9002: debian12-template
500-8999 VMs (auto-assigned) 500: first auto-assigned VM
501: second auto-assigned VM
100-499 VMs (manual assignment) User-specified VMIDs

Unified Template Range: All templates share the 9000-9999 range. VMID numbers are independent of OS version - use template metadata to track versions.

Template Selection Flow

graph TD
    Start[VM Creation Requested]
    CheckVMID{vm_template_vmid<br/>provided?}
    CheckName{vm_template_name<br/>provided?}
    CheckDist{vm_template_distribution<br/>provided?}

    UseVMID[Use VMID directly]
    LookupName[Lookup by name]
    LookupDist[Lookup {dist}-template]
    Fail[Fail: No template specified]

    Verify[Verify template exists]
    Clone[Clone template]

    Start --> CheckVMID
    CheckVMID -->|Yes| UseVMID
    CheckVMID -->|No| CheckName
    CheckName -->|Yes| LookupName
    CheckName -->|No| CheckDist
    CheckDist -->|Yes| LookupDist
    CheckDist -->|No| Fail

    UseVMID --> Verify
    LookupName --> Verify
    LookupDist --> Verify
    Verify --> Clone

    style UseVMID fill:#d4edda
    style LookupName fill:#fff3cd
    style LookupDist fill:#cce5ff
    style Fail fill:#f8d7da

Priority: VMID > Name > Distribution

This allows flexible usage:

# Most common (distribution lookup)
vm_template_distribution: rocky9

# Explicit name
vm_template_name: "rocky9-custom-template"

# Explicit VMID (highest priority)
vm_template_vmid: 9005

Disk Sizing Logic

The proxmox_vm role uses minimum sizing logic:

graph TD
    Start[Clone template]
    GetCurrent[Get current disk size]
    Compare{Current size <br/> vm_disk_min_size?}
    Resize[Resize to vm_disk_min_size]
    Keep[Keep current size]
    Done[VM ready]

    Start --> GetCurrent
    GetCurrent --> Compare
    Compare -->|Less than| Resize
    Compare -->|Greater or equal| Keep
    Resize --> Done
    Keep --> Done

    style Resize fill:#fff3cd
    style Keep fill:#d4edda

Examples:

Template Size Requested Minimum Result Action
32G 20G 32G No resize (already larger)
32G 50G 50G Resize to 50G
10G 20G 20G Resize to 20G

This prevents accidental shrinking of template disks while allowing growth when needed.

Cloning Strategies

Linked Clone (Default)

Template (9000)
    ↓ (linked clone)
VM 500 → References template disk
VM 501 → References template disk
VM 502 → References template disk

Advantages: - Fast creation (seconds) - Space-efficient (only deltas stored) - Consistent base across VMs

Disadvantages: - Requires template to exist - Cannot delete template while VMs exist - Slightly slower I/O (reads from base)

Full Clone

Template (9000)
    ↓ (full clone)
VM 500 → Independent disk copy

Advantages: - Fully independent - Can delete template - Better I/O performance

Disadvantages: - Slower creation (~30-60 seconds) - Uses more storage - Disk divergence across VMs

When to use:

  • Linked clone: Development, testing, ephemeral VMs
  • Full clone: Production, long-lived VMs, template will be deleted

Cloud-init Integration

Cloud-init provides first-boot configuration:

graph LR
    Template[Template<br/>cloud-init enabled]
    Clone[Clone VM]
    Boot[First Boot]
    CloudInit[Cloud-init runs]
    Ready[VM Ready]

    Template --> Clone
    Clone --> Boot
    Boot --> CloudInit
    CloudInit -->|Create user| Ready
    CloudInit -->|Inject SSH key| Ready
    CloudInit -->|Configure network| Ready

    style CloudInit fill:#cce5ff
    style Ready fill:#d4edda

Cloud-init configures:

  1. User account: Creates user (e.g., lavender)
  2. SSH key: Injects public key for passwordless auth
  3. Network: Configures DHCP or static IP
  4. Hostname: Sets VM hostname

Why cloud-init?

  • Passwordless SSH access immediately
  • Consistent configuration across VMs
  • No manual post-boot setup
  • Security: SSH keys only, no passwords

Management Scripts

manage-platform.sh

High-level platform operations:

./manage-platform.sh -h <host> <platform> <action> [options]

Maps platform:action to role:state:

Platform Action Role State
proxmox_template build proxmox_template build
proxmox_template destroy proxmox_template destroy
proxmox_vm create proxmox_vm create
proxmox_vm verify proxmox_vm verify

Generates temporary playbook and executes.

platform-exec.sh

Task-level execution:

./platform-exec.sh -h <host> <platform> [task] [options]

Executes individual task files from role:

# Run verify task
./platform-exec.sh -h magic proxmox_template verify

# Run cleanup task
./platform-exec.sh -h magic proxmox_template cleanup

Useful for debugging and incremental operations.

Integration Flow

Complete Workflow

sequenceDiagram
    participant User
    participant Script as manage-platform.sh
    participant Template as proxmox_template
    participant VM as proxmox_vm
    participant Proxmox

    User->>Script: Build template
    Script->>Template: Execute role
    Template->>Proxmox: Create template 9000
    Proxmox-->>User: Template ready

    User->>Script: Create VM
    Script->>VM: Execute role
    VM->>Proxmox: Lookup template 9000
    VM->>Proxmox: Clone to 500
    VM->>Proxmox: Configure cloud-init
    Proxmox-->>User: VM ready

    User->>Proxmox: Start VM 500
    Proxmox->>Proxmox: Cloud-init runs
    Proxmox-->>User: SSH ready

Data Flow

Template Creation

Cloud Image URL → Download → Verify Checksum → Resize → Import to Proxmox → Configure → Template

VM Creation

Template Selection → VMID Assignment → Name Generation → Clone → Resize (optional) → Cloud-init Config → VM Ready

Design Principles

1. Smart Defaults

Minimal configuration required:

vm_template_distribution: rocky9
# Everything else auto-generated

2. Explicit Override

Advanced users can control everything:

vm_template_vmid: 9000
vm_vmid: 505
vm_name: "my-server"
vm_disk_min_size: "100G"
vm_linked_clone: false

3. Fail Early

Validation before execution:

  • Template exists before cloning
  • VMID not in use before creation
  • Required variables provided

4. Idempotent

Safe to run multiple times:

  • Template build checks if exists
  • VM creation checks conflicts
  • Verification tasks always safe

State Management

proxmox_template States

  • build: Create template from cloud image
  • destroy: Remove template
  • verify: Check template exists

proxmox_vm States

Phase 1 (Current): - create: Clone template, configure VM - verify: Check VM exists

Phase 2 (Planned): - start: Boot VM - stop: Stop VM (non-graceful) - shutdown: Graceful shutdown - remove: Destroy VM - modify: Change VM properties

Next Steps