Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Applies to: ✔️ Linux VMs ✔️ Flexible scale sets Applies to: ✔️ Uniform scale sets
In some cases, you might want to use customized SUSE Linux Enterprise Server (SLES) or openSUSE Leap Linux virtual machines (VMs) in your Azure environment and be able to build these types of VMs through automation. This article demonstrates how to create and upload a custom Azure virtual hard disk (VHD) that contains a SUSE Linux operating system.
Prerequisites
This article assumes that you already installed a SLES or openSUSE Leap Linux operating system on a virtual hard disk. Multiple tools exist to create .vhd files. For example, you can use a virtualization solution such as Hyper-V. For instructions, see Install Hyper-V and create a virtual machine.
SLES/openSUSE Leap installation notes
Important
The remote NVMe preparation steps in this article are optional. Complete them only if you're creating an image that you intend to deploy with a remote NVMe disk controller. If the target VM uses SCSI, skip every step labeled for remote NVMe and retain the standard settings.
- For more tips on preparing Linux images for Azure, see General Linux installation notes.
- Azure doesn't support Windows Hard Disk Image (.vhdx) files. Only VHD (.vhd) files are supported outside virtual machines. You can convert the disk to VHD format by using Hyper-V Manager or the
Convert-VHDcmdlet. - Azure supports Gen1 (BIOS boot) and Gen2 (UEFI boot) virtual machines.
- The virtual file allocation table (VFAT) kernel module must be enabled in the kernel.
- Don't configure a swap partition on the OS disk. You can configure the Linux agent to create a swap file on the temporary resource disk. Steps later in this article give more information about configuring swap space.
- All VHDs on Azure must have a virtual size aligned to 1 MB. When you're converting from a raw disk to VHD, ensure that the raw disk size is a multiple of 1 MB before conversion. For more information, see General Linux installation notes.
Important
Swap guidance that uses the temporary resource disk applies only to VM sizes that include local temporary storage. The remote disk controller type, SCSI or NVMe, doesn't determine whether a resource disk is available.
Note
Cloud-init version 21.2 or later removes the user-defined function (UDF) requirement. But without the udf module enabled, the CD-ROM won't mount during provisioning, which prevents the custom data from being applied. A workaround is to apply user data. However, unlike custom data, user data isn't encrypted. For more information, see User data formats in the cloud-init documentation.
Use SUSE Studio
SUSE Studio can easily create and manage your SLES and openSUSE Leap images for Azure and Hyper-V. SUSE Studio is the recommended approach for customizing your own SLES and openSUSE Leap images.
As an alternative to building your own VHD, SUSE also publishes BYOS (bring your own subscription) images for SLES at VM Depot.
Prepare SLES for Azure
Configure the Azure and Hyper-V modules if required.
If your software hypervisor is not Hyper-V, other modules need to be added into the initial RAM disk (initramfs) to successfully boot in Azure.
Create the /etc/dracut.conf.d/azure.conf file and add the following line:
add_drivers+=" hv_vmbus hv_netvsc hv_storvsc "Rebuild initramfs:
sudo dracut --verbose --forceSet up the serial console.
To successfully work with the serial console, you must set up several variables in the /etc/defaults/grub file and re-create GRUB on the server:
# Add console=ttyS0 and earlyprintk=ttS0 to the variable. # Remove "splash=silent" and "quiet" options. GRUB_CMDLINE_LINUX_DEFAULT="audit=1 no-scroll fbcon=scrollback:0 mitigations=auto security=apparmor crashkernel=228M,high crashkernel=72M,low console=ttyS0 earlyprintk=ttyS0" # Add "console serial" to GRUB_TERMINAL. GRUB_TERMINAL="console serial" # Set the GRUB_SERIAL_COMMAND variable. GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1"sudo /usr/sbin/grub2-mkconfig -o /boot/grub2/grub.cfgOnly if you're creating an image for a remote NVMe disk controller, add
nvme_core.io_timeout=240toGRUB_CMDLINE_LINUX_DEFAULTin step 2, addnvme nvme_coreto theadd_driversvalue in /etc/dracut.conf.d/azure.conf, and then rebuild GRUB and initramfs. Otherwise, omit these settings.sudo /usr/sbin/grub2-mkconfig -o /boot/grub2/grub.cfg sudo dracut --verbose --forceFor a remote NVMe image only, verify the drivers:
Confirm that both NVMe modules exist in the kernel's module tree so they can be packaged into initramfs. This check reads the on-disk module files, so it succeeds even on a SCSI preparation VM and doesn't imply that NVMe is loaded or in use:
modinfo nvme modinfo nvme_coreEach command must return module details. If either module isn't found, install or enable it by following the SUSE documentation before you continue.
Confirm that the rebuilt initramfs package includes both NVMe drivers. This check confirms the image is ready:
sudo lsinitrd /boot/initrd-$(uname -r) | grep -E 'nvme(_core)?\.ko'The output must list both the
nvmeandnvme_coredrivers. After the image boots on an NVMe VM, verify the runtime timeout by runningcat /sys/module/nvme_core/parameters/io_timeout; the expected value is240.Register your SUSE Linux Enterprise system to allow it to download updates and install packages.
Update the system with the latest patches:
sudo zypper updateInstall the Azure Linux VM Agent (
waagent) and cloud-init:sudo SUSEConnect -p sle-module-public-cloud/15.2/x86_64 (SLES 15 SP2) sudo zypper refresh sudo zypper install python-azure-agent sudo zypper install cloud-initEnable
waagentand cloud-init to start on boot:sudo systemctl enable waagent sudo systemctl enable cloud-init-local.service sudo systemctl enable cloud-init.service sudo systemctl enable cloud-config.service sudo systemctl enable cloud-final.service sudo systemctl daemon-reload sudo cloud-init cleanUpdate the cloud-init configuration:
cat <<EOF | sudo tee /etc/cloud/cloud.cfg.d/91-azure_datasource.cfg datasource_list: [ Azure ] datasource: Azure: apply_network_config: False EOFsudo cat <<EOF | sudo tee /etc/cloud/cloud.cfg.d/05_logging.cfg # This tells cloud-init to redirect its stdout and stderr to # 'tee -a /var/log/cloud-init-output.log' so the user can see output # there without needing to look on the console. output: {all: '| tee -a /var/log/cloud-init-output.log'} EOF # Make sure mounts and disk_setup are in the init stage: echo "Adding mounts and disk_setup to init stage" sudo sed -i '/ - mounts/d' /etc/cloud/cloud.cfg sudo sed -i '/ - disk_setup/d' /etc/cloud/cloud.cfg sudo sed -i '/cloud_init_modules/a\\ - mounts' /etc/cloud/cloud.cfg sudo sed -i '/cloud_init_modules/a\\ - disk_setup' /etc/cloud/cloud.cfgIf you want to mount, format, and create a swap partition, one option is to pass in a cloud-init configuration every time you create a VM.
Another option is to use a cloud-init directive in the image to configure swap space every time the VM is created:
cat <<EOF | sudo tee -a /etc/systemd/system.conf 'DefaultEnvironment="CLOUD_CFG=/etc/cloud/cloud.cfg.d/00-azure-swap.cfg"' EOF cat <<EOF | sudo tee /etc/cloud/cloud.cfg.d/00-azure-swap.cfg #cloud-config # Generated by Azure cloud image build disk_setup: ephemeral0: table_type: mbr layout: [66, [33, 82]] overwrite: True fs_setup: - device: ephemeral0.1 filesystem: ext4 - device: ephemeral0.2 filesystem: swap mounts: - ["ephemeral0.1", "/mnt"] - ["ephemeral0.2", "none", "swap", "sw,nofail,x-systemd.requires=cloud-init.service,x-systemd.device-timeout=2", "0", "0"] EOFPreviously, the Azure Linux Agent was used to automatically configure swap space by using the local resource disk that's attached to the virtual machine after the virtual machine is provisioned on Azure. Because cloud-init now handles this step, you must not use the Azure Linux Agent to format the resource disk or create the swap file. Use these commands to modify /etc/waagent.conf appropriately:
sudo sed -i 's/Provisioning.UseCloudInit=n/Provisioning.UseCloudInit=auto/g' /etc/waagent.conf sudo sed -i 's/Provisioning.Enabled=y/Provisioning.Enabled=n/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.confNote
If you're using a cloud-init version earlier than 21.2, make sure the
udfmodule is enabled. Removing or disabling it will cause a provisioning or boot failure. Cloud-init version 21.2 or later removes the UDF requirement.For both SCSI and NVMe images, ensure that the /etc/fstab file uses a UUID (
by-uuid) or another persistent identifier. Don't use/dev/sd*or/dev/nvme*device names, because device names can change across reboots or when the disk controller changes.List the block devices and their persistent identifiers so that you can compare them with the entries in
/etc/fstab:sudo blkidCheck
/etc/fstabfor syntax errors, invalid mount options, and references that can't be resolved:sudo findmnt --verify --verbose
Remove udev rules and network adapter configuration files to avoid generating static rules for the Ethernet interfaces. These rules can cause problems when you're cloning a virtual machine in Microsoft Azure or Hyper-V.
sudo rm -f /etc/udev/rules.d/70-persistent-net.rules sudo rm -f /etc/udev/rules.d/85-persistent-net-cloud-init.rules sudo rm -f /etc/sysconfig/network/ifcfg-eth*Edit the /etc/sysconfig/network/dhcp file and change the
DHCLIENT_SET_HOSTNAMEparameter to the following value:DHCLIENT_SET_HOSTNAME="no"In the /etc/sudoers file, comment out or remove the following lines if they exist:
Defaults targetpw # Ask for the password of the target user i.e. root ALL ALL=(ALL) ALL # WARNING! Only use this setting together with 'Defaults targetpw'!Ensure that the Secure Shell (SSH) server is installed and configured to start at boot time:
sudo systemctl enable sshdClean the cloud-init stage:
sudo cloud-init clean --seed --logsRun the following commands to deprovision the virtual machine and prepare it for provisioning on Azure.
If you're migrating a specific virtual machine and don't want to create a generalized image, skip the deprovisioning step.
sudo rm -f /var/log/waagent.log sudo waagent -force -deprovision+user sudo export HISTSIZE=0 sudo rm -f ~/.bash_history
Prepare openSUSE 15.4+
On the center pane of Hyper-V Manager, select the virtual machine.
Select Connect to open the window for the virtual machine.
In a terminal, run the command
zypper lr. If this command returns output similar to the following example, the repositories are configured as expected and no adjustments are necessary. (Version numbers might vary.)# Alias Name Enabled GPG Check Refresh 1 Cloud:Tools_15.4 Cloud:Tools-> Yes (r ) Yes Yes 2 openSUSE_stable_OSS openSUSE_st-> Yes (r ) Yes Yes 3 openSUSE_stable_Updates openSUSE_st-> Yes (r ) Yes Yes If the the message "No repositories defined" appears from the
zypper lrthe repositories must be added manually.Below are examples of commands for adding these repositories (versions and links may vary):
sudo zypper ar -f https://download.opensuse.org/update/openSUSE-stable openSUSE_stable_Updates sudo zypper ar -f https://download.opensuse.org/repositories/Cloud:/Tools/15.4 Cloud:Tools_15.4 sudo zypper ar -f https://download.opensuse.org/distribution/openSUSE-stable/repo/oss openSUSE_stable_OSSYou can then verify that the repositories have been added by running the command
zypper lragain. If one of the relevant update repositories isn't enabled, enable it by using the following command:sudo zypper mr -e [NUMBER OF REPOSITORY]Update the kernel to the latest available version:
sudo zypper up kernel-defaultOr update the operating system with all the latest patches:
sudo zypper updateInstall the Azure Linux Agent:
sudo zypper install WALinuxAgentModify the kernel boot line in your GRUB configuration to include other kernel parameters for Azure. To do this, open /boot/grub/menu.lst in a text editor and ensure that the default kernel includes the following parameters:
console=ttyS0 earlyprintk=ttyS0This option ensures that all console messages are sent to the first serial port, which can assist Azure support with debugging issues. In addition, remove the following parameters from the kernel boot line if they exist:
libata.atapi_enabled=0 reserve=0x1f0,0x8We recommend that you edit the /etc/sysconfig/network/dhcp file and change the
DHCLIENT_SET_HOSTNAMEparameter to the following setting:DHCLIENT_SET_HOSTNAME="no"In the /etc/sudoers file, comment out or remove the following lines if they exist. This is an important step.
Defaults targetpw # ask for the password of the target user i.e. root ALL ALL=(ALL) ALL # WARNING! Only use this together with 'Defaults targetpw'!Ensure that the SSH server is installed and configured to start at boot time.
Don't create swap space on the OS disk.
The Azure Linux Agent can automatically configure swap space by using the local resource disk that's attached to the VM after provisioning on Azure. The local resource disk is a temporary disk and will be emptied when the VM is deprovisioned.
After you install the Azure Linux Agent, modify the parameters in /etc/waagent.conf as follows:
ResourceDisk.Format=n ResourceDisk.Filesystem=ext4 ResourceDisk.MountPoint=/mnt/resource ResourceDisk.EnableSwap=n ResourceDisk.SwapSizeMB=2048 ## NOTE: set the size to whatever you need it to be.Ensure that the Azure Linux Agent runs at startup:
sudo systemctl enable waagent.serviceRun the following commands to deprovision the virtual machine and prepare it for provisioning on Azure.
If you're migrating a specific virtual machine and don't want to create a generalized image, skip the deprovisioning step.
sudo rm -f ~/.bash_history # Remove current user history sudo rm -rf /var/lib/waagent/ sudo rm -f /var/log/waagent.log sudo waagent -force -deprovision+user sudo rm -f ~/.bash_history # Remove root user history sudo export HISTSIZE=0Select Action > Shut Down in Hyper-V Manager.
Next steps
You're now ready to use your SUSE Linux VHD to create new virtual machines 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.
For an existing supported SLES VM that you need to move from SCSI to NVMe, use Convert Linux and Windows VMs from SCSI to NVMe.