Skip to main content

Microsoft Azure

This article refers to Platform v3.3.0. The current Platform version is v3.3.0.

Beta
This platform is newly supported and the integration is currently in Beta. You can follow this guide from start to finish, but you may come across minor issues. If you do, contact our support team and we will resolve them as soon as possible.

Overview

This guide walks you through running Barbara OS on a Microsoft Azure virtual machine using the azure_amd64 image. You upload the factory image to an Azure Storage account, turn it into a Gen2 managed disk in your own subscription, launch a VM from it, and Barbara OS provisions itself on first boot.

The azure_amd64 image is a UEFI, x86_64, GPT disk image — which on Azure means a Generation 2 (Gen2) VM. It ships with the Hyper-V synthetic drivers (hv_storvsc storage, hv_netvsc network) built into the kernel and exposes a serial console, so it boots headless on an Azure VM and is managed entirely through Barbara — there is no SSH key injection, no cloud-init, and no Azure guest agent.

The procedure has five phases:

  1. Install the prerequisites in your Azure subscription.
  2. Download the Azure image from Barbara Panel and extract the VHD.
  3. Upload the VHD to an Azure Storage account.
  4. Create a Gen2 managed disk from it.
  5. Launch the VM, read the Barbara ID, and register the node in Panel.

Pre-requisites

  • An active Azure subscription, with a resource group and a region chosen for the deployment.
  • The Azure CLI (az), installed and authenticated (az login, then az account set --subscription <subscription>).
  • A Storage account in your target region to stage the VHD (also used for the VM's boot diagnostics).
  • RBAC roles for the workflow, scoped to the resource group: Storage Account Contributor + Storage Blob Data Contributor (create the account, upload the VHD), Disk Contributor (create the managed disk), and Virtual Machine Contributor + Network Contributor (create the VM, its NIC/VNet, boot diagnostics and serial console). A single Contributor role on the resource group covers the whole loop.
  • The Barbara OS image for Azure (azure_amd64), downloaded from Barbara Panel — see the OS Images view.

Instance requirements

The image is UEFI + GPT, so it must run as a Gen2 VM (the managed disk carries --hyper-v-generation V2). Create the VM with Standard securitynot Trusted Launch — because the image is UEFI but not signed for Secure Boot; Trusted Launch (Secure Boot + vTPM) would prevent it from booting. Also disable Accelerated Networking: its Mellanox driver is not built into the kernel, and the device expects the synthetic Hyper-V NIC (hv_netvsc).

Strict minimum

  • RAM: 2 GB
  • OS disk: 32 GB
  • vCPU: 2
  • Architecture: x86_64
  • RAM: 4 GB
  • OS disk: 64 GB
  • vCPU: 2
  • Architecture: x86_64

A Standard_B1ms (1 vCPU / 2 GB) meets the minimum; Standard_B2s (2 vCPU / 4 GB) matches the recommendation.

note

The factory image is a 16 GB disk, which is smaller than the 32 GB minimum, so you must size the managed disk up when you create it in step 4. On first boot, Barbara OS creates and expands the user data partition to fill the OS disk, so choose a disk large enough for your workloads: the extra space becomes usable storage automatically.

Download the image from Panel

Download the azure_amd64 image from the OS Images view in Barbara Panel (see OS Images view). The Azure image is a -IMG.zip archive whose name follows the <device>-<environment>-<version>-<build> pattern — for example azure_amd64-pro-4.9.0-1784214128-IMG.zip.

Unzip it to obtain the disk image, a fixed VHD (.vhd) — the format Azure requires:

unzip azure_amd64-<environment>-<version>-<build>-IMG.zip   # -> <image>.vhd

The commands below use <image>.vhd as a placeholder; substitute the actual filename.

Upload the VHD to a Storage account

The <...> values are yours to choose, not existing values to look up: <storage-account> is a new name you invent — 3–24 characters, lowercase letters and digits only (no hyphens/underscores/uppercase), globally unique across Azure — and the first command below creates it (list existing ones with az storage account list -o table). <resource-group> is a resource group you own (az group list -o table, or az group create -n <rg> -l <region>), and <region> is a location such as westeurope or eastus.

Create the account and a container, then upload the VHD as a page blob (fixed VHDs must be page blobs):

az storage account create -n <storage-account> -g <resource-group> -l <region> --sku Standard_LRS
az storage container create --account-name <storage-account> -n vhds

az storage blob upload \
--account-name <storage-account> -c vhds \
-n <image>.vhd -f <image>.vhd --type page \
--auth-mode key --max-connections 16
  • --type pagerequired: a fixed VHD must be a page blob.
  • --max-connections 16 — the default is 2, and with it a 16 GB VHD can take hours. Raising it is the difference between minutes and an afternoon.
  • --auth-mode key — lets the CLI resolve the account key. The default login mode uses Entra ID on the data plane and fails with a permissions error unless you hold Storage Blob Data Contributor, which Storage Account Contributor alone does not grant.
The upload is not done until the whole VHD is there

A page blob reserves its full size the moment it is created, so contentLength reports 16 GB from the start and tells you nothing about progress. Do not use it to decide the upload finished, and do not trust an exit code you read through a pipe.

The next step validates the VHD footer, which sits in the last 512 bytes of the file, so an upload that stopped early fails with not a supported VHD … expected to have cookie value 'conectix'. To check the blob really is complete:

az storage blob download --account-name <storage-account> --auth-mode key \
-c vhds -n <image>.vhd --start-range 17179869184 --end-range 17179869695 \
-f footer.bin
head -c 8 footer.bin # must print: conectix

(The byte range above is for a 16 GB VHD: its size minus 512.)

Large uploads

For repeated uploads, azcopy is faster still, since it skips the VHD's empty pages. It uploads a fixed VHD as a page blob when the target name ends in .vhd.

Create the managed disk

Create a Gen2 managed disk directly from the uploaded blob:

az disk create \
-g <resource-group> -n barbara-azure-disk \
--os-type Linux --hyper-v-generation V2 \
--size-gb 32 \
--source https://<storage-account>.blob.core.windows.net/vhds/<image>.vhd
  • --hyper-v-generation V2required: this is what makes the disk (and the VM created from it) Gen2 / UEFI. Without it the VM is Gen1/BIOS and the UEFI/GPT image will not boot.
  • --os-type Linux — Barbara OS is Linux.
  • --source — the blob URL of the VHD you uploaded. If the storage account is private, add --source-storage-account-id <account-resource-id> so the disk service can read it.
  • --size-gb 32required: the VHD is a 16 GB disk, below the 32 GB minimum, so the disk has to be created larger than its source. Raise it further for bigger workloads; the data partition grows into whatever you set on first boot.

Confirm the disk came out Gen2 and at the size you asked for, because a Gen1 disk produces a VM that never boots:

az disk show -g <resource-group> -n barbara-azure-disk \
--query '[hyperVGeneration,diskSizeGB,diskState]' -o tsv

Expect V2, 32 and Unattached. Note the capital B in diskSizeGB: the camelCase spelling returns null, which reads like a disk with no size.

Launch the VM

Create the VM from the managed disk, as a Standard-security Gen2 VM:

az vm create \
-g <resource-group> -n barbara-node \
--attach-os-disk barbara-azure-disk --os-type Linux \
--security-type Standard \
--size Standard_B2s \
--accelerated-networking false \
--public-ip-sku Standard
  • --security-type Standarddo not use Trusted Launch. The image is UEFI but not Secure-Boot-signed; Trusted Launch would enable Secure Boot and block the boot.
  • --accelerated-networking false — the accelerated (Mellanox) NIC driver is not in the kernel; the synthetic Hyper-V NIC (hv_netvsc) is what the device uses.
  • --attach-os-disk — the VM inherits Gen2 from the disk's --hyper-v-generation V2.
  • The agent only needs outbound connectivity (to the Barbara Panel MQTT broker, the container registry, and the image/OTA storage). No inbound ports are required for normal operation — see From the agent API if you want to query the Barbara ID over the network, which needs an inbound NSG rule.

On first boot, Barbara OS binds its disk encryption to the VM's SMBIOS identity (product_uuid and product_serial), creates the cache and data partitions, and grows data to fill the OS disk.

warning

Register the factory image and create each VM's disk from it. The disk encryption key is derived on first boot and tied to that VM's identity, so do not capture an image from an already-initialized VM's disk and reuse it — the copy stays bound to the original VM and will not decrypt elsewhere.

Retrieve the Barbara ID and register the node

To add the node to Barbara Panel you need its Barbara ID — a unique identifier of the form azure_amd64-<hex>, derived on first boot from the VM's SMBIOS identity. On a headless Azure VM you read it from the agent's local HTTP API. The serial console is useful for watching the boot, but the ID is not printed there.

From the agent API (programmatic)

Before the node is registered, the agent exposes a small HTTP API on TCP port 18100 that returns the Barbara ID as JSON:

curl -s http://<public-ip>:18100/device/barbaraId
# {"barbaraId":"azure_amd64-5262355a6184a160726cdc5ed3caa72b"}

# just the value:
curl -s http://<public-ip>:18100/device/barbaraId | jq -r .barbaraId

Azure's default NSG does not open 18100, so add a temporary, scoped rule to reach it from your workstation, then remove it. az vm create names the auto-created NSG <vm>NSG (here barbara-nodeNSG):

MYIP=$(curl -s https://api.ipify.org)
az network nsg rule create \
-g <resource-group> --nsg-name barbara-nodeNSG -n allow-barbara-agent-18100 \
--priority 1000 --direction Inbound --access Allow --protocol Tcp \
--destination-port-ranges 18100 --source-address-prefixes "${MYIP}/32"

curl -s http://<public-ip>:18100/device/barbaraId

az network nsg rule delete -g <resource-group> --nsg-name barbara-nodeNSG -n allow-barbara-agent-18100
Availability and access
  • This API is available only until the node is registered in Panel. Once you register it, the API shuts down and the port closes, so query it during onboarding.
  • It is unauthenticated. Scope the NSG rule to a trusted source IP/CIDR (your operator workstation) — never 0.0.0.0/0 — and delete it once you have the ID.
No Azure guest agent

Barbara OS ships no Azure Linux guest agent (waagent), so Azure features that depend on it — SSH-key/password injection from the portal, the "Run command" extension, custom-script extensions — are not available. Manage the node through Barbara Panel and use the serial console for boot-level inspection.

Watch the boot (serial console)

For boot-level troubleshooting — not for the Barbara ID — enable boot diagnostics, then read the boot log or attach the serial console (no inbound rule needed):

az vm boot-diagnostics enable -g <resource-group> -n barbara-node

# one-shot boot log:
az vm boot-diagnostics get-boot-log -g <resource-group> -n barbara-node

# or attach the serial console:
az serial-console connect -g <resource-group> -n barbara-node

From the Azure Portal you can do the same without the CLI: open the VM → Help → Serial console to attach to ttyS0, or Help → Boot diagnostics for the Serial log (the full boot text) and a Screenshot of the console. Both need boot diagnostics enabled (the az vm boot-diagnostics enable above, or the portal enables it on first use).

For the full set of ways to find a node's identifier, see Get the Barbara ID of the node.

Summary

You have uploaded the azure_amd64 VHD to a Storage account, created a Gen2 managed disk, launched it as a Standard-security Azure VM, and let Barbara OS self-provision and bind its encryption on first boot. With the Barbara ID in hand, the next step is to add the node to Barbara Panel.