Skip to content

Instantly share code, notes, and snippets.

@golles
Created February 16, 2026 15:18
Show Gist options
  • Select an option

  • Save golles/57efa3dd70ff9bcaf3b49d0d02a9ef38 to your computer and use it in GitHub Desktop.

Select an option

Save golles/57efa3dd70ff9bcaf3b49d0d02a9ef38 to your computer and use it in GitHub Desktop.
#!/bin/bash
#
# Usage: ./create-homelab-template.sh <IMAGE_PATH>
#
# This script creates a VM template from a given cloud image file.
#
# For example from debian-13-generic-amd64.qcow2 that is imported in local storage:
# ./create-homelab-template.sh /var/lib/vz/import/debian-13-generic-amd64.qcow2
set -euo pipefail
VMID="9000"
NAME="homelab-template"
USER="homelab"
STORAGE="local-lvm"
IMAGE_PATH="$1"
# Check if the image file exists
if [[ ! -f "$IMAGE_PATH" ]]; then
echo "❌ Image file '$IMAGE_PATH' not found."
exit 1
fi
# Check if VMID already exists
if qm status "$VMID" &>/dev/null; then
echo "❌ VM with ID $VMID already exists. Use 'qm destroy $VMID' to remove it first."
exit 1
fi
# Create the VM with hardware options and cloud-init settings
qm create "$VMID" \
--name "$NAME" \
--memory 1024 \
--cores 1 \
--cpu host \
--ostype l26 \
--machine q35 \
--bios ovmf \
--agent 1 \
--scsihw virtio-scsi-pci \
--scsi0 "$STORAGE":0,import-from="$IMAGE_PATH" \
--efidisk0 "$STORAGE":0,efitype=4m \
--ide2 "$STORAGE":cloudinit \
--net0 virtio,bridge=vmbr0 \
--boot order=scsi0 \
--serial0 socket \
--vga serial0 \
--ciuser "$USER" \
--ipconfig0 ip=dhcp \
--cicustom "vendor=local:snippets/homelab-vendor-file.yaml"
# Resize the disk by +1GB to guarantee enough space for cloud-init and initial updates
qm resize "$VMID" scsi0 +1G
# Convert VM into a template
qm template "$VMID"
echo "✅ VM $NAME ($VMID) created and converted into a template successfully!"
echo "Don't forget to set a password and/or SSH key in the VM cloud-init config."
#!/bin/bash
#
# Usage: ./create-homelab-vm.sh <machine-type>
#
# machine-type must be one of: databases | media | monitoring | network | smarthome | test | web
#
# This script clones VM 9000 (homelab template) and applies predefined settings based on the machine type.
set -euo pipefail
TEMPLATE_ID="9000"
STORAGE="local-lvm"
BRIDGE="vmbr0"
TAG="homelab"
MACHINE="${1:-}"
if [[ -z "$MACHINE" ]]; then
echo "Usage: $0 <machine-type>"
exit 1
fi
# Defaults (overwritten in case block)
VMID=""
CORES=2
MEMORY=1024
DISK="8G"
MAC=""
IP=""
GW="192.168.68.1"
# Machine profiles
case "$MACHINE" in
databases)
VMID=101
CORES=4
MEMORY=2048
DISK="32G"
MAC="BC:24:11:49:0B:A1"
IP="192.168.68.101/24"
;;
media)
VMID=102
CORES=4
MEMORY=4096
DISK="8G"
MAC="BC:24:11:49:0B:A2"
IP="192.168.68.102/24"
;;
monitoring)
VMID=103
CORES=2
MEMORY=2048
DISK="8G"
MAC="BC:24:11:49:0B:A3"
IP="192.168.68.103/24"
;;
network)
VMID=104
CORES=2
MEMORY=2048
DISK="8G"
MAC="BC:24:11:49:0B:A4"
IP="192.168.68.104/24"
;;
smarthome)
VMID=105
CORES=4
MEMORY=4096
DISK="8G"
MAC="BC:24:11:49:0B:A5"
IP="192.168.68.105/24"
;;
web)
VMID=106
CORES=2
MEMORY=2048
DISK="8G"
MAC="BC:24:11:49:0B:A6"
IP="192.168.68.106/24"
;;
test)
VMID=109
CORES=1
MEMORY=1024
DISK="8G"
MAC="BC:24:11:49:0B:A9"
IP="192.168.68.109/24"
;;
*)
echo "❌ Invalid machine type: $MACHINE"
exit 1
;;
esac
# Check if VMID already exists
if qm status "$VMID" &>/dev/null; then
echo "❌ VM with ID $VMID already exists. Use 'qm destroy $VMID' to remove it first."
exit 1
fi
echo "Creating VM $MACHINE ($VMID)..."
# Clone from template (full clone)
qm clone "$TEMPLATE_ID" "$VMID" --name "$MACHINE" --full true --storage "$STORAGE"
# Apply hardware settings
qm set "$VMID" \
--cores "$CORES" \
--memory "$MEMORY" \
--net0 virtio="$MAC",bridge="$BRIDGE" \
--tags "$TAG" \
--ipconfig0 ip="$IP",gw="$GW" \
--description "Homelab $MACHINE VM"
# Resize disk (scsi0 inherited from template)
qm resize "$VMID" scsi0 "$DISK"
echo "✅ VM $MACHINE ($VMID) created successfully."
echo "CPU: $CORES cores"
echo "Memory: $MEMORY MB"
echo "Disk: $DISK"
echo "MAC: $MAC"
echo "IP: $IP (don't forget to reserve it in your DHCP server)"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment