Containers are making our life simple with “ Build once deploy anywhere “
It was fun to build images and run them on local or dev-test environments, but how to take them on the full cycle of creating the images, promoting them as an artifact from dev to production using Azure DevOps.
Challenges
- How to carry the artifact(container image) across environments without rebuilding the image again for each environment
- Not all the dev images qualify for production so cannot push the image to all the environment registries on the development stage.
- Rollback operations on any production release failures.
Here is one of the best practice I will be following for promoting the images from dev to higher environment by using environment-specific container registries
How can we achieve this from using Azure DevOps Pipelines and Azure Container Registry?
Let us build an image first using the Azure DevOps Pipeline
Build an Image using Azure DevOps Pipeline CI
steps:
- task: Docker@0
displayName: 'Build an image'
inputs:
azureSubscription: 'Azure'
azureContainerRegistry: '{"loginServer":"dvcontainersacr.azurecr.io", "id" : "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/ResourceGroup/providers/Microsoft.ContainerRegistry/registries/dvcontainersacr"}'
dockerFile: DockerSample/DockerSample/Dockerfile
Push the Image to Azure Container Registry using Azure DevOps Pipeline CI
steps:
- task: Docker@0
displayName: 'Push an image'
inputs:
azureSubscription: 'Azure Dev'
azureContainerRegistry: '{"loginServer":"dvcontainersacr.azurecr.io", "id" : "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/ResourceGroup/providers/Microsoft.ContainerRegistry/registries/dvcontainersacr"}
action: 'Push an image'
Prerequisite : Service connection to you Azure Container Registry and Azure Subscription is required
Promote a Image to different environment ACR’s
using Azure CLI we can perform this move here is the inline script, you can use a script file also.
az acr import \
--name myregistry \
--source aci-helloworld:latest \
--image aci-helloworld:latest \
--registry /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/sourceResourceGroup/providers/Microsoft.ContainerRegistry/registries/mysourceregistry
note: On the above mentioned sample subscription is under the same Azure Tenant.
more samples about external registries are available here
Promote the Image from one registry to other using Azure DevOps Release Pipeline
This step would move your image from the source registry to the destination registry.
Here is the full step YAML
steps:
- task: AzureCLI@2
displayName: 'Azure CLI '
inputs:
azureSubscription: 'Azure'
scriptType: batch
scriptLocation: inlineScript
inlineScript: |
az acr import \
--name myregistry\
--source aci-helloworld:latest \
--image aci-helloworld:latest \
--registry /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/sourceResourceGroup/providers/Microsoft.ContainerRegistry/registries/mysourceregistry
Service Connection(azureSubscription) used here should be of the destination registry.
Once the Promote Image step is added next steps are of deployments of your choice, I have chosen the app service for containers deployment
Once this step is added next steps are of deployments of your choice. I have chosen the app service for containers deployment
what happened to the Challenges?
These steps mentioned above would solve the challenges mentioned to a greater extend
- Build Image once using the CI
- Promote only the qualified images to higher environments
- Rollback to the last build image instantly with the previous release in Azure DevOps
Furthermore on App Service for Container supports Slot swapping which ensures draining of connections before swapping, this can be achieved by simply deploying to the prod slot rather than the prod app service itself.