Skip to main content

cloud-init

cloud-init is a tool to customize a VM during the first boot.

Why cloud-init?

I can install and update software, create users, set up public ssh key, run commands, etc. Combined with Terraform, I can provision a new VM in 1 command.

Ubuntu cloud image

Ubuntu 24.04 cloud image is the base image for my VMs. It's pre-installed and updated with the latest packages, so it saves me a lot of time from downloading and installing updates manually.

Examples

Basic example

#cloud-config
users:
- default
# create a sudo user
- name: ${username}
groups:
- sudo
shell: /bin/bash
# allow ssh login for this user
ssh_authorized_keys:
%{~ for key in ssh_public_keys ~}
- ${key}
%{~ endfor ~}
# allow sudo without password
sudo: ALL=(ALL) NOPASSWD:ALL

# update and upgrade packages
package_update: true
package_upgrade: true

# install packages
packages:
- qemu-guest-agent # need this for guest mode in Proxmox
- curl
- ca-certificates
- unattended-upgrades

# run commands after cloud-init finishes
runcmd:
- timedatectl set-timezone America/New_York
- systemctl enable qemu-guest-agent
- systemctl start qemu-guest-agent
- echo "done" > /tmp/cloud-config.done

NFS server example

# the rest of the config is the same as above

# create a new file and write nfs mounts
write_files:
- path: /etc/exports
content: |
/shares 192.168.0.0/16(rw,fsid=0,no_subtree_check,sync,all_squash,anonuid=1001,anongid=1001)
/shares/configs 192.168.0.0/16(rw,no_subtree_check,sync,all_squash,anonuid=1001,anongid=1001)

packages:
- nfs-kernel-server
# ...

runcmd:
- mkdir -p /shares/configs
- chmod 775 -R /shares
- systemctl start nfs-kernel-server.service
- exportfs -ar
# ...

Validation

cloud-init config can be validated with:

cloud-init schema --config-file a.yaml

After the VM is created, its status can be checked with:

cloud-init status

Troubleshooting

In case of issues, the logs can be found in /var/log/cloud-init.log and /var/log/cloud-init-output.log.