Archlinux on Azure

Posted on Mon 15 August 2016 in Technology • 4 min read

This post covers the steps required to get an Archlinux virtual machine up in Azure.

azure and archlinux

Azure documentation has a guide for Create and upload generic linux image. We will expand on it and go into archlinux specific details here :)

Pre-requisites

We will use qemu through out this article to run a VM locally and configure it. Let’s install it right away.

1
# pacman -S qemu

Our strategy is to locally create a virtual machine with all requisites for azure. Then we will convert the VM hard disk to a VHD suitable for azure. Finally, we will publish the vhd to cloud, and create a VM in azure from that!

Get a virtual machine

We will assume you already have a stock virtual machine image. You can get the archlinux iso and prepare a VM with qemu, or download a archlinux image1.

Start the image in qemu.

1
$ qemu-system-x86_64 archlinux.qcow2

All the following commands will run in the VM we just started.

Prepare the VM

Let’s tweak the image for azure readiness.

Add hyper-v modules to startup

Azure requires the hyper-v modules to be preloaded during boot time. We will create a new initramfs with them.

1
2
3
4
# vim /etc/mkinitcpio.conf

Modify the MODULES array in the file
MODULES="hv_storvsc hv_vmbus"

Now generate the default initramfs image.

1
# mkinitcpio -p linux

Validate the generated image has required modules.

1
2
3
4
5
# lsinitcpio /boot/initramfs-linux.img | grep hv_

Output should be similar to:
usr/lib/modules/4.7.0-1-ARCH/kernel/hv_storvsc.ko
usr/lib/modules/4.7.0-1-ARCH/kernel/hv_vmbus.ko

Install WALinuxAgent and configure it

WALinuxAgent, as the name suggests, configures the VM to be azure compliant. It keeps azure notified of key changes like hostname etc., provisions a resource disk and so on.

If you’ve not setup yaourt or a similar aur package manager, please do so. Install the azure linux agent from AUR.

1
$ yaourt -S walinuxagent

This package installs the waagent systemd service in the VM for monitoring. We will enable the service at boot.

1
# systemctl enable waagent

Modify /etc/waagent.conf with following values.

1
2
3
Provisioning.DeleteRootPassword=n
Logs.Verbose=y
AutoUpdate.Enabled=n

Note that the options are primarily geared to help us debug failures. Later we can configure ssh to not allow root to login. We’ve disabled autoupdate to ensure VM doesn’t break without our knowledge, the demerit is we will not get any fixes (incl. critical ones) automatically. We can turn this on later as well.

A few additional checks before we deprovision the virtual machine.

Ensure dhcpcd service is enabled to run at startup. Without it, we will just lock the VM out in the cloud :)

1
# systemctl enable dhcpcd

Ensure ssh daemon is set to run at startup. You may want to pre-provision an user in the VM; just in case. Modify /etc/ssh/sshd.config appropriately.

1
# systemctl enable sshd

We’re now ready to deprovision the virtual machine.

1
2
3
# waagent -force -deprovision
# export HISTSIZE=0
# shutdown -h now

Virtual disk on the cloud

Now back to the local box which hosts the virtual machine.

Azure requires the VHD to be a fixed disk with size rounded to the nearest MB. The azure guide provides clear instructions for this. We’ll convert our disk to a raw image first.

1
$ qemu-img convert -f qcow2 -O raw archlinux.qcow2 archlinux.raw

Save the following script as resize.sh in local directory.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# Prints the size of raw and vhd disk
rawdisk="archlinux.raw"
vhddisk="archlinux.vhd"

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

echo "Current Size = $size"
rounded_size=$((($size/$MB + 1)*$MB))
echo "Rounded Size = $rounded_size"

echo "VHD Info:"
size=$(qemu-img info -f raw --output json "$vhddisk" | \
       gawk 'match($0, /"virtual-size": ([0-9]+),/, val) {print val[1]}')

echo "Current Size = $size"
rounded_size=$((($size/$MB + 1)*$MB))
echo "Rounded Size = $rounded_size"

On running ./resize.sh you will get the rounded size of the raw image. Resize it first to that value.

1
2
# # rounded_size is got by running ./resize.sh
$ qemu-img resize archlinux.raw <rounded_size>

Now convert the raw image to vhd.

1
2
$ qemu-img convert -f raw -o subformat=fixed,force_size -O vpc archlinux.raw archlinux.vhd
$ ./resize.sh

Validate that the Rounded size for raw and vhd are the same.

Upload the vhd to azure

Install azure-vhd-utils-for-go-git from AUR.

1
$ yaourt -S azure-vhd-utils-for-go-git 

Following command will upload the vhd and create a VM image in Azure.

1
$ vhd upload --localvhdpath archlinux.vhd --stgaccountname archtest --stgaccountkey storagekey --blobname archlinux.1

Note that the archtest storage account is a classic storage account.

Create VM in azure

Navigate to the older azure portal https://manage.windowsazure.com.

Create a Image for the vhd:

  • Navigate to Virtual Machines in the left side pane
  • Open the Images tab in right side
  • Use Create from the toolbar below

create vm image in azure

Point the image to vhd uploaded previously.

For creating a VM with a custom image, use the Images option in Create VM dialog. There’s a windows VM guide here, the steps are similar for our custom vhd.

choose vm image in azure

That’s all for now. If all went well, you should be able to ssh into the VM just created :)


  1. You can get one from tuxfixer. Here’s the direct link to qcow2 file.