Programster's Blog

Tutorials focusing on Linux, programming, and open-source

Create Ubuntu 22.04 KVM Guest From Cloud Image

Similar Posts


Download the Ubuntu 22.04 server cloud Image and rename to qcow2 to save confusion.

sudo mkdir /var/lib/libvirt/images/templates

sudo mv -i jammy-server-cloudimg-amd64.img \

We need to ensure we have cloud-utils and whois packages for later.

sudo apt update \
  && sudo apt install cloud-utils whois -y

The cloud-utils package is required for Debian 10 to be able to run the cloud-localds command, and the whois package is required for us to be able to run mkpasswd later. Your distro may have a different name for the required packages.


First, pick a name for your new VPS, and what you would want the username/password combo to be for the default user that will be set up:


Create an area for our new VM and copy the template cloud image into it, which will be used by the new VM.

sudo mkdir /var/lib/libvirt/images/$VM_NAME \
  && sudo qemu-img convert \
  -f qcow2 \
  -O qcow2 \
  /var/lib/libvirt/images/templates/ubuntu-22-server.qcow2 \

Increase the disk size to whatever you want for the VM, in this case I'm setting 20 GB

sudo qemu-img resize \
  /var/lib/libvirt/images/$VM_NAME/root-disk.qcow2 \

Create a cloud-init configuration so we can set the password and the hostname etc.

sudo echo "#cloud-config
    name: $USERNAME
    home: /home/$USERNAME

password: $PASSWORD
chpasswd: { expire: False }
hostname: $VM_NAME

# configure sshd to allow users logging in using password 
# rather than just keys
ssh_pwauth: True
" | sudo tee /var/lib/libvirt/images/$VM_NAME/cloud-init.cfg

The default user to log in with will be the user that you specified earlier. If we had not set a username, the default user would have been ubuntu. If you need to further customize your VM on first setup, there are plenty of online cloud config examples.

Create the ISO file from the cloud config file we just created:

sudo cloud-localds \
  /var/lib/libvirt/images/$VM_NAME/cloud-init.iso \
sudo virt-install \
  --name $VM_NAME \
  --memory 1024 \
  --disk /var/lib/libvirt/images/$VM_NAME/root-disk.qcow2,device=disk,bus=virtio \
  --disk /var/lib/libvirt/images/$VM_NAME/cloud-init.iso,device=cdrom \
  --os-type linux \
  --os-variant ubuntu19.04 \
  --virt-type kvm \
  --graphics none \
  --network network=default,model=virtio \

The --os-variant is listed as ubuntu19.04 because Debain 10 does not have ubuntu22.04 in the list outputted from running sudo osinfo-query os (which I could only run after installing the libosinfo-bin package).

After running the previous command, you will be taken to the login screen in the console, which you can log in with using the username and password you specified at the start of this tutorial.

If you need to get out of the console just press ctrl + ].


After that, it's probably a good idea to cleanup so raw passwords aren't lying around.

sudo rm /var/lib/libvirt/images/$VM_NAME/cloud-init.iso \
  && sudo rm /var/lib/libvirt/images/$VM_NAME/cloud-init.cfg

This will have removed the ISO file from your computer, but your VM may still be set up to use it. In which case edit your VM configuration:

sudo virsh edit $VM_NAME

Then remove this section:

    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <source file='/var/lib/libvirt/images/template-ubuntu-22/cloud-init.iso'/>
      <target dev='sda' bus='sata'/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>

Hostname And Hosts File

It appears that setting the hostname in the cloud-init config will set the hostname that the machine will boot as. However, it will not add the entry to the /etc/hosts file, so you may wish to do this quickly to prevent your machine taking unnecessarily long when performing some operations. Alternatively, you may figure out how to update the cloud-init.cfg file to update the hosts file correctly using the Etc hosts module.

A Note About Cloning

If you later decide to clone the VM you just spun up, in order to create a new guest, be aware that the /etc/netplan/50-cloud-init.yaml file will have a hardcoded mac address in there to match. E.g.

            dhcp4: true
                macaddress: 52:54:00:c2:9e:bc
            set-name: enp1s0
    version: 2

Before you create the clone, change the "template" VM to remove the match line and the two below it to become:

            dhcp4: true
    version: 2

This way, when the new guests are created with new, random mac addresses, their network will still work.

Disable Cloud Init

After having installed the guest, you will likely want to disable cloud-init from inside the guest by running the following command:

sudo touch /etc/cloud/cloud-init.disabled

This will stop cloud-init running any steps on startup, such as resetting your hostname.


Last updated: 13th August 2022
First published: 13th May 2022