Skip to main content

Building a customized Red Hat Enterprise Linux 7 image for Microsoft Azure

Learn how to create a Red Hat Hat Enterprise Linux 7 image to run on Azure Mv2.
Building a customized RHEL 7 for Azure

Photo by Pixabay from Pexels

Do you plan to run Red Hat Enterprise Linux (RHEL) on Azure, or are you considering it, but you want to create your own images? In this article, I’ll focus on creating an RHEL 7 image to run on Azure Mv2 (aka Hyper-V Generation 2) instances. The main difference from a standard image is that you’ll use the Unified Extensible Firmware Interface (UEFI), and therefore there are additional options required.

Apart from the main focus on Mv2, I’ll also give you a good starter set of commands so you can automate the process of creating those images and eventually integrate that process into your CI/CD pipeline.

Most of these instructions should also be applicable for building Red Hat Enterprise Linux 8 images, but that version wasn’t my primary focus.

Setting up the environment

As the build environment, Red Hat Enterprise Linux 8 provides us with the correct set of tools in order to build UEFI-bootable images. In order to reproduce everything here, you’ll need the following packages installed:

You will also need a copy of the Red Hat Enterprise Linux 7.7 binaries DVD, which you can download here if you have a valid Red Hat subscription. Save this DVD as /var/lib/libvirt/images/rhel-server-7.7-x86_64-dvd.iso.

Note: Any other Red Hat Enterprise Linux 7- or 8-based version should do it, but this walk-through has been tested with 7.7.

In order for the above to work if you’re running on a VM, you’ll need KVM enabled on the host or passed through to the VM. If you want to run this example on a remote VM, or in another CI/CD pipeline, I’ve done exactly that in order to be able to automate the process, so you can run this headless (no X, graphical UI, and X forwarding needed).

Building an image in an automated fashion

We need a few packages installed in our image plus some configurations set, and it’s recommended to have the Azure client installed. While I was searching for the best way to get this client installed in an automated fashion, the only option I found was to obtain it from the CentOS 7 extras repository (reach out to me and let me know if you know a better way).

A sample kickstart.cfg file can be obtained here. Adapt it to your needs, but make sure to leave at least the network configuration set to DHCP.

Building the image with the Kickstart file and a simple command

To build the image: 

$ sudo virt-install \
       --name rhel77 \
       --memory 4096 \
       --vcpus 4 \
       --boot uefi \
       --os-variant rhel7.7 \
       -l /var/lib/libvirt/images/rhel-server-7.7-x86_64-dvd.iso \
       --disk size=4 \
       --initrd-inject $(pwd)/kickstart.cfg \
       --extra-args="ks=file:/kickstart.cfg console=tty0 console=ttyS0,115200n8" \
       --graphics=none \
       --network network=default \

As mentioned above, you’ll need to have the DVD image in the correct place. My example assumes that you:

  • Have kickstart.cfg in your current $PWD.
  • Want a 4GB disk.
  • Are using your local libvirt/KVM install.
  • Have no special requirements regarding the network interface (I’m using the defaults).

Converting the image to the right format

I struggled to convert the image to the right format, but with friendly colleagues and Google, I finally figured out the format required: VHD aligned to 1MB.

The last built image should be the correct one:

$ image=$(ls -1tr /var/lib/libvirt/images/rhel*|tail -1)

Use sudo to access the image, convert it to RAW and put it into the current $PWD

$ sudo qemu-img convert -f qcow2 -O raw $image rhel-7.7.raw

Make sure we can access it - after this point, a “normal” (eg. non-root use can continue)

$ sudo chown $(whoami) *.raw

Calculate the size of the image.

$ MB=$((1024*1024)) size=$(qemu-img info -f raw --output json "rhel-7.7.raw" | \ gawk 'match($0, /"virtual-size": ([0-9]+),/, val) {print val[1]}') rounded_size=$((($size/$MB + 1)*$MB))

Resize the image.

$ sudo qemu-img resize -f raw rhel-7.7.raw $rounded_size

Convert the image from RAW to VHD and force the correct size

$ sudo qemu-img convert -f raw -o subformat=fixed,force_size -O vpc rhel-7.7.raw rhel-7.7.vhd

Creating a group

Now you have your own customized Red Hat Enterprise Linux 7 image. You’re probably wondering how to upload it to Azure and use it to run an instance. Read further. Since I was had to test my whole build process, I’ve done this as well.

You’ll always need a resource group in Azure. I’ve chosen westus2 as my region, but any other should do as well (if they have Mv2 instances). The name for my resource group is simply myresourcegroup. If you want to use another name, you’ll have to replace it everywhere that I used it.

To create your group, create AZ resource group in westus2 and name “myresourcegroup”.

$ sudo az group create -l westus2 -n myresourcegroup

Uploading the disk image and making it an Azure image

To upload the disk image and make it into an Azure image, create the disk in Azure with the name ‘rhel-7’, in our previously created resource group ‘myresourcegroup’.

$ sudo az disk delete --name rhel-7 -g myresourcegroup -y

Make sure it’s Hyper-V Gen 2 and operating system type Linux with the correct size.

$ sudo az disk create --hyper-v-generation V2 -g myresourcegroup -n rhel-7 --os-type Linux -l westus2 --for-upload --upload-size-bytes $(wc -c rhel-7.7.vhd|awk '{ print $1 }') --sku standard_lrs

You need a SASURI for uploading.

$ SASURI=$(az disk grant-access -n rhel-7 -g myresourcegroup --access-level Write --duration-in-seconds 86400 --query [accessSas] -o tsv)

This uses azcopy to copy the image (azcopy needs to be in your $PATH somewhere)

$ sudo azcopy $(pwd)/rhel-7.7.vhd $SASURI --blob-type PageBlob

After the upload is completed, we need to revoke the access, else the disk image cannot be used.

$ sudo az disk revoke-access -n rhel-7 -g myresourcegroup

Finally, mark it a Hyper-V, Gen 2 OS image.

$ sudo az image create -g myresourcegroup -n rhel-7 --os-type Linux --hyper-v-generation V2 --source rhel-7

Running the image

One would imagine that at this point in time, everything was clear and running an image would be easy. If you got everything correctly in place, yes, that’s true. But when I worked through this example, I completely forgot about the last step in the previous paragraph and didn’t mark the disk image an Azure image, which resulted in not being able to provide the SSH key or admin-username.

Anyway, with the above instructions, you should be all set to run the image. The following command assumes that you’re running this tool as the root user and using the root user’s SSH key. Adapt what I have here to your needs:

$ sudo az vm create  \
      --resource-group myresourcegroup \
      --location westus2 \
      --name rhel-7 \
      --image rhel-7 \
      --admin-username cloud-user \
      --ssh-key-value @/root/.ssh/

If you need boot diagnostics, you’ll need to create a so-called storage account with the name "storageaccount123" using the following command:

$ sudo az storage account create -n storageaccount123 -g myresourcegroup -l westus2 --sku Standard_LRS

The above az vm create command needs to be extended with the following parameter in order to log the boot diagnostics and messages to the storage account we just created:

--boot-diagnostics-storage storageaccount123

Note: You do not need to enable boot diagnostics, and if you do, you’ll definitely have to adapt the storage account name.

Logging into the Azure instance

From the az vm create command, you should get output containing the IP address. You should now be able to log in automatically, given that the SSH key is provided with:

$ ssh cloud-user@<azure-ip>

Wrapping up

Before exploring the possibilities of creating Red Hat Enterprise Linux 7 images for Azure Mv2 instances in an automated fashion, I had no previous experience with Azure, and therefore it was quite a journey. I’d still not consider myself an expert when it comes to Azure, and there are probably things missing. I’d love to hear your opinions to enhance this setup if necessary.

The scripts and commands I used for this article can be found here. Pull requests are welcome, as well as clones!

Want to try out Red Hat Enterprise Linux? Download it now for free. 

Topics:   Linux   Cloud  
Author’s photo

Oliver Falk

I have worked in IT for more than 20 years. Most of my experience is as a UNIX/Linux Systems Engineer/Administrator. Now I work for Red Hat as a senior technical account manager (TAM). More about me

Try Red Hat Enterprise Linux

Download it at no charge from the Red Hat Developer program.