Current Limitations of BYOC on Azure

BYOC on Azure has no snapshot runners, no stack import flow, East US only, and tagging plus custom roles pending. Every documented limit with its workaround.

BYOC on Azure carries four documented limits: snapshot-based runners are not available, the stack creation flow cannot import an existing virtual network, stacks are currently enabled for East US only, and resource tagging plus custom service account roles are listed as pending. Everything else in the Azure column of the feature matrix is supported, including Windows Server 2022 x86-64 runners, static IPs, standby disks, spot instances, local SSD auto-mount, and nested virtualization.

This page states each limit the way the documentation states it, then gives the workaround, including the AWS or GCP path where another cloud has a capability Azure does not carry yet. BYOC runs on AWS, GCP, and Azure, so most of the platform behaves identically across the three and the rows below are the Azure-specific part of a fleet decision.

Overview

The limits come from two documented sources, both checked on 2026-08-13: the Limitations and Coming Soon sections of the Azure configuration guide, and the Azure column of the feature matrix.

CapabilityBYOC on AzureBYOC on AWSBYOC on GCP
Snapshot runnersNot supportedNot supportedNot supported
Import existing stack resourcesNot supportedSupportedNot supported
Create stack resources in a new networkSupportedSupportedSupported
Custom resource tagsPendingSupportedPending
Custom service account rolesPendingSupportedSupported
Region availabilityEast US only todayAny region you configureAny region you configure
Windows runners, x86-64SupportedSupportedPending
macOS runnersNot offered on BYOCNot offered on BYOCNot offered on BYOC
Static IPsSupportedSupportedSupported
Standby disksSupportedSupportedSupported
Custom VM imagesSupportedSupportedSupported
Spot instancesSupportedSupportedSupported
Local SSD auto-mountSupportedSupportedSupported
Nested virtualizationSupportedSupportedSupported
Container layer cachingSupportedSupportedSupported
Network addonsSupportedSupportedSupported

Two rows deserve a plain reading rather than a softened one. Snapshot runners are unavailable on every BYOC cloud, so this is a hosted-versus-BYOC boundary rather than an Azure gap. macOS is absent from all three BYOC columns as well. The macOS fleet is hosted, so an iOS job in an Azure-based pipeline keeps a hosted label.

Architecture

Three properties of a stack are fixed at creation: the stack name, the storage account and container, and the region. That immutability turns the East US restriction into a planning decision rather than a setting you revisit. A second region means a second stack, a second storage container, and a second set of custom runner definitions pointing at it, and additional regions go through [email protected].

The missing import flow lands in the same place. On Azure the stack provisions its own virtual network, one public and one private subnetwork, and the storage account and container used for artifact cache, container layer caches, and telemetry data. Budget an address range for a new network in East US instead of budgeting time to adopt one you already run. The BYOC setup documentation confirms that importing resources is supported on AWS only.

Deletion runs in reverse and the platform enforces the order. A cloud connection cannot be deleted while stacks depend on it, and a stack cannot be deleted while custom runner configurations depend on it, so a region migration is a create-then-repoint-then-delete sequence: build the new stack, point each custom runner at it, then remove the old runners, the old stack, and finally the connection if nothing else uses it.

Quota headroom sits on your side of the line. The Azure BYOC docs publish per-stack guidance where CON is the number of concurrent jobs you want to support: CPU at CON times vCPU per job, persistent disks at CON times disk size, in-use regional external IPv4 addresses at 3 plus CON, one storage container, three NAT, one virtual network, and two subnetworks. Those quotas apply to the region holding the stack, which for now means East US.

Configuration

Two behaviors that often need flags elsewhere need no configuration at all on Azure, and both are worth knowing before you size VMs.

Local SSD. If the selected VM sizes include local NVMe temporary storage, the disks are detected and mounted to the runner work directory at boot. A single local SSD is formatted and mounted directly, and multiple local SSDs are combined into a RAID-0 array before mounting. This applies to Linux-based images only, so a Windows Server 2022 runner set on Azure plans its throughput around managed disks. The full support matrix and the instance families that carry NVMe temporary storage are on the local SSD runners page.

Nested virtualization. Nested virtualization works automatically on Azure VM sizes that support it with the default Standard security type, with no label and no extra configuration. One caveat carries across BYOC clouds: it is enabled only when every instance type configured for the runner set supports it, so a fallback list mixing supporting and non-supporting sizes turns it off for consistency. Android emulator jobs still need the KVM permissions step described on the nested virtualization page.

Managed disk configuration has a documented floor. The minimum disk size is 256GB and the recommended configuration is P20, with throughput and IOPS managed automatically by Azure (Azure managed disk types). Pick one or more instance types in priority order so a capacity gap in East US falls back without a workflow edit, and keep the sizes close in performance so job durations stay predictable. Spot instances suit short interruptible jobs, and Azure bills that capacity to your subscription at its own published rates.

A workflow absorbs the two hard limits with labels rather than with restructuring. The BYOC jobs carry the full Runner ID with its warp-custom- prefix, and the snapshot job and the macOS job carry hosted labels.

.github/workflows/ci.yml
name: ci
on: [push]

jobs:
  build:
    runs-on: warp-custom-azure-eastus-linux-8x
    steps:
      - uses: actions/checkout@v4
      - run: make build

  integration:
    # Snapshot runners are hosted only, so this job stays on a warp- label
    runs-on: warp-ubuntu-latest-x64-4x;snapshot.key=integration-db
    steps:
      - uses: actions/checkout@v4
      - run: ./scripts/integration.sh

  package-ios:
    runs-on: warp-macos-latest-arm64-6x
    steps:
      - uses: actions/checkout@v4
      - run: xcodebuild -scheme App -destination 'generic/platform=iOS' build

Operations

Each limit has a documented workaround, and three of them have a path on another cloud that matters when the fleet is already multi-cloud.

LimitationWorkaround on AzurePath on another cloud
Snapshot runners unavailableKeep snapshot-dependent jobs on hosted Linux runners with snapshot.key or snapshot.enabled in the same workflowNone. Snapshot runners are hosted only on all three clouds
No import of an existing virtual networkLet the stack create its network, subnetworks, and storage; plan a fresh address rangeImport mode exists on AWS and takes an existing VPC, subnets, and security group as inputs
East US onlyCreate the stack in East US; request additional regions through [email protected]AWS and GCP stacks are created in whichever region you configure
Resource tagging pendingAttribute cost at the subscription or resource group boundary, and give GitHub Actions its own subscription if the finance split has to be cleanCustom resource tags are supported on AWS
Custom service account roles pendingAuthenticate from inside the job with GitHub OIDC (securing deployments with OpenID Connect) rather than an identity attached to the VMCustom roles are supported on AWS and GCP
macOS absent from BYOCRun iOS and macOS jobs on hosted warp-macos-latest-arm64-6x labels alongside the Azure jobsNone. The macOS fleet is hosted on all three clouds
Stack name, storage, and region fixed at creationTreat the stack as immutable: create the replacement, repoint runners, then delete in dependency orderSame behavior on AWS and GCP

The snapshot workaround is the one with a price attached, so run the arithmetic before deciding which jobs move to Azure. Rates below come from the pricing page, with the GitHub list price checked on 2026-08-13.

Line itemRateCompute billed by
BYOC Linux or Windows runner minute on Azure$0.002 per minuteYour Azure subscription: VM, disk, IP, storage
Hosted warp-ubuntu-latest-x64-4x$0.008 per minuteWarpBuild
Hosted warp-windows-latest-x64-4x$0.016 per minuteWarpBuild
Hosted warp-macos-latest-arm64-6x$0.08 per minuteWarpBuild
Snapshot restore$0.04 per jobWarpBuild
Snapshot storage$0.025 per snapshot-hourWarpBuild
GitHub-hosted 4-core Linux larger runner$0.012 per minute (GitHub billing reference, checked 2026-08-13)GitHub

Take a pipeline with a 12 minute build job and a 10 minute integration job that restores a snapshot on every run. The build job on BYOC Azure costs 12 x $0.002 = $0.024 in WarpBuild fees, with the VM, disk, IP, and storage landing on your Azure invoice. The integration job stays hosted at 10 x $0.008 = $0.08 plus $0.04 for the restore, so $0.12 per run plus snapshot storage at $0.025 per snapshot-hour. The same integration job on the GitHub-hosted 4-core Linux larger runner is 10 x $0.012 = $0.12 in runner minutes with no snapshot restore available at all. Split that way, the East US limit and the snapshot limit cost a hybrid label map rather than a second platform.

Next steps depend on which limit is blocking. For the full Azure setup path, the consent model, and the quota table in context, start with BYOC runners on Azure. For the decision about which jobs belong on your subscription at all, see hosted versus BYOC runners. For the two automatic behaviors above, the detail lives on the local SSD and nested virtualization pages.

FAQ

What are the documented limitations of BYOC on Azure?

Four. Snapshot-based runners are not available, the stack creation flow cannot import an existing virtual network, stacks are currently enabled for East US only, and resource tagging plus custom service account roles are listed as pending. Everything else in the Azure column of the feature matrix is supported, including Windows Server 2022 x86-64, static IPs, standby disks, spot instances, local SSD auto-mount, and nested virtualization.

Can I run snapshot runners on BYOC Azure?

No. The feature matrix marks snapshot runners as unsupported on all three BYOC clouds, so snapshot labels belong on WarpBuild-hosted Linux runners. A single workflow can carry both, with snapshot-dependent jobs on a warp- label and the rest of the pipeline on a warp-custom- label in your Azure subscription.

Can a BYOC Azure stack use a virtual network I already run?

No. Import of existing stack resources is supported on AWS only, so an Azure stack creates its own virtual network, its public and private subnetworks, and its storage account and container. Plan a fresh address range in East US before you start, because the stack name, the storage account and container, and the region are fixed at creation.

Start with $10 in free credits

Change the runner label in your workflow and keep the rest of your GitHub Actions setup. Runner time is billed per minute.