VirtualBox Setup
→ archlinux.org — Download the ISO
Open VirtualBox → New → set the following:
| Setting | Value |
|---|---|
| Name | AzureVmTemplate (or whatever haunts you) |
| Type | Linux |
| Version | Arch Linux (64-bit) |
| RAM | 2048 MB minimum |
When prompted for storage: choose Create a virtual hard disk now → VHD (Virtual Hard Disk) → Fixed size → 30 GB.
Go to Settings → System → Motherboard.
Make sure "Enable EFI (special OSes only)" is unchecked. GRUB will be installed in BIOS/MBR mode. EFI will cause everything to collapse quietly and without mercy.
If EFI is enabled, the GRUB install will appear to succeed, the VM will appear to boot, and then nothing will work in Azure. You will spend hours debugging something that a single unchecked checkbox caused. Uncheck it now. Sleep well later.
Go to Settings → Network → Adapter 1 → set Attached to: Bridged Adapter → select your active network interface.
Go to Settings → Storage → Controller: IDE → click the empty optical drive → Choose a disk file → select the Arch ISO.
Start the VM. You will be dropped into a root shell. You are now on the launchpad.
Arch Linux Installation
$ timedatectl set-ntp true
$ cfdisk /dev/sda
| Partition | Size | Type | Purpose |
|---|---|---|---|
| /dev/sda1 | 10 MB | BIOS boot | GRUB anchor point |
| /dev/sda2 | Remaining | Linux filesystem | Everything else. Your whole life. |
$ mkfs.ext4 /dev/sda2 $ mount /dev/sda2 /mnt
$ pacstrap /mnt base linux linux-firmware grub nano git \
btop curl wget openssh dhcpcd sudo dnsutils \
base-devel htop
$ genfstab -U /mnt >> /mnt/etc/fstab
$ arch-chroot /mnt
$ ln -sf /usr/share/zoneinfo/Asia/Dhaka /etc/localtime $ hwclock --systohc
$ nano /etc/locale.gen # Uncomment: en_US.UTF-8 UTF-8 $ locale-gen $ echo "LANG=en_US.UTF-8" > /etc/locale.conf $ echo "KEYMAP=us" > /etc/vconsole.conf
$ grub-install --target=i386-pc /dev/sda $ nano /etc/default/grub # Edit if needed $ grub-mkconfig -o /boot/grub/grub.cfg
$ passwd
$ useradd -m -G wheel -s /bin/bash potato $ passwd potato
potato with your preferred username. Or don't. Potato is a perfectly valid identity.$ nano /etc/sudoers # Uncomment both wheel lines: # %wheel ALL=(ALL:ALL) ALL # %wheel ALL=(ALL:ALL) NOPASSWD: ALL
$ nano /etc/ssh/sshd_config # Set PermitRootLogin yes $ systemctl enable dhcpcd $ systemctl enable sshd
$ nano /etc/hosts # Add: 127.0.0.1 localhost ::1 localhost 127.0.1.1 AzureVmTemplate AzureVmTemplate.localdomain
$ exit $ umount -a $ poweroff
Prepare for Azure
Boot the VM after the initial installation before proceeding. The following steps run inside the live system, not the installer.
$ nano /etc/mkinitcpio.conf # Change: MODULES=(hv_storvsc hv_vmbus)
$ mkinitcpio -p linux
WA Linux Agent
$ su potato $ cd && mkdir aur && cd aur $ git clone https://aur.archlinux.org/walinuxagent.git $ cd walinuxagent && makepkg -si
$ systemctl enable waagent
$ nano /etc/waagent.conf # Set: ResourceDisk.EnableSwap=y ResourceDisk.SwapSizeMB=8192
$ mkdir /mnt/resource
$ rm -Rf ~/.bash_history ~/aur
$ waagent -force -deprovision $ export HISTSIZE=0 $ shutdown -h now
Upload to Azure
$ az login
$ az storage blob upload \ --account-name <storage-account-name> \ --account-key <access-key> \ --container-name <container-name> \ --name arch.vhd \ --file <path/to/your.vhd>
<bracketed> values with your actual Azure credentials. Do not commit them to git. Do not paste them in Discord. You know what you did last time.Your Arch Linux VHD is now floating somewhere in Microsoft's data centers. It has survived VirtualBox, a manual partition table, GRUB in BIOS mode, and the Azure provisioning process. Respect it accordingly.