Azure Container App - Traffic Splitting

October 13, 2024

Problem Statement

You have a web application running in Azure Container Apps, and you want to deploy a new version of the application. However, you want to ensure that the new version is stable and does not introduce any issues before fully rolling it out to all users. To achieve this, you want to perform a canary deployment, where a small percentage of traffic is routed to the new version while the majority of traffic continues to go to the existing version.

Traffic Splitting in AKS

In Azure Kubernetes Service (AKS), traffic splitting is typically achieved using service meshes like Istio or Linkerd, or by leveraging Kubernetes-native tools like Ingress controllers. These tools allow you to define routing rules that split traffic between different versions of your application. While powerful, setting up and managing these tools can be complex and requires a deep understanding of Kubernetes networking and service mesh concepts.

Traffic Splitting in Azure Container Apps

Azure Container Apps simplifies traffic splitting by providing built-in support for this feature. With Azure Container Apps, you can easily define traffic splitting rules directly in your application configuration, without the need for additional infrastructure or complex setups.

Use Case: Canary Deployment for a Web Application

Solution: Leveraging Labels and Revisions for Traffic Splitting

Azure Container Apps provides a powerful mechanism for managing application changes using revisions and labels. Revisions allow you to create immutable snapshots of your application, and labels enable you to manage and route traffic between these revisions.

Step-by-Step Implementation

  1. Create Initial Deployment, label new revision and set traffic weight for the label to 100%

    srinmantest.azurecr.io/bookstoreapi:v1 and srinmantest.azurecr.io/bookstoreapi:v2 are the images for the web application. Please change this to your image.
    First, deploy your initial version of the web application to Azure Container Apps.

    uami_id=$(az identity show --resource-group academorg --name acaacrpulluami --query id --output tsv)

    Assign AcrPull role for this identity to the ACR where the image is stored.

    
    az containerapp create --name bookstoreapi --resource-group academorg --environment academoenvw2con --workload-profile-name "Consumption" --image srinmantest.azurecr.io/bookstoreapi:v1 --target-port 5000 --ingress external --revisions-mode multiple --revision-suffix v1 --query properties.configuration.ingress.fqdn --registry-identity $uami_id --registry-server srinmantest.azurecr.io --min-replicas 1 --max-replicas 3    
    
    az containerapp revision label add --label stable --name bookstoreapi --resource-group academorg --revision bookstoreapi--v1 
    
    az containerapp ingress traffic set --name bookstoreapi --resource-group academorg --label-weight stable=100
    az containerapp revision list --name bookstoreapi --resource-group academorg -o table
    
  2. Deploy New Version

    Deploy the new version of your web application. This will create a new revision.

    az containerapp update --name bookstoreapi --resource-group academorg --image srinmantest.azurecr.io/bookstoreapi:v2 --min-replicas 1 --max-replicas 3 --revision-suffix v2 
    az containerapp revision label add --label canary --name bookstoreapi --resource-group academorg --revision bookstoreapi--v2
  3. List Revisions

    List the revisions to get the names of the current and new revisions.

    az containerapp revision list --name my-web-app --resource-group my-resource-group --query "[].{name:name, active:active}" -o table
    az containerapp revision list --name bookstoreapi --resource-group academorg 
    az containerapp revision list --name bookstoreapi --resource-group academorg -o table
  4. Configure Traffic Splitting

    Split the traffic between the stable and canary revisions. For example, route 90% of the traffic to the stable version and 10% to the canary version.

    az containerapp ingress traffic set --name my-web-app --resource-group my-resource-group --traffic-weight stable=90 canary=10
    az containerapp ingress traffic set -n bookstoreapi -g academorg --label-weight stable=90 canary=10
  5. Monitor and Validate

    Monitor the performance and stability of the canary revision using Azure Monitor or Application Insights. Ensure that the new version is functioning correctly and does not introduce any issues.

  6. Gradually Increase Traffic

    If the canary revision is stable, gradually increase the traffic to the canary revision until it receives 100% of the traffic.

    az containerapp ingress traffic set --name my-web-app --resource-group my-resource-group --traffic-weight stable=50 canary=50
    az containerapp ingress traffic set --name my-web-app --resource-group my-resource-group --traffic-weight stable=0 canary=100
    az containerapp ingress traffic set -n bookstoreapi -g academorg --label-weight stable=50 canary=50
    az containerapp ingress traffic set -n bookstoreapi -g academorg --label-weight stable=0 canary=100
    
    
  7. Promote Canary to Stable

    Once the canary revision is fully validated, promote it to the stable label. Label swap helps with this.

    az containerapp revision label swap --name bookstoreapi --resource-group academorg --source canary --target stable
  8. Deactive old revision

    Old revision is not needed anymore. Deactivate it.

    az containerapp revision deactivate --name bookstoreapi --resource-group academorg --revision bookstoreapi--v1

Conclusion

By leveraging labels and revisions in Azure Container Apps, you can effectively manage application changes and perform canary deployments with traffic splitting. This approach allows you to gradually roll out new versions of your application, monitor their performance, and ensure stability before fully deploying them to all users. This method simplifies the deployment process and reduces the risk of introducing issues in production.


Profile picture

Written by Sridher Manivel Based out of Charlotte, NC. Linkedin