While experimenting with dqlite, I needed to create multiple virtual machines from a custom template to manually test a few scenarios. cloud-init
combined with one of the cloud images from here would have worked, but I wanted to avoid waiting for the VM to boot and configure itself each time I spun up a new instance.
After some research, I discovered virt-sysprep
, which turned out to be the perfect tool for the task. From the official documentation:
Virt-sysprep can reset or unconfigure a virtual machine so that clones can be made from it. Steps in this process include removing SSH host keys, removing persistent network MAC configuration, and removing user accounts. Virt-sysprep can also customize a virtual machine, for instance by adding SSH keys, users or logos. Each step can be enabled or disabled as required.
Below, I'll document the steps I followed to create a custom template VM disk image.
Prerequisites
- A Linux host or VM
virt-sysprep
(installlibguestfs-tools
on Ubuntu/Debian)- [Optional] ovftool (can also be installed with
brew
on macOS)
Steps
Create a virtual machine, configure it as needed, and install the required packages (e.g.
open-vm-tools
).Shutdown the VM.
[Optional] Use
ovftool
to Convert the VM into an OVF (e.g.ovftool /path/to/template.vmx /output/path/to/template.ovf
)Use
virt-sysprep
to "unconfigure" the disk image:ops=$(virt-sysprep --list-operations | egrep -v 'fs-uuids|lvm-uuids' | awk '{ printf "%s,", $1}' | sed 's/,$//') sudo virt-sysprep -a /path/to/disk.vmdk --hostname localhost --remove-user-accounts ansible --enable $ops --firstboot-command 'dpkg-reconfigure openssh-server' --root-password password:changeme
Create a new VM from the disk image.