Carlos Sura

How to run Azure DevOps self-hosted agents on Azure Container Instances (ACI)

When configuring custom build environments for Azure DevOps Pipelines, running full Virtual Machines (VMs) for self-hosted agents can introduce unnecessary infrastructure maintenance and costs. Instead of provisioning and maintaining full VMs, you can deploy self-hosted pipelines agents on Azure Container Instances (ACI) backed by Azure Container Registry (ACR).

Using ACI allows you to rapidly spin up Windows or Linux containerized agents, assign public or private IPs, execute build jobs in isolated environments, and tear them down on demand.


Prerequisites

Before starting, ensure you have:

  • An active Azure Subscription.
  • An Azure Container Registry (ACR) instance.
  • Azure CLI installed and authenticated (az login).
  • Docker installed (configured for Windows containers if deploying Windows core images).
  • An Azure DevOps Organization (https://dev.azure.com/).
  • An Azure DevOps Personal Access Token (PAT) with Agent Pools (Read & Manage) permissions.
  • An existing Agent Pool in Azure DevOps (e.g., Default or a custom pool).

Create the Dockerfile

Below is a Windows Server Core Dockerfile configured to download and extract the official Azure DevOps pipelines agent package.

FROM mcr.microsoft.com/windows/servercore:ltsc2022

SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]

ARG AGENT_VERSION="3.X"
WORKDIR C:/azp

RUN Invoke-WebRequest -Uri "https://vstsagentpackage.azureedge.net/agent/${AGENT_VERSION}/vsts-agent-win-x64-${AGENT_VERSION}.zip" -OutFile agent.zip; \
    Expand-Archive -Path agent.zip -DestinationPath . ; \
    Remove-Item agent.zip

COPY start.ps1 C:/azp/start.ps1

ENTRYPOINT ["powershell", "-File", "C:/azp/start.ps1"]

Create the Startup Script (start.ps1)

The entrypoint PowerShell script configures the agent against your Azure DevOps organization and agent pool, using environment variables passed during container creation, then launches the agent runner.

$ErrorActionPreference = "Stop"

if (-not $env:AZP_URL) {
    Write-Error "AZP_URL environment variable is missing."
    exit 1
}

if (-not $env:AZP_TOKEN) {
    Write-Error "AZP_TOKEN environment variable is missing."
    exit 1
}

$agentPool = if ($env:AZP_POOL) { $env:AZP_POOL } else { "Default" }
$agentName = if ($env:AZP_AGENT_NAME) { $env:AZP_AGENT_NAME } else { "aci-agent-$(hostname)" }

Set-Location C:\azp

# Configure the Azure DevOps Pipelines agent
.\config.cmd --unattended `
  --url "$env:AZP_URL" `
  --auth PAT `
  --token "$env:AZP_TOKEN" `
  --pool "$agentPool" `
  --agent "$agentName" `
  --replace `
  --acceptTeeEula

# Run the agent worker process
.\run.cmd

Tip: If you want the container to execute a single job and exit, you can append –once to .\config.cmd.


Build and Push Image to Azure Container Registry (ACR)

Authenticate to your ACR instance, tag your built agent image, and push it:

# Login to ACR
az acr login --name <your-acr-name>

# Tag local image
docker tag azp-agent-win:latest <your-acr-name>.azurecr.io/azp-agent-win:latest

# Push to ACR
docker push <your-acr-name>.azurecr.io/azp-agent-win:latest

Deploy the Agent on Azure Container Instances (ACI)

Deploy your agent container to Azure using az container create. Using –secure-environment-variables ensures sensitive credentials such as your PAT token are protected and hidden in Azure Resource Manager logs.

az container create `
  --resource-group myACIRunnersRG `
  --name azp-runner-win-01 `
  --image <your-acr-name>.azurecr.io/azp-agent-win:latest `
  --registry-login-server <your-acr-name>.azurecr.io `
  --registry-username <acr-username> `
  --registry-password <acr-password> `
  --os-type Windows `
  --cpu 2 --memory 4 `
  --environment-variables AZP_URL=https://dev.azure.com/<your-organization> AZP_POOL=Default AZP_AGENT_NAME=aci-win-agent-01 `
  --secure-environment-variables AZP_TOKEN=<your-azure-devops-pat> `
  --ip-address Public `
  --restart-policy Never `
  --location <location>

Running Azure DevOps self-hosted agents on Azure Container Instances gives you a lightweight, cost-effective, and fully isolated environment for build and deployment tasks without the overhead of maintaining persistent Virtual Machines.


References