Azure Container Services Comparison – Part 2: Deep Dive Implementation & Code Examples

Azure Container Services Comparison – Part 2: Deep Dive Implementation & Code Examples

This entry is part 2 of 5 in the series Azure Container Services Comparison

Azure Container Services Comparison: Container Apps vs Container Instances vs AKS

Part 2: Deep Dive Implementation & Code Examples

In Part 1, we covered the conceptual differences between Azure’s container services. Now let’s get our hands dirty with real implementations, code examples, and practical scenarios that will help you understand exactly how each service works in practice.

Azure Container Instances: Quick and Simple Deployments

Let’s start with the simplest scenario – deploying a web API using ACI.

Example 1: Simple Web API with ACI

# ARM Template for ACI deployment
{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "containerName": {
            "type": "string",
            "defaultValue": "my-web-api"
        }
    },
    "resources": [
        {
            "type": "Microsoft.ContainerInstance/containerGroups",
            "apiVersion": "2021-07-01",
            "name": "[parameters('containerName')]",
            "location": "[resourceGroup().location]",
            "properties": {
                "containers": [
                    {
                        "name": "web-api",
                        "properties": {
                            "image": "nginx:latest",
                            "ports": [
                                {
                                    "port": 80,
                                    "protocol": "TCP"
                                }
                            ],
                            "resources": {
                                "requests": {
                                    "cpu": 0.5,
                                    "memoryInGB": 1.0
                                }
                            }
                        }
                    }
                ],
                "osType": "Linux",
                "ipAddress": {
                    "type": "Public",
                    "ports": [
                        {
                            "port": 80,
                            "protocol": "TCP"
                        }
                    ]
                }
            }
        }
    ]
}

Deployment time: ~30 seconds
Configuration complexity: Minimal
Best for: Simple stateless applications, development environments

Example 2: Batch Processing Job with ACI

# Azure CLI command for batch job
az container create \
  --resource-group myResourceGroup \
  --name batch-processor \
  --image myregistry.azurecr.io/data-processor:latest \
  --restart-policy Never \
  --environment-variables \
    STORAGE_ACCOUNT=mystorageaccount \
    QUEUE_NAME=processing-queue \
  --cpu 2 \
  --memory 4 \
  --registry-login-server myregistry.azurecr.io \
  --registry-username myusername \
  --registry-password mypassword

Key Benefits: Perfect for one-off tasks, automatic cleanup when job completes, pay-per-second billing.

Azure Container Apps: Microservices Made Easy

Container Apps shines in microservices scenarios. Let’s build a complete example with multiple services.

Example 3: Microservices Architecture with Container Apps

# 1. Create Container Apps Environment
az containerapp env create \
  --name my-environment \
  --resource-group myResourceGroup \
  --location eastus

# 2. Deploy API Gateway Service
az containerapp create \
  --name api-gateway \
  --resource-group myResourceGroup \
  --environment my-environment \
  --image nginx:latest \
  --target-port 80 \
  --ingress external \
  --min-replicas 1 \
  --max-replicas 10 \
  --cpu 0.5 \
  --memory 1.0Gi

# 3. Deploy Internal User Service
az containerapp create \
  --name user-service \
  --resource-group myResourceGroup \
  --environment my-environment \
  --image myregistry.azurecr.io/user-service:v1 \
  --target-port 3000 \
  --ingress internal \
  --min-replicas 0 \
  --max-replicas 5 \
  --cpu 0.25 \
  --memory 0.5Gi

Container Apps YAML Configuration

properties:
  configuration:
    ingress:
      external: true
      targetPort: 80
      allowInsecure: false
    secrets:
    - name: database-connection
      value: "Server=myserver;Database=mydb;..."
    registries:
    - server: myregistry.azurecr.io
      username: myusername
      passwordSecretRef: registry-password
  template:
    containers:
    - image: myregistry.azurecr.io/my-app:latest
      name: main-app
      env:
      - name: DATABASE_CONNECTION
        secretRef: database-connection
      - name: ASPNETCORE_ENVIRONMENT
        value: "Production"
      resources:
        cpu: 0.5
        memory: 1Gi
    scale:
      minReplicas: 1
      maxReplicas: 10
      rules:
      - name: http-requests
        http:
          metadata:
            concurrentRequests: "10"

Key Benefits: Built-in service discovery, automatic HTTPS, Dapr integration, event-driven scaling.

Azure Kubernetes Service: Enterprise-Grade Control

AKS gives you the full power of Kubernetes. Here’s a complete microservices deployment.

Example 4: Complete AKS Deployment

# 1. Create AKS Cluster
az aks create \
  --resource-group myResourceGroup \
  --name myAKSCluster \
  --node-count 3 \
  --node-vm-size Standard_B2s \
  --enable-addons monitoring \
  --enable-cluster-autoscaler \
  --min-count 1 \
  --max-count 5

# 2. Get credentials
az aks get-credentials \
  --resource-group myResourceGroup \
  --name myAKSCluster

Kubernetes Deployment Manifest

apiVersion: apps/v1
kind: Deployment
metadata:
  name: user-service
  labels:
    app: user-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: user-service
  template:
    metadata:
      labels:
        app: user-service
    spec:
      containers:
      - name: user-service
        image: myregistry.azurecr.io/user-service:v1
        ports:
        - containerPort: 3000
        env:
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: connection-string
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 3000
          initialDelaySeconds: 5
          periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: user-service-svc
spec:
  selector:
    app: user-service
  ports:
  - port: 80
    targetPort: 3000
  type: ClusterIP
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: user-service-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: user-service
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

Performance Comparison: Real-World Scenarios

Scenario 1: E-commerce API Backend

MetricACIContainer AppsAKS
Cold Start Time10-15 seconds2-5 secondsInstant (pre-warmed)
Auto-scaling ResponseN/A30-60 seconds15-30 seconds
Max Concurrent RequestsLimited by instance10,000+ per replicaUnlimited (cluster capacity)
Setup Complexity (1-10)248

Scenario 2: Data Processing Pipeline

ACI Approach: Perfect for event-triggered batch jobs

# Triggered by Azure Function or Logic App
az container create \
  --name data-processor-$(date +%s) \
  --image myregistry.azurecr.io/data-processor:latest \
  --restart-policy Never \
  --environment-variables \
    INPUT_BLOB_URL=$1 \
    OUTPUT_CONTAINER=$2

Container Apps Approach: Event-driven scaling with KEDA

scale:
  minReplicas: 0
  maxReplicas: 20
  rules:
  - name: azure-servicebus
    custom:
      type: azure-servicebus
      metadata:
        queueName: processing-queue
        messageCount: '10'

AKS Approach: Custom operators and advanced scheduling

apiVersion: batch/v1
kind: Job
metadata:
  name: data-processor
spec:
  parallelism: 5
  completions: 100
  template:
    spec:
      containers:
      - name: processor
        image: myregistry.azurecr.io/data-processor:latest
        resources:
          requests:
            memory: "2Gi"
            cpu: "1000m"
      restartPolicy: Never
      nodeSelector:
        workload: compute-intensive

When Each Service Excels

Choose ACI When:

  • You need to run containers for short periods (minutes to hours)
  • Simplicity is more important than advanced features
  • You have unpredictable, sporadic workloads
  • Cost optimization for low-usage scenarios is critical

Choose Container Apps When:

  • Building modern microservices architectures
  • You need auto-scaling but want to avoid Kubernetes complexity
  • Event-driven applications are your primary use case
  • You want built-in service mesh capabilities (Dapr)

Choose AKS When:

  • You need specific Kubernetes features or ecosystem tools
  • Complex networking or security requirements exist
  • You’re modernizing existing Kubernetes applications
  • Your team has strong Kubernetes expertise

Coming Up Next

In Part 3, we’ll explore advanced scaling strategies, networking configurations, and security features that can make or break your production deployments. We’ll also dive into monitoring and observability patterns for each service.


These code examples show the practical differences between Azure’s container services. The choice often comes down to balancing simplicity with control – choose the service that matches your team’s expertise and your application’s complexity needs.

Navigate<< Azure Container Services Comparison: Container Apps vs Container Instances vs AKS – Part 1: Overview and Core DifferencesAzure Container Services Comparison – Part 3: Scaling, Networking & Advanced Features >>

Written by:

387 Posts

View All Posts
Follow Me :