2. First contact
Simple bootstrapping with the Rocky Linux 10 QCOW2 image¶
In the previous chapter, we covered the fundamental concepts of cloud-init. Now, it is time to move from theory to practice. This chapter is your first hands-on mission: you will take the official Rocky Linux 10 Generic Cloud image, provide it with a simple set of instructions, and watch it configure itself on first boot.
1. Prepping the lab environment¶
Before we can boot our first instance, we need to prepare our local lab environment. For these exercises, we will simulate a cloud environment using standard Linux virtualization tools.
Prerequisites: host tools¶
Ensure you have the following tools installed on your host machine. On a Rocky Linux host, you can install them with dnf:
sudo dnf install -y libvirt qemu-kvm virt-install genisoimage
- Virtualization Hypervisor: A tool like KVM/QEMU or VirtualBox.
virt-install: A command-line utility for provisioning new virtual machines.genisoimage(ormkisofs): A tool to create an ISO9660 filesystem.
The QCOW2 image¶
If you have not already, download the official Rocky Linux 10 Generic Cloud image.
curl -L -o Rocky-10-GenericCloud.qcow2 \
https://dl.rockylinux.org/pub/rocky/10/images/x86_64/Rocky-10-GenericCloud-Base.latest.x86_64.qcow2
To preserve the original, create a working copy of the image for your VM.
cp Rocky-10-GenericCloud.qcow2 first-boot-vm.qcow2
Save disk space with backing files
A full copy of the image can be large. To save disk space, you can create a linked clone that uses the original image as a backing file. This creates a much smaller qcow2 file that only stores the differences from the original.
qemu-img create -f qcow2 -F qcow2 \
-b Rocky-10-GenericCloud.qcow2 first-boot-vm.qcow2
2. Method 1: The NoCloud datasource (ISO)¶
One of the most common ways to provide data to cloud-init in a local environment is the NoCloud datasource. This method requires packaging your configuration files into a virtual CD-ROM (an ISO file) that cloud-init will automatically detect and read on boot.
Creating the configuration files¶
-
Create a directory for your configuration files:
mkdir cloud-init-data -
Create the
user-datafile: This file is your primary instruction set. We will use acatheredoc to create it.cat <<EOF > cloud-init-data/user-data #cloud-config hostname: cloud-rockstar-01 runcmd: - [ sh, -c, "echo 'Hello from the cloud-init Final Stage!' > /root/boot_done.txt" ] EOF -
Create the
meta-datafile: This file provides context about the instance. Theinstance-idis particularly important, ascloud-inituses it to determine if it has run on this instance before. Changing the ID will causecloud-initto run again.cat <<EOF > cloud-init-data/meta-data { "instance-id": "i-first-boot-01", "local-hostname": "cloud-rockstar-01" } EOF -
Generate the ISO: Use
genisoimageto package the files intoconfig.iso. The volume label-V cidatais the magic key thatcloud-initlooks for.genisoimage -o config.iso -V cidata -r -J cloud-init-data
Booting and verification¶
-
Launch the VM with
virt-install, attaching both the VM image and theconfig.iso.virt-install --name rocky10-iso-boot \ --memory 2048 --vcpus 2 \ --disk path=first-boot-vm.qcow2,format=qcow2 \ --disk path=config.iso,device=cdrom \ --os-variant rockylinux10 \ --import --noautoconsole -
Find the IP and connect via SSH. The default user is
rocky.virsh domifaddr rocky10-iso-boot ssh rocky@<IP_ADDRESS>Secure logins with SSH keys
Connecting with a default user is convenient for a quick lab test, but it is not a secure practice. In the next chapter, we will explore how to use
cloud-initto automatically inject your SSH public key, allowing for secure, passwordless logins. -
Verify the changes: Check the hostname and the file created by
runcmd.hostname sudo cat /root/boot_done.txt
3. Method 2: Direct injection with virt-install¶
Creating an ISO is a reliable method, but for users of libvirt and virt-install, there is a much simpler way. The --cloud-init flag allows you to pass user-data directly, letting virt-install handle the creation of the datasource automatically.
Simplified user-data¶
Create a simple user-data.yml file. You can even add the SSH key preemptively.
cat <<EOF > user-data.yml
#cloud-config
users:
- name: rocky
ssh_authorized_keys:
- <YOUR_SSH_PUBLIC_KEY>
EOF
Booting and verification¶
-
Launch the VM using the
--cloud-initflag. Notice we can set the hostname here directly.virt-install --name rocky10-direct-boot \ --memory 2048 --vcpus 2 \ --disk path=first-boot-vm.qcow2,format=qcow2 \ --cloud-init user-data=user-data.yml,hostname=cloud-rockstar-02 \ --os-variant rockylinux10 \ --import --noautoconsole -
Find the IP and connect. If you added your SSH key, you should be able to connect without a password.
-
Verify the hostname. It should be
cloud-rockstar-02.
This direct method is often faster and more convenient for local development and testing with libvirt.
Author: Wale Soyinka