Creating a Debain Template on Proxmox with a Cloud Image

Kyle Prince - - 5 mins read

Download and Import Cloud Image

All of these commands will have to be run directly from the proxmox shell.

Download the Image

The first step is to download the cloud image from debian.org. It is important to get the qcow2 image that matches your system architecture. Most machines that are running proxmox are likely using a 64 bit x86 processor. For this article, I’m going to keep the commands to that type of system. If you are using arm or riscv, you probably know more than I do.

wget https://cdimage.debian.org/images/cloud/trixie/latest/debian-13-generic-amd64.qcow2

Create a New VM with VirtIO SCSI Controller

This will create a new Virtual Machine. The 9000 in this example, is the VM ID. If you already have a VM or Template using that ID, you will have to change the number to one that is available. This will also create a virtual network device that connects to the network bridge vmbr0. This is the default on most systems, but if you have more than one NIC, you may have to change this too. The scsi settings are needed to import the cloud image in the next step.

qm create 9000 --memory 1024 --net0 virtio,bridge=vmbr0 --scsihw virtio-scsi-pci

Import the Image to the VM Storage

This imports the cloud image into the new virtual machine as a scsi drive. Make sure that the VM ID matches the previous step. You will also need to be sure that the path to image is correct. If you changed directories before running the command in the first step, then you will have to change the path to the image, to match it’s actual location in the file system.

qm set 9000 --scsi0 local-lvm:0,import-from=/root/debian-13-generic-amd64.qcow2

Changing the VM Settings

There are some hardware, VM options and cloud-init settings that I would recommend changing.

Changing Hardware Settings

On VM 9000 (or whatever ID you used) go to the hardware tab. All virtual hardware is added through the add dropdown menu.

For UEFI Templates

There are only three steps for using UEFI. They are:

  • Add an EFI disk
    • You will need to select a storage location. I only had one option (lvm-local), but any are fine
  • Select BIOS and edit
    • Select OVFM bios
  • Select Machine and edit
    • Select q35

For All Templates

Add a cloud-init drive to the VM. Any storage location will work.

Since the virtual disk has no free space, add a little room

  • Select hard disk, Disk Action, Resize
    • add at least 1G to virtual disk

Changing the Cloud-Init Settings

You don’t need to do this, but I would rather have some default settings before I start cloning my template. It can be nice to have a default admin user on each VM. Any of these can be changed after cloning the template. Select Cloud-Init and change the following settings

  • User
  • Password
  • SSH public key (if you have one)
  • IP Config
    • Set ip address or select DHCP

Changing the Options

The only thing in here that truly needs to be done is changing the boot order. I prefer to change the name, since matching the template name to the cloud init vendor file helps keep things managable. I also always enable QEMU guest agent on all VM’s on proxmox. That will allow the host system to safely shut down VM’s if it nees to. Select VM options and change these settings

  • Name
    • Change to whatever you want your template to be named
  • Boot Order
    • Enable the SCSI device
    • Change to boot from SCSI device
  • QEMU-Guest-Agent
    • Enable this

Set Local Storage to Allow Snippets

Under data center - storage - select local - edit - add snippets in the content drop down

Create Vendor File

From the proxmox shell, in /var/lib/vz/snippets create the vendor file vendor.yaml. The vendor file name is just generic here for this example but it is wise to match the name of the template. If you ever need to edit or remove the file, then matching the vendor file name to the template name will make it easier to identify where the change needs to be made.

vim /var/lib/vz/snippets/vendor.yaml

Here are a couple of examples that I use. They will install qemu-guest-agent, vim-nox, ufw and htop on the VM after the first boot. Then it will create a firewall rule to allow ssh connections, start the firewall and reboot.

#cloud-config

packages:
  - qemu-guest-agent
  - vim-nox
  - ufw
  - htop

runcmd:
  - ufw allow ssh
  - ufw enable
  - reboot

The next one is the same except that it will install the latest docker-ce and add the user created by cloud-init to the docker group before rebooting.

#cloud-config

packages:
  - qemu-guest-agent
  - vim-nox
  - ufw
  - htop

runcmd:
  - ufw allow ssh
  - ufw enable
  - curl -sSL https://get.docker.com/ | sh
  - sudo usermod -aG docker $(id -u -n 1000)
  - reboot

Apply Vendor File to VM

Then you simply identify the vendor file to be applied to the template. Of course, make sure the VM ID matches the template and the vendor file name is correct.

qm set 9000 --cicustom "vendor=local:snippets/vendor.yaml"

Create a Template from the VM

The last step is to select the VM from the left hand menu of proxmox. Right click on the VM and select convert to template. Select “Yes” on the next pop up screen and you have the most functional, lightweight, template that debian can offer. It’s not the fastest deploying template, but it is certainly the best one that I have come across. Happy labbing!