Bringing technical clarity to the unknown

Azure Managed DevOps Pools make life easier

07 Mar 2025 🔖 azure devops security
💬 EN

Table of Contents

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:

  1. on-prem servers
  2. 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:

  1. they are difficult to provision, configure, and maintain to acceptable security, reliability, and availability standards.
  2. 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:

  1. Specify an Azure VNET subnet’s resource ID for the VmssFabricProfile.networkProfile.subnetId property of your Microsoft.DevOpsInfrastructure/pools resource.
    • 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.
  2. When you register the Microsoft.DevOpsInfrastructure Azure resource provider, Microsoft automatically provisions a service principal named “DevOpsInfrastructure” into your Entra ID tenant.

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:

  1. the Azure Pipelines Agent .exe, or
  2. 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?)
--- ---