Today I'm going to go over using
Hyper-V and customizing the base image.
I build a lot of VM's and tear them down throughout a general work week, I am tired of spending a bunch of time baby-sitting an installer to enter the same information all the time. I wanted to make this a single script that I can run to create an entire environment.
To accomplish this I needed an image that has Cloud-init setup in it that works with Hyper-V. I chose the Ubuntu cloud image for Azure. Azure runs on Hyper-V so it fit well right out of the box, mostly. I do need to pull out some of the Azure specific customizations. I'll cover that as well.
To customize the image and to remove the Azure components you'll need to be an Administrator on your computer. You will need Windows Subsystem for Linux installed from the Microsoft Store. The reason you need WSL from the store is that we mount the Ubuntu cloud image inside of it so we can customize it. That feature is only in the Store instance of WSL.
To create the virtual machine you will need the Windows Assessment and Deployment Kit with the
Deployment Tools feature. This is used to create the
iso image that contains the Cloud-init configuration.
Assumptions with this post
- You'll be using the
- You have admin rights on your computer
- You have Windows Subsystem for Linux already setup and running with default settings and a distribution with
- You're using a directory named
c:\Cloud-initto store everything.
- You have the
Windows Assessment and Deployment Kitwith a minimum, the
Deployment Toolsfeature installed at the default location of
C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit.
- You have this repository checked out
Create the base image
First step in creating the base image, download the Azure Cloud-init image from Ubuntu's cloud image site linked here
I'm going to be picking on the latest one,
mantic. The image name for the
mantic version of Ubuntu is
Now that you have that downloaded, extract the
vhd file from that archive. You can use WSL to do this, or an application like 7-zip.
Customize the base image
Now that you have the
vhd extracted, we need to customize it.
Here is a link to the
create-vm.ps1 script that will convert the
vhd to a dynamically sizing
vhdx, mount the
vhdx in WSL, remove the Azure specific components, and finally
chroot into the mounted
vhdx so you can customize it.
You can execute this from where you checked out the repo in an administrator PowerShell window
./set-cloudinit-ubuntu.ps1 -Source C:\cloud-init\livecd.ubuntu-cpc.azure.vhd -Destination C:\cloud-init\ubuntu-mantric.vhdx
You should be greeted with output that looks very similar to this.
Converting image to a dynamic disk Mounting in WSL The disk was successfully mounted as '/mnt/wsl/61447da8-c86a-4526-b900-5048ec59d556'. Note: The location will be different if you have modified the automount.root setting in /etc/wsl.conf. To unmount and detach the disk, run 'wsl.exe --unmount \\?\C:\cloud-init\ubuntu-mantric.vhdx'. Modifying the cloud-init data source Removing the azure specific configuration Entering your image environment Press ctrl+d or type exit when you are done customizing your image root@edslaptop:/#
You are now in the
chroot environment of your golden image. Customize as you see fit. Once you are happy with your image, press
ctrl+d or type
exit and press enter to exit the
After you exit the
chroot environment, you should now be greeted with the following
Unmounting from WSL The operation completed successfully.
Your golden image is now setup and ready to be cloned.
Building your virtual machine
We're going to now setup some basic example Cloud-init files. You can find the example Cloud-init configuration in the
example directory here
Those example files will show how to build a VM with the hostname of
example, a single user with username/password of
example and install
ca-certificates. It will also enable password based
ssh login, which is disabled by default and upgrade all of the currently installed packages.
Use the Cloud-init configurations and build the VM
Now that you have your Cloud-init configuration build, it's time to build the actual virtual machine. We'll use the
create-vm.ps1 script for that. It is very simple to use, here is the minimal usage of the script. It creates a virtual machine named
Test, with a root disk of 30 gigs, using the
example directory, the base image we just created and 4 gigs of memory.
./create-vm.ps1 -VirtualMachineName Test -VirtualDiskSize 30 -CloudInitDirectory ./example -RootDiskPath C:\cloud-init\ubuntu-mantric.vhdx -MemorySize 4
You should now be greeted with an output looking like this.
Copying root disk from C:\cloud-init\ubuntu-mantric.vhdx to C:\ProgramData\Microsoft\Windows\Virtual Hard Disks\Test.vhdx Resizing virtual disk to 30 gigabytes Creating cloud init iso at C:\ProgramData\Microsoft\Windows\Virtual Hard Disks\Test-cidata.iso OSCDIMG 2.56 CD-ROM and DVD-ROM Premastering Utility Copyright (C) Microsoft, 1993-2012. All rights reserved. Licensed only for producing Microsoft authorized content. Scanning source tree Scanning source tree complete (2 files in 1 directories) Computing directory information complete Image file is 57344 bytes Writing 2 files in 1 directories to C:\ProgramData\Microsoft\Windows\Virtual Hard Disks\Test-cidata.iso 100% complete Final image file is 57344 bytes Done. Creating virtual machine Disabling dynamic memory Setting secure boot settings Adding cidata iso to the virtual machine Starting virtual machine Virtual machine creation complete
Check your virtual machine
Hyper-V Manager application and check your
Test virtual machine, if it's not the basic
login screen then wait a couple of minutes.
login screen is up, try logging in with the
example user, the password is also
This is the under pinning of how to use Hyper-V, Cloud-init, PowerShell and WSL to customize a base image and actually use it in Hyper-V. Next post will be using PowerShell to easily create a set of Cloud-init files to quickly build a basic Ubuntu virtual machine.
This was a fun project to do. I'm glad I did it, even thought it was a little difficult to figure it all out.
Hopefully you find it useful as well.