Setting hostname with Cloud-Init in Proxmox

I recently set up VM template using Proxmox following the official and very helpful Cloud-Init Support doc. With Cloud-Init, new VMs can be quickly created using automation, which is far faster and more reliable than manually clicking through the Proxmox web interface and the OS installation process.

Problem

Along the way, I learned that any user data set in cloud-config will cause Proxmox to not pass in the VM name to Cloud-Init, and the VM hostname would remain “localhost”. I needed a way to specify certain configurations in the template without changing the template for each new VM as that would greatly complicate the entire process.

I found some other people have struggled with this same problem
https://forum.proxmox.com/threads/hostname-in-cloud-init-user-data.129663/
https://forum.proxmox.com/threads/setting-host-name-via-cloud-init.45525/
https://forum.proxmox.com/threads/hostname-not-set-via-cloudinit-with-cicustom-and-ubuntu-22-04.110446/

Solution

I found an easy solution to this situation by simply specifying configuration in vendor data Cloud-Init data rather than user data.

if the user data Cloud-Init file is provided, the hostname will not be set!

The steps below explain the differences from the official Proxmox doc.

1. Create the vendor data Cloud-Init file

This installs and starts the Proxmox guest agent, and disables IPv6 networking.

note that any values provided in the users: key will be ignored.

also note that the file must start with #cloud-config

vi /mnt/data/snippets/vendorconfig.yaml

#cloud-config
packages:
  - qemu-guest-agent
runcmd:
  - systemctl enable qemu-guest-agent
  - systemctl start qemu-guest-agent
  - systemctl restart systemd-sysctl
write_files:
  - path: /etc/sysctl.d/10-disable-ipv6.conf
    permissions: 0644
    owner: root
    content: |
      net.ipv6.conf.eth0.disable_ipv6 = 1

2. Add the vendor data Cloud-Init file to the Proxmox VM template

note we specify vendor here instead of user as instructed in the Proxmox doc.

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

3. Specify user names and SSH keys

It is necessary to set user information here, as any users specified in Cloud-Init vendor data is ignored.

qm set 123 --ciuser northben
qm set 123 --sshkey ~/.ssh/id_rsa.pub;

Conclusion

With this configuration, it is possible to create a VM from the template and the hostname will be set to the name of the VM.

For example, this will create a VM named “ubuntu2” and Cloud-Init will set the hostname to “ubuntu2”.

qm clone 9000 123 --name ubuntu2