In this post, we will see an automated approach to creating a guest VM with cloud-init using libvert/virt-install. In the Previous post described here, we have seen the manual procedure. Now, we will use a shell script wrapper to do the same for our convenience. For your convenience, the script is loaded with comments, so if anyone is interested to go through it would not face any challenges.
Step-1: clone the Repo and navigate to the directory
git clone https://github.com/technekey/libvert-cloud-init-virt-install.git
Cloning into 'libvert-cloud-init-virt-install'...
remote: Enumerating objects: 10, done.
remote: Counting objects: 100% (10/10), done.
remote: Compressing objects: 100% (8/8), done.
remote: Total 10 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (10/10), 7.44 KiB | 3.72 MiB/s, done.
cd libvert-cloud-init-virt-install/
Step-2: Modify the cloud-init file supplied in the repo or create yours
vi my-config.yml
cloud-config
system_info:
default_user:
name: technekey # put your username
home: /home/technekey #make changes as per username
sudo: ALL=(ALL) NOPASSWD:ALL #keep this line if you want to give sudo priv with no password
password: technekey #the password for the user, if you use key this is perhaps not needed
chpasswd: { expire: False } #to prevent password expiry
hostname: host-configured-by-cloud-init #give a good name to your host
ssh_authorized_keys:
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI-FAKE-FAKE-DELETE-THIS-ADD-YOURS #add right ssh pub key
ssh_pwauth: True #make if false if you want to disable password based auth for ssh
# list of packages to install
package_upgrade: true #update the package
packages:
- nfs-common #for example, I need nfs-common installed in my guest vm
runcmd: #run the following commands during bootstrap, change as per your requirement
- sudo systemctl enable iscsid
- sudo systemctl start iscsid
- sudo systemctl start apache2
- ip addr show $(ip route get 1.1.1.1 |grep -oP 'dev\s+\K[^ ]+') |grep -oP '^\s+inet\s+\K[^/]+' |tee /tmp/my-ip
Step-3: Trigger the install command
The following command would create a VM and wait till the cloud-init execution is completed. The syntax is as follows, if you want to know the OS Variant then you can run virt-install –osinfo list command and grep to the desired name.
bash virth-install-with-cloud-init.sh -n <VM-NAME> \
-f </PATH/TO/CLOUD-INIT-FILE> \
-i <CLOUD-IMAGE-DOWNLOAD-URL> \
-c <NUMBER-OF-CPU> \
-m <MEMORY IN MB IN INTEGER> \
-d <DISK IN GIG WITH A G SUFFIX> \
-v <OS-VARIANT>
bash virth-install-with-cloud-init.sh -n VM-1 \
-f my-config.yml \
-i https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img \
-c 2 \
-m 2048 \
-d 60G \
-v ubuntu22.04
=====================================================================================
Installation Info
=====================================================================================
VM NAME: VM-1
CLOUD-INIT FILE LOCATION: /home/technekey/virt_install_default/my-config.yml
CPU: 2
Memory 2048
Disk: 60G
Image Source: https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img
VM Disk Location: /home/technekey/LIBVERT_VM_DISKS/LIBVERT_IMAGE_ubuntu22.04_NAME_VM-1_U1Ks8k
OS VARIANT: ubuntu22.04
=====================================================================================
Wed Jun 29 04:22:04 PM CDT 2022: [Info]: Downloading the image from https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img, this typically takes 1-10 mins depending on speed of your connection
Wed Jun 29 04:22:50 PM CDT 2022: [Info]: Download finised for https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img, rc=0
Wed Jun 29 04:22:50 PM CDT 2022: [Info]: The name of the downloaded image file is jammy-server-cloudimg-amd64.img
Wed Jun 29 04:22:50 PM CDT 2022: [Info]: The image /home/technekey/vm_images//jammy-server-cloudimg-amd64.img is having qcow2 format, converting to qcow2
Wed Jun 29 04:22:52 PM CDT 2022: [Info]: Resizing the disk to 60G
Image resized.
Wed Jun 29 04:22:52 PM CDT 2022: [Info]: Creating a seeding iso to include the cloud-init data
Starting install...
Creating domain... | 0 B 00:00:00
Domain creation completed.
Wed Jun 29 04:22:54 PM CDT 2022: [Info]: Waiting for Cloud init to complete.., ATTEMPT=1, MAX ATTEMPTS=10, Retrying in 60 seconds.
Wed Jun 29 04:23:26 PM CDT 2022: [Info]: Waiting for Cloud init to complete.., ATTEMPT=2, MAX ATTEMPTS=10, Retrying in 60 seconds.
Wed Jun 29 04:23:59 PM CDT 2022: [Info]: Waiting for Cloud init to complete.., ATTEMPT=3, MAX ATTEMPTS=10, Retrying in 60 seconds.
Wed Jun 29 04:24:01 PM CDT 2022: [Info]: Cloud init instructions are successfully executed on the guest VM(kube-master-1)
Id: 13
Name: VM-1
UUID: 268f23543c6-b12ff-4e08-9504-d65a76bff0d26
OS Type: hvm
State: running
CPU(s): 2
CPU time: 50.5s
Max memory: 2097152 KiB
Used memory: 2097152 KiB
Persistent: yes
Autostart: disable
Managed save: no
Security model: apparmor
Security DOI: 0
Security label: libvirt-268fb942332-b1ff-4e08-9504-d6434bff0d26 (enforcing)
TWEAKS MIGHT BE NEEDED:
You might want to set different values to IMAGE_CACHE and LIBVERT_VM_DISK variables as per your storage. As a default, I am keeping both in the home directory of the user. The script is loaded with comments, and should not be complex to modify or improve. However, if you find difficulty please drop a comment here.
#!/bin/bash
set -e
###################################################################################################
#NOTE: DO NOT USE THIS SCRIPT FOR WINDOWS, THE MAIN PURPOSE OF THIS SCRIPT IS TO GLUE GLOUD-INIT
###################################################################################################
#this location will store the downloaded images file for caching
# this will prevent repeated downloads
IMAGE_CHACHE=~/vm_images/
# This is the directory keeping out VM's disk
LIBVERT_VM_DISK=~/LIBVERT_VM_DISKS
#This is timeout value for cloud-init execution completion.
CLOUD_INIT_WAIT_COUNTER_MAX=10
If things do not work out or if you need a change, feel free to edit the code or bug request at https://github.com/technekey/libvert-cloud-init-virt-install for everyone. Thanks!