BYOC Runners on Azure for GitHub Actions
WarpBuild BYOC runs GitHub Actions runners inside your own Azure subscription. WarpBuild manages the fleet, your subscription owns the VMs, disks, and cache.
Last verified:
WarpBuild BYOC runs GitHub Actions runners as ephemeral VMs inside an Azure subscription you own, while WarpBuild manages the fleet: it creates each runner, registers it with GitHub, and terminates it when the job ends. Your subscription holds the virtual network, the VMs, the disks, and the storage account and container used for cache and telemetry, so Azure bills that compute to you directly and WarpBuild charges $0.002 per minute for BYOC runners.
BYOC runs on AWS, GCP, and Azure. This page covers the Azure path: what lives where, which consent and quotas the setup needs, what the dashboard configures, and who is responsible for each piece once runners are live. One constraint decides most of the planning, so it belongs up front: BYOC Azure is currently enabled for East US only, and additional regions go through [email protected].
Architecture
BYOC on Azure splits into two planes.
The WarpBuild control plane decides when a runner is needed, creates it in your subscription, registers it with GitHub against the repositories you granted through the WarpBuild GitHub bot, and terminates the VM when the job finishes. It holds the runner images, the queue logic, and the dashboard where stacks and runner configurations are defined.
Your Azure subscription holds everything that costs Azure money. The VMs that execute jobs, their disks and IP addresses, the virtual network and subnets they sit in, and the storage account and container that holds artifact cache, container layer caches, and telemetry data are all resources in your subscription, under your own role assignments and your own bill.
Three objects connect the two planes, and they are created in this order.
- A cloud connection. Creating a cloud connection sets up a consent for the WarpBuild CI Enterprise application with the permissions required by WarpBuild to manage runners. You provide the tenant ID and subscription ID to verify the connection after the consent and permission configuration (ARM deployment) is complete.
- A stack. A stack is the group of infrastructure in one region of your subscription that runners need: the virtual network, the public and private subnetworks, and the storage account and container used for cache and telemetry.
- A custom runner. A custom runner is the machine shape: one or more VM sizes in priority order, the disk configuration, and the IP configuration. Each custom runner gets a Runner ID, and that ID, prefixed with
warp-custom-, is theruns-onlabel your workflow uses.
Three properties of a stack are fixed at creation. The stack name, the storage account and container, and the region cannot be changed after creation. Treat a stack as immutable infrastructure: to move regions, to rename, or to relocate cache storage, create a new stack, point the custom runners at it, and delete the old one.
Deletion runs in reverse and the platform enforces the order. A cloud connection cannot be deleted until the stacks that depend on it are deleted, and a stack cannot be deleted until the custom runner configurations that depend on it are deleted. WarpBuild shows the dependent list on each delete confirmation, so a cleanup pass starts at the runner configurations.
Every job gets a fresh VM. There is no persistent runner pool to patch, no controller to keep alive in your cluster, and no state carried from one job to the next inside the VM. Cache is the deliberate exception, and it lives in the storage account and container in your subscription rather than on the machine.
Egress costs during deploy-heavy jobs are handled on the enterprise tier; see zero egress on the WarpBuild enterprise tier. Region placement for regulated workloads is covered on the US data residency page and the EU data residency page; US and EU are the regions WarpBuild names publicly.
Permissions and Access
Setup needs three grants: one in Microsoft Entra, one in the Azure subscription, and one in GitHub.
Entra consent. The person running setup must hold Privileged Role Administrator to grant admin consent for the WarpBuild CI Enterprise application. That consent is what allows WarpBuild to manage runner infrastructure. If your organization separates directory administration from subscription ownership, book both people for the same window, because the connection is only verified once the consent and the ARM deployment have both landed.
Subscription scope. The connection is verified against the tenant ID and subscription ID you supply, so its blast radius is that subscription. A second subscription needs a second cloud connection. Teams that want a hard audit boundary between GitHub Actions and production usually connect a subscription dedicated to GitHub Actions, which also makes the compute line on the Azure bill self-explanatory.
GitHub access. Install the WarpBuild GitHub bot and grant it the repositories whose workflows should be allowed to queue jobs on these runners. Runners register against those repositories, and a workflow reaches the fleet by carrying the matching warp-custom- label in runs-on.
The outbound list for a runner is short. A runner needs outbound access to api.warpbuild.com for registration and lifecycle, and to github.com and api.github.com for the job itself, plus whatever package registries and container registries your build pulls from. The AWS security hardening guide documents that outbound list in full, and the same destinations apply to runners on Azure.
Quotas in the stack region
Runner resources are created in the BYOC Azure subscription, so Azure quotas set your practical concurrency ceiling. The Azure BYOC docs publish per-stack guidance where CON is the number of concurrently running jobs you want to support.
| Resource | Additional quota per stack | Notes |
|---|---|---|
| CPU | CON x vCPU per job | Adjust for machine type, preemptible, and on-demand instances |
| Persistent disks | CON x DISK_TB | Adjust provisioned IOPS if needed |
| In-use regional external IPv4 addresses | 3 + CON | One static IP is required for NAT in a stack, and one static IP is attached to each concurrently running job |
| Object storage | 1 | The same storage container is used for artifact cache, container layer caches, and telemetry data |
| NAT | 3 | One per stack |
| Networks | 1 | One virtual network is needed |
| Subnetworks | 2 | One public and one private subnetwork is needed per stack |
Two details trip up first-time setups. The quotas apply to the region where the stack is created, so change the region selector in the Azure portal before editing quota values. And the list is a starting point rather than an exhaustive one; for a fleet sized past a few hundred concurrent jobs, send the intended concurrency to [email protected] and get the numbers checked before the first heavy Monday morning.
A new stack that throttles early is usually short on quota in its region. Azure approves increases asynchronously, so file the requests during setup rather than after the first queue backs up.
Configuration
Setup is three screens in the dashboard, in the order the architecture describes: connect the subscription, create the stack, create one or more custom runners. Two limits shape the choices.
No import flow. BYOC Azure does not support the import flow for stack creation, so the stack creates its own network resources rather than adopting a virtual network you already run. Plan the address space for a new network instead of budgeting time to reuse an existing one.
No snapshot runners. Snapshot-based runners are not available for BYOC Azure. Keep snapshot-dependent jobs on WarpBuild-hosted Linux runners and run the rest of the pipeline in your subscription.
Region availability
BYOC Azure is currently enabled for East US. For additional regions, reach out to [email protected]. Because the region is fixed at stack creation, decide the region before you create anything, and remember that a second region later means a second stack, a second storage container, and a second set of custom runner definitions pointing at it.
Machine and disk configuration
Pick one or more instance types in priority order. The GitHub workflow uses a single runner label, and the runner picks the instance type based on availability, so a priority list absorbs capacity gaps in the region without a workflow edit. Choose sizes with similar performance so job durations stay predictable across the fallbacks.
Spot instances are useful for short jobs that can be interrupted, and they pair well with a priority list of two or three sizes. Azure bills that capacity to your subscription at its own published rates.
Disk configuration has a documented floor. The minimum disk size is 256GB, and the recommended configuration is P20; throughput and IOPS are managed automatically by Azure, described on the Azure managed disk types page.
Two behaviors need no configuration at all. If the selected VM sizes include local NVMe temporary storage, the disks are detected and mounted to the runner's 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. Nested virtualization also works automatically on Azure VM sizes that support it with the default Standard security type, which matters for Android emulator jobs and similar workloads.
Windows Server 2022 x86-64 runners are supported on Azure. The preinstalled software page lists the tooling on that image.
Resource tagging is listed as coming soon in the Azure configuration docs, so plan cost attribution on the subscription or resource group boundary for now.
Workflow YAML
A BYOC runner is referenced by its full Runner ID. A single workflow can mix BYOC labels with hosted ones, which is how most teams handle macOS while their Linux and Windows fleets run in Azure.
name: ci
on:
push:
branches: [main]
jobs:
build-linux:
# The full Runner ID, including the warp-custom- prefix, is the label
runs-on: warp-custom-azure-eastus-linux-8x
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- run: npm run build
test-windows:
runs-on: warp-custom-azure-eastus-win-4x
steps:
- uses: actions/checkout@v4
- run: dotnet test --configuration Release
package-ios:
runs-on: warp-macos-latest-arm64-6x
steps:
- uses: actions/checkout@v4
- run: xcodebuild -scheme App -destination 'generic/platform=iOS' buildFor a staged cutover, put the label behind a repository variable. The workflow keeps running on a WarpBuild-hosted runner until the Azure stack is ready, and the switch is one variable edit with no pull request.
jobs:
test:
runs-on: ${{ vars.LINUX_RUNNER || 'warp-ubuntu-latest-x64-4x' }}
steps:
- uses: actions/checkout@v4
- run: make testSet LINUX_RUNNER to warp-custom-azure-eastus-linux-8x when the stack is verified, and clear the variable to roll back.
Automation
Terraform support exists for BYOC on AWS. Azure stacks are created through the dashboard flow described above.
Who Manages What
The split below is the operating agreement for a BYOC Azure fleet.
| Area | WarpBuild | Your Azure subscription |
|---|---|---|
| Runner lifecycle: create, register with GitHub, terminate | Managed by WarpBuild | Nothing to run |
| Runner images and preinstalled software | Built and updated by WarpBuild | Nothing to build |
| Entra consent for the WarpBuild CI Enterprise application | Requests the consent | Privileged Role Administrator approves it |
| Stack resources: virtual network, subnets, storage account and container | Provisioned through the connection | Owned by you, billed to you |
| Region choice and the immutable stack name, storage container, and region | Enforces immutability after creation | Chosen by you at creation |
| Quota increases in the stack region | Advises the numbers | Requested and approved in Azure |
| Runner minutes and compute charges | $0.002 per BYOC runner minute | VM, disk, IP, and storage billed directly by Azure |
| Instance type priority list and spot selection | Configuration surface in the dashboard | Sizes and spot policy chosen by you |
| Cache, container layer cache, and telemetry data | Written by the runner | Stored in your storage container |
| Deletion order: runners, then stack, then connection | Blocks deletes with dependents | Executed by you |
| Support and incident response | [email protected] | Azure support for subscription-level issues |
Cost model
BYOC changes the shape of the bill: WarpBuild fees drop to a flat per-minute rate and the compute moves onto your Azure invoice, where your own reserved capacity and spot pricing apply. WarpBuild rates come from the pricing page.
Your BYOC total depends on the Azure machine types, regions, and purchasing model you choose. Work the arithmetic below against your own Azure prices and measured job duration.
| Line item | Rate | Clouds |
|---|---|---|
| BYOC Linux runners | $0.002 per minute | AWS, GCP, Azure |
| BYOC Windows runners | $0.002 per minute | AWS, Azure |
| Add-ons on BYOC | Included | AWS, GCP, Azure |
Work a concrete month. Take 100,000 GitHub Actions minutes on a 4 vCPU, 16 GB Linux job. GitHub lists its 4-core Linux larger runner at $0.012 per minute and its 4-core Windows larger runner at $0.022 per minute on the Actions minute multipliers reference (see also GitHub pricing), both checked on 2026-08-13.
| Option | Rate billed by the runner vendor | 100,000 minutes | Compute billed by Azure |
|---|---|---|---|
| GitHub-hosted 4-core Linux larger runner | $0.012 per minute | $1,200 | None; GitHub bills the compute |
| warp-ubuntu-latest-x64-4x, WarpBuild hosted | $0.008 per minute | $800 | None; WarpBuild bills the compute |
| BYOC Linux runner on Azure | $0.002 per minute | $200 | VM, disk, IP, and storage on your invoice |
The same month on Windows, at 20,000 minutes of a 4 vCPU, 16 GB job:
| Option | Rate billed by the runner vendor | 20,000 minutes | Compute billed by Azure |
|---|---|---|---|
| GitHub-hosted 4-core Windows larger runner | $0.022 per minute | $440 | None; GitHub bills the compute |
| warp-windows-latest-x64-4x, WarpBuild hosted | $0.016 per minute | $320 | None; WarpBuild bills the compute |
| BYOC Windows runner on Azure | $0.002 per minute | $40 | VM, disk, IP, and storage on your invoice |
The break-even is arithmetic you can run against your own Azure rate card. For the Linux example, BYOC comes out ahead of the WarpBuild-hosted 4 vCPU runner when the all-in Azure cost of that VM stays under $0.006 per minute, which is $0.36 per VM hour including disk, IP, and storage. Against GitHub's 4-core larger runner the threshold is $0.010 per minute, or $0.60 per VM hour. Price the VM sizes on your priority list in East US, add the disk and storage lines, and compare against those two thresholds before committing to a stack.
Two costs are easy to forget in that model. The storage account and container accumulates cache and telemetry data, so budget its storage and request charges. And enabling static IPs places runners in private subnets behind NAT, which adds data transfer and processing charges to the traffic a job pulls; leave static IPs off unless a third-party allowlist requires a fixed egress IP.
The WarpBuild side of the bill stays simple whatever the split.
Compliance and proof
Because BYOC keeps job execution and cache data inside your own subscription, the audit surface your security team reviews is mostly your own: your network, your storage account, your role assignments, plus the Entra consent granted to the WarpBuild CI Enterprise application.
Start with the Azure BYOC setup docs, size the stack against the quota table above, and check the pricing page for current per-minute rates. If Azure is one of several clouds in play, the same model is documented for BYOC on AWS, where Terraform support exists, and for BYOC on GCP.
FAQ
Which Azure regions can I create a BYOC stack in?
BYOC Azure is currently enabled for East US only. For additional regions, reach out to [email protected]. The region cannot be changed after the stack is created, so a second region means a second stack.
Can I use Terraform to set up BYOC on Azure?
No. Terraform support exists for BYOC on AWS. Azure setup runs through the dashboard in three steps: cloud connection, stack, and custom runner.
Do snapshot runners work on BYOC Azure?
No. Snapshot-based runners are not available for BYOC Azure. Keep snapshot workloads on WarpBuild-hosted Linux runners and run the rest of the pipeline on your Azure subscription.
What does WarpBuild charge for BYOC runners on Azure?
BYOC Linux and Windows runners cost $0.002 per minute in WarpBuild fees, and Azure bills the VM, disk, IP, and storage to your subscription.
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.