Azure Managed DevOps Pools make life easier
07 Mar 2025
Azure Managed DevOps Pools is a new service that allows Azure customers to provision privately networked Azure Pipelines agents that Microsoft automatically keeps at feature/fix parity with their public equivalents.
This is awesome, because you used to have to be a server administration and containerization expert to run privately networked CI/CD pipelines in Azure DevOps (“ADO”)!
Problem: managed Microsoft-hosted agents are public
Microsoft-hosted agents enable Azure Pipelines to automatically build code stored in Azure Repos into runnable artifacts.
However, because they exist on the public internet, their (rapidly changing and widely shared) IP addresses are forbidden from deploying those artifacts into privately networked target runtimes, such as:
- on-prem servers
- privately networked Azure App Service instances.
Problem: private self-hosted agents are unmanaged
Self-hosted agents enable Azure Pipelines to deploy built artifacts into privately networked target runtimes, but:
- they are difficult to provision, configure, and maintain to acceptable security, reliability, and availability standards.
- they do not come with the rich feature set of Microsoft-hosted agents, so they cannot build any codebases that have not been thought out in advance.
- (Do your developers want to build from a .NET 8 codebase? Too bad for them if you forgot to install anything but a .NET 6 SDK onto your self-hosted agent.)
Solution: private managed agent pools
Luckily, the Microsoft team that produces Microsoft-hosted agents found that Microsoft’s internal developers were also struggling with self-hosted agent challenges above.
(In fact, on RunAsRadio podcast episode #972, Eliza Tarasila shared that one self-hosted agent was even found under a developer’s desk!)
Five years ago, they created Azure Managed DevOps Pools in response.
Two years ago, they started working on making it a public service, and in November of 2024, it became generally available to all Azure customers.
Implementation tips
Azure resource type: Microsoft.DevOpsInfrastructure/pools.
Publicly networked by default. To provision one into a privately networked subnet:
- Specify an Azure VNET subnet’s resource ID for the
VmssFabricProfile.networkProfile.subnetIdproperty of yourMicrosoft.DevOpsInfrastructure/poolsresource.- You want the subnet hosting your Managed DevOps Pool to be able to reach the subnet hosting your deployment-target runtime (e.g. Azure App Service, an on-prem server).
- This is easier said than done if you have no idea how to set up networking in Azure. That’s why I haven’t yet published an example! Coming soon, I hope. 😅
- Presumably, someone at your company does know how, and can provide an appropriate subnet resource ID for your Managed DevOps Pool.
- When you register the
Microsoft.DevOpsInfrastructureAzure resource provider, Microsoft automatically provisions a service principal named “DevOpsInfrastructure” into your Entra ID tenant.- You need to make it the principal of some Azure RBAC role assignments that are target-scoped against the Azure virtual network serving as a parent to your Managed DevOps Pool’s subnet.
- Otherwise, your Managed DevOps Pool won’t be able to join its intended subnet.
Identity and access control limitation
10/12/26 update:
Sadly, Managed DevOps Pools only solve Azure Pipelines agents’ “line of sight” problems at a network level.
If your Azure Pipelines agent just needs an identity & access control line of sight to an Entra tenant, then Azure Pipelines’s notion of an ARM Service Connector can use OIDC credential federation to let the an Azure Pipelines agent’s underlying machine “become” an Entra Service Principal – easy-peasy, no matter whether you’re using a Managed DevOps Pool or self-hosting your Azure Pipelines agent’s compute.
- And that’s enough to get you into Azure Key Vault, so if the code that you’d like to run on an Azure Pipelines Agent simply needs to know the username and password for, say, a User-typed Active Directory principal, you’re probably still fine.
But if the code that you’d like to run on an Azure Pipelines agent also needs the machine serving as the “agent” to, say, be a Device-typed principal in an older identity and access provider like Active Directory, then you’re possibly still going to have to self-host the compute for your Azure Pipelines agent.
Managed image
Having to stick with self-hosting your Azure Pipelines agent’s VM (on a machine whose operating system & installed software you have to patch) is a bummer, because Managed DevOps Pools puts the burden of patching the agent’s operating system & preinstalled software onto Microsoft.
I mean, once you’re having to install manage the self-hosted VM yourself, at that point, is there really even much of a noticeable difference between the “hello, Microsoft’s part of the internet! Do I have work to execute yet?” .exe process running on that VM is:
- the Azure Pipelines Agent
.exe, or - the Azure Automation Account Hybrid Runbook Worker
.exe?
- (Update: a colleague pointed out yes, there is! Of course, how did I forget? It’s at a business process / conceptual level. Azure Pipelines comes with Azure Pipeline Artifacts and the idea of “stages,” so that you can follow an “immutable artifacts” / “build once; deploy anywhere” approach to technical process automation.)
Stateless compute
Having to self-host is also a bummer, because with a long-lived VM serving as your self-hosted Azure Pipelines agent, you’ve got to worry about Job A from yesterday leaving behind crud in the agent VM’s environment variables, or Job A from yesterday overflowing the agent VM’s disk space, and consequently messing up the execution of Job B today. Whereas with a stateless Managed DevOps Pool, the compute ephemerally blinks into existence just in time to run an Azure Pipelines job, then auto-self-destructs once the job finishes executing.
- (I mean, maybe you’re amazing enough at AD-joined VM provisioning, configuration, and deprovisioning to, in-house, engineer something equally stateless & ephemeral for your self-hosting? But I imagine it’s kinda hard?)
Additional links
- Simplify Azure DevOps agent management with Managed DevOps Pools by John Lokerse
- Deploying in a Private Azure Environment using Managed DevOps Pools by Gora Leye
- A first look at using Azure Managed DevOps Pools by Richard Fennell
- Simplifying Build Farms with Managed DevOps Pools for Azure DevOps by Matteo Emili
- Managed DevOps Pools: Simplifying Azure DevOps Setup by Patrick de Kruijf
- GitHub.com docs: private networking with GitHub-hosted runners (an introduction to the equivalent technology over on the GitHub Actions side of Microsoft’s CI/CD platform house)