#!/bin/bash source ~/.bashrc # Configure Cloud-Init on Proxmox VMs via API # Sets up IP addresses, users, and basic configuration set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" # Load environment variables if [ -f "$PROJECT_ROOT/.env" ]; then set -a source <(grep -v '^#' "$PROJECT_ROOT/.env" | grep -v '^$' | sed 's/#.*$//' | grep '=') set +a fi # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' PVE_USERNAME="${PVE_USERNAME:-root@pam}" PVE_PASSWORD="${PVE_ROOT_PASS:-}" PROXMOX_URL="${PROXMOX_ML110_URL:-https://192.168.1.206:8006}" PROXMOX_NODE="${PROXMOX_NODE:-pve}" log_info() { echo -e "${GREEN}[INFO]${NC} $1" } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } get_api_token() { local response=$(curl -s -k --connect-timeout 10 --max-time 15 \ -d "username=$PVE_USERNAME&password=$PVE_PASSWORD" \ "$PROXMOX_URL/api2/json/access/ticket" 2>&1) if echo "$response" | grep -q '"data"'; then local ticket=$(echo "$response" | grep -o '"ticket":"[^"]*' | cut -d'"' -f4) local csrf_token=$(echo "$response" | grep -o '"CSRFPreventionToken":"[^"]*' | cut -d'"' -f4) echo "$ticket|$csrf_token" else echo "" fi } configure_vm_cloudinit() { local vmid=$1 local name=$2 local ip=$3 local gateway=$4 local user=$5 log_info "Configuring cloud-init for VM $vmid ($name)..." local tokens=$(get_api_token) if [ -z "$tokens" ]; then log_error "Failed to authenticate with Proxmox" return 1 fi local ticket=$(echo "$tokens" | cut -d'|' -f1) local csrf_token=$(echo "$tokens" | cut -d'|' -f2) # Configure cloud-init settings local response=$(curl -s -k -X PUT \ -H "Cookie: PVEAuthCookie=$ticket" \ -H "CSRFPreventionToken: $csrf_token" \ -d "ipconfig0=ip=$ip/24,gw=$gateway" \ -d "ciuser=$user" \ -d "cipassword=" \ "$PROXMOX_URL/api2/json/nodes/$PROXMOX_NODE/qemu/$vmid/config" 2>&1) if echo "$response" | grep -q '"data"'; then log_info "VM $vmid cloud-init configured successfully" return 0 else log_error "Failed to configure VM $vmid: $response" return 1 fi } start_vm() { local vmid=$1 local name=$2 log_info "Starting VM $vmid ($name)..." local tokens=$(get_api_token) local ticket=$(echo "$tokens" | cut -d'|' -f1) local csrf_token=$(echo "$tokens" | cut -d'|' -f2) local response=$(curl -s -k -X POST \ -H "Cookie: PVEAuthCookie=$ticket" \ -H "CSRFPreventionToken: $csrf_token" \ "$PROXMOX_URL/api2/json/nodes/$PROXMOX_NODE/qemu/$vmid/status/start" 2>&1) if echo "$response" | grep -q '"data"'; then log_info "VM $vmid started successfully" return 0 else log_warn "VM $vmid may already be running or start failed: $response" return 0 fi } main() { log_info "Configuring cloud-init on all service VMs" if [ -z "$PVE_PASSWORD" ]; then log_error "PVE_ROOT_PASS not set in .env" exit 1 fi # VM definitions: vmid name ip gateway user local vms=( "100 cloudflare-tunnel 192.168.1.60 192.168.1.254 ubuntu" "101 k3s-master 192.168.1.188 192.168.1.254 ubuntu" "102 git-server 192.168.1.121 192.168.1.254 ubuntu" "103 observability 192.168.1.82 192.168.1.254 ubuntu" ) # Configure cloud-init for vm_spec in "${vms[@]}"; do read -r vmid name ip gateway user <<< "$vm_spec" configure_vm_cloudinit "$vmid" "$name" "$ip" "$gateway" "$user" sleep 1 done log_info "Waiting 5 seconds before starting VMs..." sleep 5 # Start VMs for vm_spec in "${vms[@]}"; do read -r vmid name ip gateway user <<< "$vm_spec" start_vm "$vmid" "$name" sleep 2 done log_info "Cloud-init configuration and VM startup completed!" log_warn "VMs are starting. They will boot with cloud-init configuration." log_warn "Check VM status via Proxmox web UI or API." } main "$@"