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:
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:
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:
For the Test task, provide values as below:
For the Publish task, provide values as below:
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:
Thereafter, configure docker publish task as below:
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:
Also, we should now be able to see the docker image created in the specified registry and repository:
Configure Continuous Release Pipeline
Now, in the Azure Pipelines section, we first need to go the release and then select ‘create a 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:
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:
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.
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:
Also, container instance should be view-able in the azure resources and you can access the same using the URI of the instance:
Thanks for this clear explanation.
LikeLike
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!
LikeLike
It’s general azure service connection.
LikeLike
Can you please ellobarate what should i do if i use docker hub at last step?? which credentials should i use?
LikeLike
You should use the credentials to connect to docker hub.
LikeLike
Yes i get that but can you please add it to your article with an example. BTW great article
LikeLike
I understand and thanks for the appreciation. I’ll look into same.
LikeLike
I am working on liquibase ci/cd without maven.Can u help pls.
LikeLike
Nice article! One question though, what if there is upfates in the repos and how does the container instance gets updated as well?
LikeLike