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.
| Capability | BYOC on Azure | BYOC on AWS | BYOC on GCP |
|---|---|---|---|
| Snapshot runners | Not supported | Not supported | Not supported |
| Import existing stack resources | Not supported | Supported | Not supported |
| Create stack resources in a new network | Supported | Supported | Supported |
| Custom resource tags | Pending | Supported | Pending |
| Custom service account roles | Pending | Supported | Supported |
| Region availability | East US only today | Any region you configure | Any region you configure |
| Windows runners, x86-64 | Supported | Supported | Pending |
| macOS runners | Not offered on BYOC | Not offered on BYOC | Not offered on BYOC |
| Static IPs | Supported | Supported | Supported |
| Standby disks | Supported | Supported | Supported |
| Custom VM images | Supported | Supported | Supported |
| Spot instances | Supported | Supported | Supported |
| Local SSD auto-mount | Supported | Supported | Supported |
| Nested virtualization | Supported | Supported | Supported |
| Container layer caching | Supported | Supported | Supported |
| Network addons | Supported | Supported | Supported |
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.
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' buildOperations
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.
| Limitation | Workaround on Azure | Path on another cloud |
|---|---|---|
| Snapshot runners unavailable | Keep snapshot-dependent jobs on hosted Linux runners with snapshot.key or snapshot.enabled in the same workflow | None. Snapshot runners are hosted only on all three clouds |
| No import of an existing virtual network | Let the stack create its network, subnetworks, and storage; plan a fresh address range | Import mode exists on AWS and takes an existing VPC, subnets, and security group as inputs |
| East US only | Create the stack in East US; request additional regions through [email protected] | AWS and GCP stacks are created in whichever region you configure |
| Resource tagging pending | Attribute cost at the subscription or resource group boundary, and give GitHub Actions its own subscription if the finance split has to be clean | Custom resource tags are supported on AWS |
| Custom service account roles pending | Authenticate from inside the job with GitHub OIDC (securing deployments with OpenID Connect) rather than an identity attached to the VM | Custom roles are supported on AWS and GCP |
| macOS absent from BYOC | Run iOS and macOS jobs on hosted warp-macos-latest-arm64-6x labels alongside the Azure jobs | None. The macOS fleet is hosted on all three clouds |
| Stack name, storage, and region fixed at creation | Treat the stack as immutable: create the replacement, repoint runners, then delete in dependency order | Same 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 item | Rate | Compute billed by |
|---|---|---|
| BYOC Linux or Windows runner minute on Azure | $0.002 per minute | Your Azure subscription: VM, disk, IP, storage |
Hosted warp-ubuntu-latest-x64-4x | $0.008 per minute | WarpBuild |
Hosted warp-windows-latest-x64-4x | $0.016 per minute | WarpBuild |
Hosted warp-macos-latest-arm64-6x | $0.08 per minute | WarpBuild |
| Snapshot restore | $0.04 per job | WarpBuild |
| Snapshot storage | $0.025 per snapshot-hour | WarpBuild |
| 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.