We’ve already covered creating VM templates in Harvester. Now let’s automate our VM creation even more by introducing cloud-init.
Cloud-init is an interesting project by Canonical. Almost every cloud provider in the world uses it to provision fresh VMs. If you ever wondered how a fresh ubuntu cloud vm already has custom packages, ssh keys, or users and passwords set up and ready to go after first boot, its because the cloud provider probably used cloud-init to provision the machine.
What does it do?
During boot,
cloud-init
identifies the cloud it is running on and initialises the system accordingly. Cloud instances will automatically be provisioned during first boot with networking, storage, SSH keys, packages and various other system aspects already configured.
Cloud-init
provides the necessary glue between launching a cloud instance and connecting to it so that it works as expected.~ cloudinit.readthedocs.io
Essentially, you tell it what users, packages, volumes, swap files, and ssh keys you want to come preinstalled with the server, and it applies your settings.
Now that we know what it is, let’s create our first cloud config file. Here is one that I use in my own Harvester install:
#cloud-config
users:
- name: <username>
sudo: ALL=(ALL) NOPASSWD:ALL
passwd: <a-password>
ssh_authorized_keys:
- <your-ssh-pub-key>
lock_passwd: false
shell: /bin/bash
packages:
- curl
- wget
- btop
write_files:
- path: /tmp/install_docker.sh
content: |
#!/bin/bash
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
permissions: '0755'
runcmd:
- sudo apt update && sudo apt upgrade -y
- sudo /tmp/install_docker.sh
- - systemctl
- enable
- '--now'
- qemu-guest-agent
This cloud config does a few things:
it creates a user
that has a password
and an ssh key
and sudo access
it installs
curl
wget
btop
docker
it makes sure the quemu-guest-agent is running (a harvester thing)
It’s actually a simple file but it takes away alot of manual work.
Before I use cloud-init, I would SSH into my new machine, create the user, change the passwd, add the authorized ssh pub key, update and upgrade, install my packages, and than reboot.
Now, I slap this file on my VM and voila! I am ready to go after the first boot.
Briefly looking at https://cloudinit.readthedocs.io/en/latest/reference/examples.html you can see that you can use cloud-init for almost anything.
Configure instance's SSH keys, run commands on first boot, setup disks, run apt or yum updates and upgrades, write out arbitrary files, setup Ansible, create users and password, and the list goes on.
Something that I initially messed up was the password part. You need to generate a hash using the following command:
mkpasswd --method=SHA-512 --rounds=4096
You can than type your password and you should be set to go.
As a reminder, you will have to use the cloud image of ubuntu in Harvester. You can find that here: http://cloud-images.ubuntu.com/releases/focal/release/ubuntu-20.04-server-cloudimg-amd64.img
Cheers,
Joe