claude-home/examples/vm-management/proxmox-automation.md
Cal Corum 7edb4a3a9c CLAUDE: Update VM management patterns and Tdarr operational scripts
- Update patterns/vm-management/README.md: Add comprehensive automation workflows
  - Cloud-init deployment strategies and post-install automation
  - SSH key management integration and security hardening patterns
  - Implementation workflows for new and existing VM provisioning

- Add complete VM management examples and reference documentation
  - examples/vm-management/: Proxmox automation and provisioning examples
  - reference/vm-management/: Troubleshooting guides and best practices
  - scripts/vm-management/: Operational scripts for automated VM setup

- Update reference/docker/tdarr-monitoring-configuration.md: API monitoring integration
  - Document new tdarr_monitor.py integration with existing Discord monitoring
  - Add API-based health checks and cron scheduling examples
  - Enhanced gaming scheduler integration with health verification

- Update Tdarr operational scripts with stability improvements
  - scripts/tdarr/start-tdarr-gpu-podman-clean.sh: Resource limits and CDI GPU access
  - scripts/tdarr/tdarr-schedule-manager.sh: Updated container name references
  - scripts/monitoring/tdarr-timeout-monitor.sh: Enhanced completion monitoring

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-12 12:18:43 -05:00

8.7 KiB

Proxmox VM Automation - Complete Examples

Complete working examples for automated VM provisioning in Proxmox environments using cloud-init and post-installation scripts.

Overview

This guide provides real-world examples for automating Ubuntu Server VM deployment with:

  • SSH key-based authentication
  • Docker environment setup
  • Security hardening
  • System updates and maintenance

Example 1: Cloud-Init VM Creation

Proxmox VM Setup

# Create VM with cloud-init support in Proxmox
# VM ID: 200, Name: homelab-docker-01, IP: 10.10.0.200

# 1. Create VM through Proxmox web interface or CLI
pvesh create /nodes/pve/qemu -vmid 200 -name homelab-docker-01 \
  -memory 2048 -cores 2 -sockets 1 -cpu cputype=host \
  -net0 virtio,bridge=vmbr0 \
  -ide2 local:cloudinit \
  -boot c -bootdisk scsi0 \
  -scsi0 local-lvm:10 \
  -ostype l26

Cloud-Init Configuration

Use the complete cloud-init-user-data.yaml template:

#cloud-config
hostname: homelab-docker-01
timezone: America/New_York

users:
  - name: cal
    groups: [sudo, docker]
    shell: /bin/bash
    sudo: ALL=(ALL) NOPASSWD:ALL
    ssh_authorized_keys:
      - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDVVK02rOeeIw1e... homelab-cal@nobara-pc
      - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCPzqHDgdK9TlN4uzumBZKEOGt... emergency-homelab-cal@nobara-pc

ssh_pwauth: false
disable_root: true
package_update: true
package_upgrade: true

# Docker installation and configuration...
# (Full template available in scripts/vm-management/cloud-init-user-data.yaml)

Deployment Process

  1. Create VM with cloud-init drive attached
  2. Paste cloud-init config into User Data field
  3. Set network configuration (IP: 10.10.0.200/24, Gateway: 10.10.0.1)
  4. Start VM - automatic provisioning begins
  5. Wait 3-5 minutes for first boot provisioning
  6. Test connectivity: ssh cal@10.10.0.200

Example 2: Post-Installation Script

Scenario: Existing VM Needs Provisioning

# VM already exists at 10.10.0.150 with password authentication
# Need to configure SSH keys, Docker, and security hardening

# Run the post-installation script
cd /mnt/NV2/Development/claude-home
./scripts/vm-management/vm-post-install.sh 10.10.0.150 cal

Script Execution Flow

🔐 Starting VM provisioning for 10.10.0.150 as user cal
✅ System updates completed
✅ SSH key authentication successful  
✅ SSH hardened (password authentication disabled)
✅ Docker and Docker Compose installed successfully
✅ User environment configured
🎉 VM provisioning completed successfully!

=== PROVISIONING SUMMARY ===
VM IP: 10.10.0.150
User: cal
Hostname: homelab-vm-03
Docker: Docker version 24.0.7, build afdd53b

Example 3: Bulk VM Provisioning

Multiple VM Deployment Script

#!/bin/bash
# Bulk VM provisioning for home lab expansion
# Creates and configures multiple VMs with sequential IPs

VM_BASE_ID=300
VM_BASE_IP="10.10.0"
VM_COUNT=3

for i in $(seq 1 $VM_COUNT); do
    VM_ID=$((VM_BASE_ID + i))
    VM_IP="${VM_BASE_IP}.$((200 + i))"
    VM_NAME="homelab-worker-$(printf "%02d" $i)"
    
    echo "Creating VM: $VM_NAME (ID: $VM_ID, IP: $VM_IP)"
    
    # Create VM in Proxmox (adapt to your environment)
    pvesh create /nodes/pve/qemu -vmid $VM_ID -name $VM_NAME \
      -memory 2048 -cores 2 \
      -net0 virtio,bridge=vmbr0 \
      -ide2 local:cloudinit \
      -scsi0 local-lvm:20
    
    # Set cloud-init configuration
    pvesh set /nodes/pve/qemu/$VM_ID/config \
      -ipconfig0 ip=$VM_IP/24,gw=10.10.0.1 \
      -nameserver 10.10.0.16 \
      -user cal \
      -sshkeys /path/to/encoded/ssh-keys
    
    # Start VM
    pvesh create /nodes/pve/qemu/$VM_ID/status/start
    
    echo "VM $VM_NAME created and starting..."
    sleep 30  # Wait for boot
done

echo "Bulk provisioning completed. VMs available at:"
for i in $(seq 1 $VM_COUNT); do
    echo "  homelab-worker-$(printf "%02d" $i): ${VM_BASE_IP}.$((200 + i))"
done

Example 4: Docker Service Deployment

Post-Provisioning Service Setup

After VM provisioning, deploy services using Docker Compose:

# Connect to newly provisioned VM
ssh cal@10.10.0.200

# Create service directory
mkdir -p ~/services/nginx-proxy
cd ~/services/nginx-proxy

# Create docker-compose.yml
cat > docker-compose.yml << 'EOF'
version: '3.8'
services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./config:/etc/nginx/conf.d:ro
      - ./ssl:/etc/nginx/ssl:ro
    restart: unless-stopped
    
  portainer:
    image: portainer/portainer-ce:latest
    ports:
      - "9000:9000"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data
    restart: unless-stopped

volumes:
  portainer_data:
EOF

# Deploy services
docker compose up -d
docker compose logs -f

Example 5: VM Template Creation

Creating Reusable VM Templates

# 1. Create and fully configure a base VM
./scripts/vm-management/vm-post-install.sh 10.10.0.199 cal

# 2. Clean up the VM for template use
ssh cal@10.10.0.199 '
    # Clear bash history
    history -c && history -w
    
    # Clear logs
    sudo truncate -s 0 /var/log/*log
    sudo truncate -s 0 /var/log/syslog
    
    # Clear SSH host keys (regenerated on first boot)
    sudo rm -f /etc/ssh/ssh_host_*
    
    # Clear machine ID
    sudo truncate -s 0 /etc/machine-id
    
    # Clear network configuration
    sudo rm -f /etc/udev/rules.d/70-persistent-net.rules
    
    # Shutdown
    sudo shutdown -h now
'

# 3. Convert VM to template in Proxmox
pvesh create /nodes/pve/qemu/199/template

# 4. Clone template to create new VMs
pvesh create /nodes/pve/qemu/199/clone -newid 201 -name homelab-from-template

Example 6: Monitoring and Verification

Post-Deployment Health Checks

#!/bin/bash
# VM health check script
# Usage: ./vm-health-check.sh <vm-ip>

VM_IP="$1"

echo "🔍 VM Health Check: $VM_IP"

# Test SSH connectivity
if ssh -o ConnectTimeout=5 cal@$VM_IP 'echo "SSH OK"' >/dev/null 2>&1; then
    echo "✅ SSH: Connected"
else
    echo "❌ SSH: Failed"
    exit 1
fi

# Check system info
INFO=$(ssh cal@$VM_IP '
    echo "Hostname: $(hostname)"
    echo "Uptime: $(uptime -p)"
    echo "Memory: $(free -h | grep Mem | awk "{print \$3\"/\"\$2}")"
    echo "Disk: $(df -h / | tail -1 | awk "{print \$3\"/\"\$2\" (\"\$5\" used)\"}")"
')

echo "$INFO"

# Test Docker
if ssh cal@$VM_IP 'docker --version && docker compose version' >/dev/null 2>&1; then
    echo "✅ Docker: Installed and working"
else
    echo "❌ Docker: Not working"
fi

# Test Docker permissions
if ssh cal@$VM_IP 'docker run --rm hello-world' >/dev/null 2>&1; then
    echo "✅ Docker: User permissions OK"
else
    echo "❌ Docker: User permissions issue"
fi

echo "🎉 Health check completed"

Common Workflows

1. New Development Environment

# Create VM with cloud-init
# Wait for provisioning
# Deploy development stack
ssh cal@10.10.0.201 '
    mkdir -p ~/dev
    cd ~/dev
    
    # Clone your project
    git clone https://github.com/your-org/project.git
    cd project
    
    # Start development environment
    docker compose -f docker-compose.dev.yml up -d
'

2. Service Migration

# Provision new VM
./scripts/vm-management/vm-post-install.sh 10.10.0.202 cal

# Copy service configuration from existing server
scp -r cal@10.10.0.124:~/services/app-name cal@10.10.0.202:~/services/

# Start service on new VM
ssh cal@10.10.0.202 'cd ~/services/app-name && docker compose up -d'

3. Testing Environment

# Quick test environment with cloud-init
# Use minimal resources: 1GB RAM, 1 CPU, 10GB disk
# Deploy test configuration
# Run automated tests
# Destroy when done

Troubleshooting Examples

VM Won't Start After Cloud-Init

# Check cloud-init logs
ssh cal@<vm-ip> 'sudo cloud-init status --long'
ssh cal@<vm-ip> 'sudo cat /var/log/cloud-init-output.log'

# Manual cloud-init re-run if needed
ssh cal@<vm-ip> 'sudo cloud-init clean && sudo cloud-init init'

SSH Key Issues

# Verify keys are properly installed
ssh cal@<vm-ip> 'cat ~/.ssh/authorized_keys | wc -l'  # Should show 2 keys

# Test specific key
ssh -i ~/.ssh/homelab_rsa cal@<vm-ip> 'echo "Primary key works"'
ssh -i ~/.ssh/emergency_homelab_rsa cal@<vm-ip> 'echo "Emergency key works"'

Docker Permission Problems

# Check user groups
ssh cal@<vm-ip> 'groups'  # Should include 'docker'

# Re-login to apply group membership
ssh cal@<vm-ip> 'newgrp docker'

# Test Docker access
ssh cal@<vm-ip> 'docker ps'
  • Scripts: scripts/vm-management/README.md - Implementation details
  • Patterns: patterns/vm-management/README.md - Architectural guidance
  • SSH Setup: examples/networking/ssh-homelab-setup.md - Key management
  • Docker: examples/docker/ - Container deployment patterns