Replacing self-hosted agents with ephemeral pipelines agents in Azure DevOps

Cover image

Schema of sample architecture using ephemeral agents

If you have Azure Resources that aren't exposed on the internet but only accessible via a private network, you can't use Microsoft-hosted agents because they can't connect to the private network. Therefore, we need to maintain a pool (or several pools) of self-hosted agents, with the associated costs and effort to maintain that pool(s).

In this case it is where Ephemeral pipelines agents come into action.

Overview

Ephemeral pipelines agents come to eliminate the need to use and maintain pools of self-hosted agents for deployment purposes.
This type of agents are capable to deploy to private azure resources. The process is not very complex. Ephemeral pipelines agents run in an Azure Container Instance (ACI) with access to the private network where the other Azure resources are. The agents are created to run a pipeline job and then deleted to avoid extra costs and resources consumption.

This way, we can deploy to private Azure resources without having to expose them on the internet or having to maintain self-hosted agents on the same (or with access) virtual network (with their associated costs and cons).

The agent that runs in the ACI its only a basic Docker image with the necessary dependencies to run the agent and to be capable to deploy to our private resources. For example, a base Ubuntu image with the necessary dependencies and the deploy agent installed.


🚨🚨 Edit 25/02/2023🚨🚨: the original project appears to be discontinued and archived by Microsoft. So it will no longer be maintained... We will have to look for other solutions such as allowing temporal access from agents to private resources or deploying self-hosted agents from a docker image by our own.

TL;DR: The purpose of this task is to create a short-lived Azure Pipelines Agent to run a deploy in a private virtual network so we can deploy to Azure Resources that are not internet accessible.

⚠️ Important: This approach (and task) is currently in preview and has known issues and limitations. Please take this into account before proceeding to use this process.

How does the process works

Only three steps/requirements:

  1. One docker image that can run a deploy agent in a container (needed to provision agents).

  2. Provision one ephemeral pipeline agent to run the deployment job. This process can be done using this task. This task provisions, configures and registers an agent on an ACI using the docker image mentioned in the first step.

  3. The container runs one pipeline job, and then it unregisters the agent and deletes the container (it self destructs).

So considering we have setup a docker image that can run a deploy agent in a container, our pipeline will look like this:

Example pipeline with ephemeral agents

Example pipeline with ephemeral agents

As you can see, two jobs are needed:

Tutorial

In this post I will guide you through a simple tutorial on how to deploy assets on a container in an Azure Storage account in a private virtual network, using Ephemeral pipeline agents.

So let's get started!

Requirements:

Overview of the resources

For this tutorial I have created two resource groups:

Resource group for vnet and security group

Resource group for the VNet and security group

Resource group for ACR and Storage account

Resource group for the ACR and Storage account

Also, the Azure Storage account should be in the private network, with a configuration similar to this one:

Azure Storage Account VNet configuration

Azure Storage Account VNet configuration

If you need it, the main repo of ephemeral agents has sample scripts on how to deploy these resources.

Pushing the base image for ephemeral agents

Once finished configuring our resources in Azure, we will need the base image to use with the ephemeral agents.
In this case I have used the Agent Images available in the GitHub repo, specifically the Ubuntu one. We can use the pipeline in the GitHub repo to deploy our Agent image in the ACR (using an ACR Service connection).

After that, we should have one repository with one image in our ACR:

ACR with Agent Image

ACR with sample Agent Image based on Ubuntu

Setting up the pipeline in Azure DevOps

After creating the needed resources and pushing the Agent Image to the ACR, we are ready to create our pipeline and use ephemeral agents to deploy.

First of all, we will need to create an additional agent pool in our Project, and grant access to all pipelines.

Permissions:

For this process we will need to give specific permissions in order to allow the pipeline to register agents in the new pool, running jobs in these agents and unregister them.

In order to register the agent a token with sufficient permissions on the Azure DevOps Organization the agent is going to be registered is needed.

You can use two different types of tokens: a Personal Access Token or an OAuth token (recommended).

If using the OAuth token, you need to met the following conditions:

In this example, permissions on the pool (for the OAuth token approach) will look like the following:

Pool permissions for OAuth token

Pool permissions for OAuth token

Additional considerations:

You must register an Azure Resource provider for the namespace Microsoft.ContainerInstance in order to create container instances for the agents. This can be done easily opening a Powershell instance in the Azure portal and executing the following command:

Register-AzureRmResourceProvider -ProviderNamespace 'Microsoft.ContainerInstance'

This will register the needed Azure Resource provider.

Service connections:

We will need a Service connection using a Service principal, which has to have access to the VNet resource group and the ACR and Storage Account resource group. We can set it up in the project settings in Azure DevOps, granting permissions to one resource group and then going to the Azure Portal to grant permissions to the another one. Make sure to grant permissions to all pipelines.

Also, as mentioned above we will need an ACR Service Connection to our ACR to run the ephemeral agents in the ACI from the Agent Image in the ACR (granting permissions to all pipelines).

Pipeline definition:

In this part of the process two pipelines are created for my sample project, one for creating the base image for the agents in the ACR (which we have previously created), and another one for the main deploy process of our project.

Two main pipelines defined

Pipelines defined in our projects

The main deploy pipeline used in this tutorial is the same defined in the GitHub repo sample. As we have seen in the previous stages, we have to define two jobs: one to provision the agent and another one to perform the deploy job.

Configure the variables in the sample pipeline to reference your resources correctly and then try to run it:

Pipeline preparing the agent in the first job

Pipeline preparing the agent in the first job

If we have configured everything correctly, the pipeline will succeed:

Final pipeline result

Final pipeline result

If we inspect our created agent pool, we will see the executed job but no agents registered in the pool (which is the main purpose of this process). This is because the agent has unregistered itself when the deployment job finished.

Pool executed job

Pool executed job

Final result:

After the deploy pipeline execution, we can check how we successfully have deployed our assets to the Azure Storage container connected to the private virtual network:

Deployed assets on Azure Storage container inside the VNet

Deployed assets on Azure Storage container inside the VNet

Conclusion

We have seen how ephemeral pipelines agents works, how to replace self-hosted agents with ephemeral ones and the most important part: how to reduce maintenance costs of having our own self-hosted agents pool(s).

It is important to emphasize that this process its currently in preview, so maybe some things just do not work out of the box, but I personally think its an excellent approach to avoid having self-hosted agents in the mentioned situations.

Happy deploy! 🎉🎉

Sources:

  1. GitHub of Microsoft Azure Pipelines ephemeral agents. (2020, March 15)
  2. Microsoft docs: Azure Pipelines agents. (2020, March 15)
  3. Ephemeral Pipelines Agents extension. (2020, March 15)

🙏🙏🙏

Since you've made it this far, sharing this article on your favorite social media network would be highly appreciated 😀! For feedback, please ping me on Twitter.

Published