Create a Debian Cloud-Init image on Proxmox

I recently began to set up a new MiniPC cluster and needed a VM template. Usually, I would use something like Ubuntu. However, this time I wanted to go with Debian. Initially, my older methods of using Packer seemed to offer little for this process. Though I was looking half-heartedly. Then along came Brandon’s post on his deployment of Debian 11.

Brandon’s method seemed solid, but it had a few issues for my work case:

  • Debian 11 and not Debian 12.
  • Instructions weren’t 100% clear.
  • I wanted Trim on the main storage.
  • I wanted to set Start On Boot.
  • Disk Size was set to 2GB by default.

Initial Steps

Let’s first login to your Proxmox server running something newer, such as versions 7 or 8.

Once logged in, open up the shell inside of your desired deployment server.

At this point, you should be greeted by a BASH prompt as root@<YourServersName>.

First, let’s head to the tmp directory by running cd /tmp.

Secondly, we need to download the image from Debian’s cloud image website. You can select whichever version you Debian you would like but I would suggest Bookworm as it is the current latest.

After deciding the version you will be using. Select the latest build and find the file named debian-<version>-genericcloud-amd64-<date>.qcow2. For me as of this writing that is debian-12-genericcloud-amd64-20240507-1740.qcow2. Copy the link to that file, and we will use it to download to our tmp directory. To do that, run wget https://cloud.debian.org/images/cloud/bookworm/20240507-1740/debian-12-genericcloud-amd64-20240507-1740.qcow2

Summary:

# Change to tmp directory to keep things clean.
cd /tmp

# Download image from debian's website.
wget https://cloud.debian.org/images/cloud/bookworm/20240507-1740/debian-12-genericcloud-amd64-20240507-1740.qcow2 

Initial VM Creation

Now that we have downloaded the Debian image, we need to create an actual VM.

First, we need to create a VM. For my documentation, I am going to use the VMID of 900 but you can change this to whatever you like.

qm create 900 --name Debian12CI --net0 virtio,bridge=vmbr0

Values:

  • 900 = VMID
  • Debian12CI = VM Name, and will transition to your Template name.
  • virtio = network type, Virtio is the suggested method here.
  • vmbr0 = The name of your network bridge in Proxmox. Default is: vmbr0.

Secondly, we need to import the disk we downloaded from earlier.Make sure to use the name of the file you downloaded.

qm importdisk 900 debian-12-genericcloud-amd64-20240507-1740.qcow2 local-lvm

Values:

  • 900 = VMID
  • debian-12-genericcloud-amd64-20240507-1740.qcow2 = Name of the image we downloaded from Debian’s website. You can find the version you downloaded with ls /tmp.
  • local-lvm = Storage location on your server. This could also be something like local-zfs.

Now let’s make it so we can mount the disk we just created.

qm set 900 --scsihw virtio-scsi-pci --scsi0 local-lvm:vm-900-disk-0,discard=on

Values:

  • 900 = VMID
  • virtio-scsi-pci = VMs host bus adapter for talking to your virtual drives.
  • local-lvm:vm-900-disk-0 = The default disk created by our previous command along with the storage location.
  • discard=on = Enable VM Trimming of disk to conserve space (Thin Provision).

Now we need to create a Cloud-Init drive! It’s why we are here after all!

qm set 900 --ide2 local-lvm:cloudinit

Values:

  • 900 = VMID
  • local-lvm = storage location.
  • cloudinit = cloudinit drive location, this shouldn’t be changed.

Let’s set our default boot drive.

qm set 900 --boot c --bootdisk scsi0

Values:

  • 900 = VMID
  • scsi0 = id of the drive we created two steps ago.

This step is very much Optional but we can set up a serial terminal instead of a graphical one. To do this, run the following command.

qm set 900 --serial0 socket --vga serial0

Values:

  • 900 = VMID
  • –serial0 = Creates a serial interface.
  • socket = Specifies the type of serial connection.
  • –vga = We are setting the VM shell method on serial0.

To make it so our Proxmox node and VM can do some light communication let’s set up the agent utility. To make this work, you will need to manually install qemu-guest-agent inside of your VM after it is created.

qm set 900 --agent enabled=1

Values:

  • 900 = VMID
  • --agent enabled=1 = Enabling the agent option on the VM config.

Summary:

# Create VM.
qm create 900 --name Debian12CI --net0 virtio,bridge=vmbr0

# Import the image we previously downloaded to an virtual disk.
qm importdisk 900 debian-12-genericcloud-amd64-20240507-1740.qcow2 local-lvm

# Attach the virtual disk to our VM.
qm set 900 --scsihw virtio-scsi-pci --scsi0 local-lvm:vm-900-disk-0,discard=on

# Add the cloud-init drive.
qm set 900 --ide2 local-lvm:cloudinit

# Set our boot drive.
qm set 900 --boot c --bootdisk scsi0

# Use a serial console.
qm set 900 --serial0 socket --vga serial0

# Enable the agent.
qm set 900 --agent enabled=1

At this point, we now have a functional VM. At this point in the original documentation we would convert this into a Template and be on our way. However, I want to add a few more edits.

Customization

I want my new templates to already have the onboot flag set. We can do that with the following command.

qm set 900 --onboot 1

Values:

  • 900 = VMID
  • --onboot 0 = Disabled Autostart
  • --onboot 1 = Enabled Autostart

Since we made this VM from scratch it doesn’t have some other customizations. Let’s inform our system that it is running a 2.6+ linux kernel.

qm set 900 --ostype l26

Values:

  • 900 = VMID
  • l26 = Linux 6.x - 2.6 Kernel. (Moden Linux Kernels): l24, l26, other, solaris, w2k, w2k3, w2k8, win10, win11, win7, win8, wvista, wxp

Let’s give ourselves some more space by increasing the default disk size to something more comfortable.

qm resize 900 scsi0 +30G

Values:

  • 900 = VMID
  • local-lvm:vm-900-disk-0 = Our file path to the virtual disk.
  • 30 = Increase by 30GB of storage. Should end up around 32GB.

Let’s increase the default memory to 2GB. qm set 900 --memory 2048

Values:

  • 900 = VMID
  • --memory 2048 = Memory in MBs. 2048 = 2GB, 4096 = 4GB, 8192 = 8GB.

Summary:

# Set to autoboot.
qm set 900 --onboot 1

# Set the OS Type to Linux 2.6 +
qm set 900 --ostype l26

# Resize the storage
qm resize 900 scsi0 +30G

# Increase Memory
qm set 900 --memory 2048

Template Time!

We need to transition this into a template, which is pretty easy! Simply run: qm template 900

Summary:

# Change our VM into a template

qm template 900

Clone and Cloud-Init

Now when you are ready to deploy, head into Proxmox and either right-click then clone your template or run the following command: qm clone 900 901 --name cloned-vm.

Afterward, head into your new VM and manually edit the Cloud-init section of your VM. Make sure to set the: User, Password, DNS Servers, IP Config settings or you are going to have a difficult time.

Next, head into the hardware settings and confirm your needs are met for the VM you will be running. Take a look at Memory, CPU, Disk, and Network settings.

After that, head into options and brush up any final things before starting your VM.

At this point, you can right-click and start your new VM.

Happy Proxmoxing!

Extra:

Here is a look at my setup.

# Change to tmp directory to keep things clean.
cd /tmp

# Download image from debian's website.
wget https://cloud.debian.org/images/cloud/bookworm/20240507-1740/debian-12-genericcloud-amd64-20240507-1740.qcow2 

# Create VM.
qm create 900 --name Debian12CI --net0 virtio,bridge=insecure

# Import the image we previously downloaded to an virtual disk.
qm importdisk 900 debian-12-genericcloud-amd64-20240507-1740.qcow2 local-lvm

# Attach the virtual disk to our VM.
qm set 900 --scsihw virtio-scsi-pci --scsi0 local-lvm:vm-900-disk-0,discard=on

# Add the cloud-init drive.
qm set 900 --ide2 local-lvm:cloudinit

# Set our boot drive.
qm set 900 --boot c --bootdisk scsi0

# Use a serial console.
qm set 900 --serial0 socket --vga serial0

# Enable the agent.
qm set 900 --agent enabled=1

# Set to autoboot.
qm set 900 --onboot 1

# Set the OS Type to Linux 2.6 +
qm set 900 --ostype l26

# Resize the storage
qm resize 900 scsi0 +254G

# Increase Memory
qm set 900 --memory 8192

# Increase CPU Count and makes them more migratable.
qm set 900 --cpu cputype=x86-64-v4 --cores 4 --sockets 1

You can find out your supported cputype by the following script modified from David Yin’s Blog.

#!/bin/sh -eu
 
flags=$(cat /proc/cpuinfo | grep flags | head -n 1 | cut -d: -f2)
 
supports_v2='awk "/cx16/&&/lahf/&&/popcnt/&&/sse4_1/&&/sse4_2/&&/ssse3/ {found=1} END {exit !found}"'
supports_v2_aes='awk "/aes/ {found=1} END {exit !found}"'
supports_v3='awk "/avx/&&/avx2/&&/bmi1/&&/bmi2/&&/f16c/&&/fma/&&/abm/&&/movbe/&&/xsave/ {found=1} END {exit !found}"'
supports_v4='awk "/avx512f/&&/avx512bw/&&/avx512cd/&&/avx512dq/&&/avx512vl/ {found=1} END {exit !found}"'
 
echo "$flags" | eval $supports_v2 || exit 2 && echo "CPU supports x86-64-v2"
echo "$flags" | eval $supports_v2_aes || exit 2 && echo "CPU supports x86-64-v2-AES"
echo "$flags" | eval $supports_v3 || exit 3 && echo "CPU supports x86-64-v3"
echo "$flags" | eval $supports_v4 || exit 4 && echo "CPU supports x86-64-v4"