
Table of Contents
By Khimananda Oli | Last reviewed: August 2026
Microsoft-hosted runners are convenient but often fail compliance audits requiring private networking or specific toolchains. Self-hosted Azure DevOps agents solve this by executing pipeline jobs on infrastructure you fully control, whether on-premises in Kathmandu or in a private AWS VPC. This guide covers the practical setup, security hardening, and operational trade-offs needed to run them reliably in production.
How do you install and configure self-hosted Azure DevOps agents?
The agent is a lightweight .NET Core application that polls Azure Pipelines for work. Installation takes under ten minutes on Ubuntu 22.04/24.04 or Windows Server 2022. Before starting, ensure you have a Personal Access Token (PAT) scoped to Agent Pools (read, manage) and that the target machine can reach dev.azure.com over HTTPS.
Step-by-step Linux installation
- Create a dedicated service account. Never run the agent as root in production.
- Download the latest agent package from your organization’s agent pool page.
- Extract, configure interactively once to validate credentials, then install as a systemd service.
- Verify the agent appears online in the Azure DevOps portal before queuing builds.
# Create service user
sudo useradd -m -s /bin/bash azagent
# Download and extract (verify version on your org's download page)
mkdir /opt/azagent && cd /opt/azagent
curl -O https://vstsagentpackage.azureedge.net/agent/3.241.0/vsts-agent-linux-x64-3.241.0.tar.gz
tar zxvf vsts-agent-linux-x64-3.241.0.tar.gz
chown -R azagent:azagent /opt/azagent
# Interactive configuration (run as azagent user)
sudo -u azagent ./config.sh \
--url https://dev.azure.com/YOUR_ORG \
--auth pat \
--token YOUR_PAT_TOKEN \
--pool Default \
--agent ubuntu-prod-01 \
--acceptTeeEula
# Install and start as systemd service
sudo ./svc.sh install azagent
sudo ./svc.sh start azagent
sudo ./svc.sh status azagent A common mistake is skipping the interactive validation step. If your PAT lacks the correct scope or the agent name conflicts with an existing registration, config.sh will fail silently during service install. Always confirm the agent shows "Online" in the portal before proceeding. For teams managing multiple agents, consider automating this with Ansible playbooks as described in automating server setup with Ansible.
When should you use self-hosted agents instead of Microsoft-hosted runners?
Microsoft-hosted runners are ephemeral VMs managed entirely by Azure. They’re ideal for open-source projects or workloads with no private dependencies. Self-hosted agents become necessary when your requirements exceed what shared infrastructure can provide. The decision isn’t about preference—it’s about constraints.
| Criteria | Microsoft-Hosted | Self-Hosted Azure DevOps Agents |
|---|---|---|
| Private network access | Not available | Full VPC/on-prem access |
| Custom toolchains | Limited to pre-installed | Any software, any version |
| Compliance (SOC 2, ISO 27001) | Shared tenant concerns | Isolated, auditable infra |
| Build caching / artifacts | Ephemeral, no persistence | Persistent disk, local caches |
| Cost at scale | Per-minute billing adds up | Fixed VM cost, higher utilization |
| Maintenance burden | Zero | Patching, updates, monitoring |
| Cold start time | 30–90 seconds | Near-instant (warm pool) |
In practice, most teams I work with adopt a hybrid model: Microsoft-hosted for PR validation and public-facing builds, self-hosted for deployment pipelines, integration tests against staging databases, and any job touching internal APIs. This balances cost, security, and maintenance overhead. If you’re evaluating cloud providers for hosting these agents, comparing AWS, Azure, and GCP helps clarify which platform offers the best networking and pricing for your agent fleet.
How do you secure self-hosted Azure DevOps agents for production?
Running agents on your infrastructure means owning the attack surface. Treat every agent like a production server: hardened, monitored, and least-privilege. After years of audit preparation for SOC 2 and ISO 27001, these controls are non-negotiable.
- Service isolation: Run each agent under a dedicated non-root user with no shell access beyond the agent directory.
- PAT rotation: Use short-lived PATs (30–90 days) stored in HashiCorp Vault or Azure Key Vault, never in plaintext config files. Automate rotation via API.
- Network egress filtering: Allow outbound only to
dev.azure.com,*.vsblob.vsassets.io, and your internal artifact feeds. Block all other egress. - Immutable base images: Rebuild agent VMs monthly from golden images rather than patching in place. This prevents configuration drift and simplifies audit evidence collection.
- Workspace cleanup: Configure
clean: truein pipeline YAML or set the agent’sVSTS_AGENT_CLEAN_WORKSPACEenvironment variable to prevent secret leakage between jobs.
For secrets management specifically, integrating HashiCorp Vault eliminates static credentials entirely. Agents fetch dynamic secrets at job runtime, reducing blast radius if a build is compromised. See secrets management with HashiCorp Vault for implementation patterns that work well with Azure Pipelines.
How do you scale and maintain self-hosted Azure DevOps agents efficiently?
A single agent handles one job at a time. At scale, you need autoscaling, health monitoring, and automated recovery. Manual agent management doesn’t survive past five machines.
Autoscaling strategies
For containerized workloads, deploy agents as Kubernetes pods using the official Azure DevOps Agent Helm chart. Scale based on queue depth using KEDA with the Azure Pipelines scaler. For VM-based agents, use Azure Virtual Machine Scale Sets or AWS Auto Scaling Groups with a custom metric derived from the Azure DevOps REST API’s queue length endpoint.
# Example: Check pending jobs via Azure DevOps REST API
curl -s -H "Authorization: Bearer $PAT" \
"https://dev.azure.com/YOUR_ORG/_apis/distributedtask/pools/Default/jobrequests?api-version=7.0" \
| jq '[.value[] | select(.result == null)] | length' Monitoring and alerting
Agents expose health via the Azure DevOps UI, but that’s insufficient for production. Monitor these metrics locally and ship to your observability stack:
- Agent process uptime and restart count
- Disk usage in
_workdirectory (alert at 80%) - Job duration outliers (detect stuck builds)
- Failed authentication attempts (indicates PAT expiry or misconfiguration)
Prometheus node_exporter plus a custom script parsing _diag logs gives you actionable signals. Pair this with Grafana dashboards as outlined in monitoring with Prometheus and Grafana to correlate agent health with pipeline throughput.
Operational checklist for self-hosted Azure DevOps agents
Before marking your agent pool production-ready, verify these items. Missing even one has caused failed audits and midnight incidents in environments I’ve reviewed.
- Agent runs as non-root with workspace cleanup enabled
- PAT stored in secrets manager, rotated automatically, scoped minimally
- Outbound firewall allows only required Azure DevOps endpoints
- Base image rebuilt monthly; configuration managed via IaC
- Monitoring covers process health, disk, job duration, and auth failures
- Disaster recovery documented: how to rebuild entire pool from code in under 30 minutes
- Audit trail captures agent provisioning, config changes, and secret access
Running self-hosted Azure DevOps agents securely at scale
Self-hosted Azure DevOps agents give you control that Microsoft-hosted runners cannot match, but that control demands discipline. Start with a small, well-monitored pool. Automate provisioning and secret rotation early. Treat agents as production infrastructure, not disposable build boxes. When configured correctly, they become the foundation of compliant, high-throughput CI/CD that passes audits and survives traffic spikes. If your team needs help designing or hardening an agent fleet, reach out to discuss your specific requirements.