claude-home/vm-management/examples/proxmox-automation.md
Cal Corum 4b7eca8a46
All checks were successful
Reindex Knowledge Base / reindex (push) Successful in 3s
docs: add YAML frontmatter to all 151 markdown files
Adds title, description, type, domain, and tags frontmatter to every
doc for improved KB semantic search. The description field is prepended
to every search chunk, and domain/type/tags enable filtered queries.

Type values: context, guide, runbook, reference, troubleshooting
Domain values match directory structure (networking, docker, etc.)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 09:00:44 -05:00

355 lines
9.1 KiB
Markdown

---
title: "Proxmox Automation Examples"
description: "Working examples for Proxmox VM automation: cloud-init deployment, post-install scripting, bulk provisioning, Docker service deployment, VM template creation, and health check scripts."
type: reference
domain: vm-management
tags: [proxmox, automation, cloud-init, docker, templates, examples]
---
# 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
```bash
# 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:
```yaml
#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
```bash
# 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
```bash
#!/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:
```bash
# 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
```bash
# 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
```bash
#!/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
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# 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'
```
## Related Documentation
- **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