Prepare an Ubuntu virtual machine for Azure
Applies to: ✔️ Linux VMs ✔️ Flexible scale sets
Ubuntu now publishes official Azure virtual hard disks (VHDs) for download at the Ubuntu Cloud Images webpage. If you need to build your own specialized Ubuntu image for Azure instead of using the manual procedure that follows, start with these known working VHDs and customize them, as needed. You can always find the latest image releases at the following locations:
- Ubuntu 20.04/Focal: focal-server-cloudimg-amd64-azure.vhd.tar.gz
- Ubuntu 22.04/Jammy: jammy-server-cloudimg-amd64-azure.vhd.tar.gz
- Ubuntu 24.04/Jammy: jammy-server-cloudimg-amd64-azure.vhd.tar.gz
Prerequisites
This article assumes that you've already installed an Ubuntu Linux operating system (OS) to a VHD. Multiple tools exist to create .vhd files. An example is a virtualization solution such as Hyper-V. For instructions, see Install the Hyper-V role and configure a virtual machine (VM).
Ubuntu installation notes
- For more tips on preparing Linux for Azure, see General Linux installation notes.
- The VHDX format isn't supported in Azure, only fixed VHD. You can convert the disk to VHD format by using Hyper-V Manager or the
Convert-VHD
cmdlet. - When you install the Linux system, we recommend that you use standard partitions rather than Logical Volume Manager (LVM), which is often the default for many installations. These standard partitions avoid LVM name conflicts with cloned VMs, particularly if an OS disk ever needs to be attached to another VM for troubleshooting. LVM or RAID can also be used on data disks.
- Don't configure a swap partition or swap file on the OS disk. You can configure the
cloud-init
provisioning agent to create a swap file or a swap partition on the temporary resource disk. For more information about this process, see the following steps. - All VHDs on Azure must have a virtual size aligned to 1 MB. When you convert from a raw disk to VHD, you must ensure that the raw disk size is a multiple of 1 MB before conversion. For more information, see Linux installation notes.
Manual steps
Note
Before you attempt to create your own custom Ubuntu image for Azure, consider using the prebuilt and tested images from the Ubuntu Cloud Images webpage instead.
In the center pane of Hyper-V Manager, select the VM.
Select Connect to open the window for the VM.
Replace the current repositories in the image to use Ubuntu's Azure repository.
Before you edit
/etc/apt/sources.list
, we recommend that you make a backup:sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
sudo sed -i 's#http://archive\.ubuntu\.com/ubuntu#http://azure\.archive\.ubuntu\.com/ubuntu#g' /etc/apt/sources.list sudo sed -i 's#http://[a-z][a-z]\.archive\.ubuntu\.com/ubuntu#http://azure\.archive\.ubuntu\.com/ubuntu#g' /etc/apt/sources.list sudo sed -i 's#http://security\.ubuntu\.com/ubuntu#http://azure\.archive\.ubuntu\.com/ubuntu#g' /etc/apt/sources.list sudo sed -i 's#http://[a-z][a-z]\.security\.ubuntu\.com/ubuntu#http://azure\.archive\.ubuntu\.com/ubuntu#g' /etc/apt/sources.list sudo apt-get update
The Ubuntu Azure images are now using the Azure-tailored kernel. Update the OS to the latest Azure-tailored kernel and install Azure Linux tools (including Hyper-V dependencies):
sudo apt update sudo apt install linux-azure linux-image-azure linux-headers-azure linux-tools-common linux-cloud-tools-common linux-tools-azure linux-cloud-tools-azure sudo apt full-upgrade sudo reboot
Modify the kernel boot line for GRUB to include extra kernel parameters for Azure. To do this step, open
/etc/default/grub
in a text editor, find the variable calledGRUB_CMDLINE_LINUX_DEFAULT
(or add it if needed), and edit it to include the following parameters:GRUB_CMDLINE_LINUX_DEFAULT="console=tty1 console=ttyS0,115200n8 earlyprintk=ttyS0,115200 rootdelay=300 quiet splash"
Save and close this file, and then run
sudo update-grub
. This step ensures that all console messages are sent to the first serial port, which can assist Azure technical support with debugging issues.Ensure that the SSH server is installed and configured to start at boot time. This setting is usually the default.
Install
cloud-init
(the provisioning agent) and the Azure Linux agent (the guest extensions handler).Cloud-init
usesnetplan
to configure the system network configuration (during provisioning and each subsequent boot) andgdisk
to partition resource disks.sudo apt update sudo apt install cloud-init gdisk netplan.io walinuxagent && systemctl stop walinuxagent
Note
The
walinuxagent
package might remove theNetworkManager
andNetworkManager-gnome
packages, if they're installed.Remove
cloud-init
default configurations and leftovernetplan
artifacts that might conflict withcloud-init
provisioning on Azure:sudo rm -f /etc/cloud/cloud.cfg.d/50-curtin-networking.cfg /etc/cloud/cloud.cfg.d/curtin-preserve-sources.cfg /etc/cloud/cloud.cfg.d/99-installer.cfg /etc/cloud/cloud.cfg.d/subiquity-disable-cloudinit-networking.cfg sudo rm -f /etc/cloud/ds-identify.cfg sudo rm -f /etc/netplan/*.yaml
Configure
cloud-init
to provision the system by using the Azure data source:sudo tee /etc/cloud/cloud.cfg.d/90_dpkg.cfg <<EOF datasource_list: [ Azure ] EOF sudo tee /etc/cloud/cloud.cfg.d/90-azure.cfg <<EOF system_info: package_mirrors: - arches: [i386, amd64] failsafe: primary: http://archive.ubuntu.com/ubuntu security: http://security.ubuntu.com/ubuntu search: primary: - http://azure.archive.ubuntu.com/ubuntu/ security: [] - arches: [armhf, armel, default] failsafe: primary: http://ports.ubuntu.com/ubuntu-ports security: http://ports.ubuntu.com/ubuntu-ports EOF sudo tee /etc/cloud/cloud.cfg.d/10-azure-kvp.cfg <<EOF reporting: logging: type: log telemetry: type: hyperv EOF
Configure the Azure Linux agent to rely on
cloud-init
to perform provisioning. For more information on these options, look at the WALinuxAgent project.sudo sed -i 's/Provisioning.Enabled=y/Provisioning.Enabled=n/g' /etc/waagent.conf sudo sed -i 's/Provisioning.UseCloudInit=n/Provisioning.UseCloudInit=y/g' /etc/waagent.conf sudo sed -i 's/ResourceDisk.Format=y/ResourceDisk.Format=n/g' /etc/waagent.conf sudo sed -i 's/ResourceDisk.EnableSwap=y/ResourceDisk.EnableSwap=n/g' /etc/waagent.conf
sudo tee -a /etc/waagent.conf <<EOF # For Azure Linux agent version >= 2.2.45, this is the option to configure, # enable, or disable the provisioning behavior of the Linux agent. # Accepted values are auto (default), waagent, cloud-init, or disabled. # A value of auto means that the agent will rely on cloud-init to handle # provisioning if it is installed and enabled, which in this case it will. Provisioning.Agent=auto EOF
Clean
cloud-init
and Azure Linux agent runtime artifacts and logs:sudo cloud-init clean --logs --seed sudo rm -rf /var/lib/cloud/ sudo systemctl stop walinuxagent.service sudo rm -rf /var/lib/waagent/ sudo rm -f /var/log/waagent.log
Deprovision the VM and prepare it for provisioning on Azure.
Note
The
sudo waagent -force -deprovision+user
command generalizes the image by attempting to clean the system and make it suitable for reprovisioning. The+user
option deletes the last provisioned user account and associated data.sudo waagent -force -deprovision+user sudo rm -f ~/.bash_history
Warning
Deprovisioning by using the preceding command doesn't guarantee that the image is cleared of all sensitive information and is suitable for redistribution.
Select Action > Shut Down in Hyper-V Manager.
Azure only accepts fixed-size VHDs. If the VM's OS disk isn't a fixed-size VHD, use the
Convert-VHD
PowerShell cmdlet and specify the-VHDType Fixed
option. For more information, look at the docs forConvert-VHD
at Convert-VHD.To bring a Generation 2 VM on Azure, follow these steps:
Change the directory to the
boot EFI
directory:cd /boot/efi/EFI
Copy the
ubuntu
directory to a new directory namedboot
:sudo cp -r ubuntu/ boot
Change the directory to the newly created boot directory:
cd boot
Rename the
shimx64.efi
file:sudo mv shimx64.efi bootx64.efi
Rename the
grub.cfg
file tobootx64.cfg
:sudo mv grub.cfg bootx64.cfg
Related content
You're now ready to use your Ubuntu Linux VHD to create new VMs in Azure. If this is the first time that you're uploading the .vhd file to Azure, see Create a Linux VM from a custom disk.