Provision a VM with Cloud Image and Cloud-init

Zhimin Wen
3 min readFeb 13, 2022
Image by Mikes-Photography from Pixabay

The cloud image is a standard release for many of the Linux distributions. Thanks to cloud-init, we can uniformly provision and customize a VM quickly for different flavors of Linux in a standard way.

Take an example of a Ubuntu cloud image with KVM.

1. Get the latest cloud image

Download the current version of 20.04 LTS,

curl -LO http://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64-disk-kvm.img

2. Create the image disk

Use the base image as a backing image, create a new disk of 100GB

qemu-img create -b focal-server-cloudimg-amd64-disk-kvm.img -F qcow2 -f qcow2 cl-ubuntu.qcow2 100G

Specify the backing image format with “-F” also.

3. Prepare Cloud-init disk

Create the following user data for cloud-init, named as userdata.yaml

#cloud-config
hostname: cl-ubuntu
fqdn: cl-ubuntu
manage_etc_hosts: false
ssh_pwauth: true
disable_root: false
users:
- default
- name: ubuntu
shell: /bin/bash
sudo: ALL=(ALL) NOPASSWD:ALL
lock_passwd: false
ssh-authorized-keys:
- "content of ssh public key..."
chpasswd:
list: |
root:password
ubuntu:password
expire: false
runcmd:
- [ sh, -c, echo 192.168.100.10 cl-ubuntu | tee -a /etc/hosts]

Set the hostname and FQDN hostname. We allow the SSH password-based login and the root login for testing purposes.

Under the user session, first, include the default user. Then update it with the next block following it. Allow the sudo for all commands without a password prompt. Allow for password-based authentication. Include the authorized SSH public key as a YAML array.

Update the default password. In the chpasswd block, use the list format. Notice the content under the list is the text format, not the key: value format of YAML. Cloud-init will use the list line by line feeding into the chpasswd command.

Lastly, we run a shell command to update the /etc/hosts to update the hostname. This is to avoid the issue of “sudo

Zhimin Wen