Intro

In this post I will cover the process to import and use cloud based images in Proxmox. Cloud based images are handy because they are configurable on boot via cloud-init . I will use the image created in this post in a future post on how to deploy VMs in Proxmox via Terraform.

The following software was used in this post.

  • Proxmox - 7.0-11
  • Ubuntu - 20.04

Image Prep

Prior to uploading the cloud images to the Proxmox host, I will be downloading them to an Ubuntu host to install the qemu-guest-agent . The guest agent allows for introspection into the guest from the host and better integrations to control the guest shutdown, restart etc..

The libguestfs-tools package allows you to install packages into an image without booting it up. The libguestfs-tools package conflicts with Proxmox. For this reason, I am using my Ubuntu host to complete this step.

Lets get started by downloading a cloud image.

cmd
curl -O http://cloud-images.ubuntu.com/releases/focal/release/ubuntu-20.04-server-cloudimg-amd64.img

Now install libguestfs-tools .

cmd
sudo apt install libguestfs-tools -y

Install the qemu-guest-agent into the image.

cmd
sudo virt-customize -a focal-server-cloudimg-amd64.img --install qemu-guest-agent

# output
[   0.0] Examining the guest ...
[  27.1] Setting a random seed
virt-customize: warning: random seed could not be set for this type of guest
[  27.3] Setting the machine ID in /etc/machine-id
[  27.4] Installing packages: qemu-guest-agent
[ 130.6] Finishing off

Once the package is installed, copy the image to the Proxmox host.

cmd
scp ubuntu-20.04-server-cloudimg-amd64.img <user>@<host>:/tmp/

Proxmox Host

Create a new VM that will be used as the base for future images.

cmd
qm create 9001 \
  --name ubuntu-2004-cloud-init --numa 0 --ostype l26 \
  --cpu cputype=host --cores 2 --sockets 1 \
  --memory 2048  \
  --net0 virtio,bridge=vmbr0

Import the cloud image to a storage pool.

cmd
qm importdisk 9001 /tmp/ubuntu-20.04-server-cloudimg-amd64.img local-lvm
  
# output
Successfully imported disk as 'unused0:local-lvm:vm-9001-disk-0'

Attach the disk to the VM as a SCSI drive.

cmd
qm set 9001 --scsihw virtio-scsi-pci --scsi0 local-lvm:vm-9001-disk-0

# output
update VM 9001: -scsi0 local-lvm:vm-9001-disk-0 -scsihw virtio-scsi-pci

Create a cloud-init CDROM drive. This allows you to assign configuration to the VM on boot.

cmd
qm set 9001 --ide2 local-lvm:cloudinit

# output
update VM 9001: -ide2 local-lvm:cloudinit
  Logical volume "vm-9001-cloudinit" created.

Make the VM disk bootable.

cmd
qm set 9001 --boot c --bootdisk scsi0

# output
update VM 9001: -boot c -bootdisk scsi0

Assign a serial console to the VM. This required by some cloud-init images.

cmd
qm set 9001 --serial0 socket --vga serial0

# output
update VM 9001: -serial0 socket -vga serial0

Enable the guest agent.

cmd
qm set 9001 --agent enabled=1

# output
update VM 9001: -agent enabled=1

Convert the VM to a template. The template will be used to clone future VMs.

cmd
qm template 9001

# output
Renamed "vm-9001-disk-0" to "base-9001-disk-0" in volume group "pve"
Logical volume pve/base-9001-disk-0 changed.
WARNING: Combining activation change with other commands is not advised.

Create VM

Now that the VM template is built, lets create a VM from the template.

cmd
qm clone 9001 999 \
  --name ubuntu-test \
  --full \
  --storage local-lvm

# output
create full clone of drive ide2 (local-lvm:vm-9001-cloudinit)
  Logical volume "vm-999-cloudinit" created.

Assign an SSH key to the VM that will be applied via cloud-init on boot.

cmd
qm set 999 --sshkey ~/.ssh/id_rsa.pub

# output
update VM 999: -sshkeys ssh-rsa...

For this test I will assign an IP address to the VM that will be applied via cloud-init on boot.

cmd
qm set 999 --ipconfig0 ip=192.168.255.60/24,gw=192.168.255.1
  
# output
update VM 999: -ipconfig0 ip=192.168.255.60/24,gw=192.168.255.1

Start the VM.

cmd
qm start 999

# output
generating cloud-init ISO

Once the VM has booted, SSH to the VM with the SSH key previously defined and the default username, ubuntu in the case of Ubuntu cloud images.

cmd
ssh ubuntu@192.168.255.60

# Accept hostkey
The authenticity of host '192.168.255.60 (192.168.255.60)' cant be established.
ECDSA key fingerprint is SHA256:4iiOYYaI1uS7cH1YqIByhZfTAJSgwtiQtLSMkkUHAdc.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes

ubuntu@ubuntu-test:~$

Clean Up

Shutdown and delete the VM.

cmd
qm stop 999 && qm destroy 999

Remove the orginal cloud image

cmd
rm /tmp/ubuntu-20.04-server-cloudimg-amd64.img

Outro

In this post, I covered the process to import an Ubuntu cloud image as a VM template, deploy a VM from the template and configure the VM via cloud-init .