Configure CI/CD for Azure Container Instances using Azure / Azure DevOps Pipelines

Containers are fast becoming the preferred way to package, deploy, and manage cloud applications. Azure Container Instances offers the fastest and simplest way to run a container in Azure, without having to manage any virtual machines and without having to adopt a higher-level service.

Azure Container Instances is a great solution for any scenario that can operate in isolated containers, including simple applications, task automation, and build jobs. Also, Azure Container Instances supports the deployment of multiple containers onto a single host by using a container group aka pods in terms of Kubernetes. Multi-container container groups or Pods are useful when building an application sidecar for logging, monitoring, or any other configuration where a service needs a second attached process.

In this blog post, we’ll create an ASP.NET Core App, containerize it and configure CI/CD for same using Azure Pipelines (or Azure DevOps pipelines).

This can be also be thought of as the follow-up on previous blog post where we learned steps to create Container Instances using .NET Core and Docker and deploy the same from Azure Portal. However, instead of using manual steps, we would now need to configure CI/CD pipelines for same. So the focus will be restricted to steps required for same.

Create a ASP.NET Core Web Application

For demo purpose, we have used the source code in one of the sample repositories provided by Microsoft at: https://github.com/MicrosoftDocs/pipelines-dotnet-core

It contains the sample .NET Core code along with few test cases and dockerfile to convert it into a docker image.

Upload the source code in Azure Repos

Before, we can do the build and release using Azure Pipelines, we’ll need to upload source code to Azure Repos. For steps on how to upload source code to Azure Repos using Git, refer here.

You can also choose to directly import source code into Azure Repos from GitHub.

Configure Continuous Build Pipeline

For this, go to the required Project in Azure DevOps and go to Azure Pipelines section. From there, we can create new Build Pipeline:

create a new build pipeline

We can choose to configure pipeline using YAML provided in the source repository itself or define our tasks in old fashioned way. Next few steps contains configuration for manual steps in the build configuration.

For this, we first need to start with an empty job while creating new pipeline. Let’s select agent pool as ‘Hosted Ubuntu 1604’ and provide a name for the pipeline:

Provide values for the pipeline name and hosted pool

Since our Dockerfile is very bare, we’ll first need to add steps to build and publish .NET Core image. Let’s go to add tasks and add 3 tasks for .NET Core: Build, Test and Publish.

For the Build task, provide values as below:

dotnet core build task configuration

For the Test task, provide values as below:

dotnet core test task configuration

For the Publish task, provide values as below:

dotnet core publish task configuration

We now need to add couple of tasks for docker build and push. Again, go to the list of tasks and add docker task twice: One for building image and second to publish image.

Configure docker build task as below:

configure task to build docker image

Thereafter, configure docker publish task as below:

configure task to publish docker image

You may choose to not use Azure Container Registry (ACR) and use a provider registry of your choice.

Once everything is configured, run the build pipeline, and it should get completed successfully:

Build Pipeline result summary for one of the test runs

Also, we should now be able to see the docker image created in the specified registry and repository:

view images stored in the azure container registry

Configure Continuous Release Pipeline

Now, in the Azure Pipelines section, we first need to go the release and then select ‘create a release pipeline’:

create a new azure release pipeline

Again, we need to start with an empty job so that we can adjust it as per our needs and provide a name for the release definition. For the purpose of demo, we have named release definition as dotnetcore-acr-cd.

Next, we need to add artifacts to our application. Since all we want to deploy is an docker image located in the ACR, select artifact type as the Azure Container Registry (ACR). It will ask for few other details such as name of the registry and name of the repository containing the docker image and you need to provide values specific to your environment:

add a azure container image type artifact

If you are using private or docker hosted repositories, you can instead select artifact type as ‘Docker Registry’ and provide appropriate values.

Next, we need to enable the continuous deployment trigger.

After this, we need to add our tasks in a stage. Note that there are no inbuilt tasks to deploy Azure Container Instances. Since we would be using azure cli for this purpose, we need to add azure cli task from the list:

add azure cli task from the list

Next, change the command to inline script and provide below command:

az container create –resource-group aci-rg –name aci-demo-app –image $(acrLoginServer)/pipelines-dotnet-core:latest –cpu 1 –memory 1 –registry-login-server $(acrLoginServer) –registry-username$(acrName) –registry-password $(acrPassword) –dns-name-label aci-demo-app –ports 80

Note that, we are supplying the values of Azure Container Registry and Authentication details using the variables in above command.

configure task for azure cli for acr deployment

Next, we need to save the release definition and create a release. If all goes fine, you would be able to see the release completed successfully:

release definition completion summary

Also, container instance should be view-able in the azure resources and you can access the same using the URI of the instance:

Access the dotnet core image using the ACI Url

9 thoughts on “Configure CI/CD for Azure Container Instances using Azure / Azure DevOps Pipelines

  1. You’ve added the artifact in your release pipeline, I’m not able to figure out what service connection should be. I’ve tried adding a kubernetes cluster service connection but it didn’t work. Just wanna know what type of service connection should it be. Thanks!

    Like

  2. Nice article! One question though, what if there is upfates in the repos and how does the container instance gets updated as well?

    Like

Leave a comment