This is part 2 of my series "Proxmox Cloud-Init" where we want to explore Cloud-Init and Proxmox together to create VM templates that we can use to quickly provision new virtual machines.

In the last part we've learned what Cloud-Init is, where it comes from and how the technology can help us to build a base-image we can further use.

In this part, we want to create a Proxmox VM, install cloud-init and configure some stuff and the create a new VM with our base-configuration.

Base Image:

You could install cloud-init from scratch, but the big Operatingsystems provide ready-to-go cloud-init image in the qcow2 format. Here is a list of all the repositories where you can find them:

CentOS (search for GenericCloud images)

Even if Red Hat announced the discontinuation fo CentOS it still plays a big role in enterprise-application, so you might need it to test some special application.

Debian

Debian hosts own cloud-images here: Index of /cdimage/cloud. Here you want to choose the newest build and the “generic” versions, since we are not bound to a cloud-provider like AWS or Azure.

Ubuntu

Ubuntu also hosts it’s own images on their CDN, which you can find here: https://cloud-images.ubuntu.com/. Here you can freely choose which image you want to use, just pick the one that is appropriate to your architecture.

RHEL

RHEL (Red Hat Enterprise Linux) also provides cloud-images for their customers, so you need to be logged in to download them. You can find the links here:

Arch Linux

Arch Linux offers pre-build qcow2 images here: https://mirror.pkgbuild.com/images/

Fedora

Fedora also hosts it’s images here: The lightweight VM environment | The Fedora Project. You want to choose “Cloud Base image for Openstack”, because OpenStack also uses cloud-init for deploying virtual maschines.

Most Linux Distributions nowdays offer cloud-init-ready images which you can freely download, mostly on their download pages. There are also Windows Server images Windows Cloud Images - Cloudbase Solutions or creation-tools like this: GitHub - cloudbase/windows-imaging-tools: Tools to automate the creation of a Windows image for OpenStack, supporting KVM, Hyper-V, ESXi and more. but I won’t go into detail on this one.

Modify

Now, let’s download one of those images and modify it. I want my image to have the following things:

  • SSH-enabled Login via root with password-authentication on, because the image will not be used in a production environment. In a production environment you want to have root-login disabled and SSH-password-based authentication as well off, so people can only login with a key + a dedicated user.
  • a custom MOTD which will be displayed when I login.

I will use the Debian 10 cloud-image, since that is what I am most familiar with. The setup should not vary much, since we are editing cloud-init images, but there might be one or two differentes between distributions.

We will need libguestfs-tools on the linux-maschine where we will modify the templates, so we can install that via apt (https://libguestfs.org/).

$ wget https://cdimage.debian.org/cdimage/cloud/buster/20210329-591/debian-10-genericcloud-amd64-20210329-591.qcow2

Next, I’ll rename the file to “debian-image.qcow2”, because we will be typing this a few times during the setup and the long name is tidious.

Now we can open the image up and edit files. You will not be able to browse the directory structure like you are used to, instead you have to open each file specifically. I’ll go ahead and open the “/etc/cloud/cloud.cfg” file, where most of our editing will take place. Don’t worry, the command takes some time to unpack the image, just be patiente.

$ virt-edit debian-image.qcow2 /etc/cloud/cloud.cfg

/etc/cloud/cloud.cfg

As you can see, there is a parameter called “disable_root”, which is set to “false” by default. This is because, as mentioned in the beginning, root is disabled by default, because of the security risks that comes with allowing root-login. In my case, I can safely set that to true.

I will also edit the “/etc/ssh/sshd_config” to enable root-login over SSH, which is of course also disabled by default.

/etc/ssh/sshd_config

This is an easy one, we just have to comment in the PermitRootLogin by removing the # in the beginning and changing the value to yes, so the line is just PermitRootLogin yes. We also need to enable password-authentication by changing PasswordAuthentication from no to yes.

Next, to display my custom MOTD, I will edit the “/etc/motd” file, to just add some ASCII-art.

/etc/motd

Now we are basically done and just need to import the image to Proxmox. Since I was doing the modifications on the Proxmox server, I can run the commands just in the current terminal, otherwise you’d have to transfer the file to the server, for example over scp or sftp.

Proxmox VE import & template creation

Now that we have the file where we need it, we can start by creating a virtual maschine where we will apply the image. I will use the VMID 9002, since that one is unused at the moment.

$ qm create 9002 --name "debian-10-cloudinit-template" --memory 2048 --net0 virtio,bridge=vmbr0

the bridge argument should be exchanged to whatever your actual bridge device is. vmbr0 is the default, but double-check just to make sure.

Next, we can import our qcow2 image into the proxmox-storage so we can assign it to the VM.

$ qm importdisk 9002 debian-image.qcow2 local-lvm

“debian-image.qcow2” is my filename and local-lvm is the storage in which I want to import it. You can of course use any other storage, as long as it can store “disks”. You should now see a process-log and something like Successfully imported disk as ‘unused0:local-lvm:vm-9002-disk-0.

We can now assign the imported disk to our created VM:

$ qm set 9002 --scsihw virtio-scsi-pci --scsi0 local-lvm:vm-9002-disk-0

Depending on your storage, there might be a slight variation in the –scsi0 parameter. You often can use the part after “unused0:” from the previous command.

Next, we need to assign the cloud-init drive. Proxmox has direct integration for cloud-init, so that command is straight forward:

$ qm set 9002 --ide2 local-lvm:cloudinit

You should see something like “Logical volume … created.”.

Now we just need to set the boot-disk and convert the VM into a template, so we can use it from the Proxmox GUI.

$ qm set 9002 --boot c --bootdisk scsi0
$ qm template 9002

And we are done! We can now go into the gui and create a server based on our image.

We want to go into Proxmox and right-click our new template in the sidebar and choose “Clone”. A dialog like this will pop up.

clone VM Template Screen

Here you will enter the Node on which you want to create the server (everything except the node where the storage is on will require the template to be located in a share-storage like NFS, iSCSI, Ceph, etc..), the Hostname (Name) and the VMID. I will not change the Target Storage, but you can do that of course. Also I’m choosing “Full clone”, because then the whole template gets cloned and I can remove the template whenever I want to. If you choose linked clone you cannot delete the template without also deleting the servers cloned from that template (but it saves drive-space).

VM Cloud-Init Overview

When we navigate to the new VM and go to “Cloud-Init”, we can change the default parameters of the cloud-init drive which will be applied once we start the VM. I’m changing the User to “root”, the Passwort to something secret and also set the DNS and IP-Parameters, so the VM has internet access.

Now we can just start the Server and go to the console and watch the cloud-init magic happen. After the setup is done, you should be able to connect over SSH, so in my case “ssh root@192.168.0.72”. I have to enter my password – as expected and we’re good to go!

I hope this guide leads you in the right direction to make your deployment of servers quicker and more efficient! If you are in search for a hosting panel to offer Proxmox-based server hosting to customers, check out my product at https://bennetgallein.de/shop/proxmox_control_panel

If you have any questions, don’t hesitate to reach out over E-Mail (me[at]bennetgallein.de) or leave a comment.