Azure Container Apps: Serverless Containers with Dapr and KEDA

Not every containerized workload deserves a Kubernetes cluster. AKS gives you full control and full responsibility: upgrades, node pools, ingress controllers, certificate plumbing. Azure Container Apps sits on Kubernetes internally but hides all of it, and for a large class of microservices, APIs, background processors, and event driven jobs, it is simply the better operational deal. You bring an image; the platform brings scaling, ingress, TLS, revisions, and service discovery.

Environment and App

resource "azurerm_container_app_environment" "this" {
  name                           = "cae-services-prod"
  location                       = "westeurope"
  resource_group_name            = azurerm_resource_group.apps.name
  log_analytics_workspace_id     = azurerm_log_analytics_workspace.central.id
  infrastructure_subnet_id       = azurerm_subnet.aca.id
  internal_load_balancer_enabled = true
  zone_redundancy_enabled        = true
}

resource "azurerm_container_app" "api" {
  name                         = "orders-api"
  container_app_environment_id = azurerm_container_app_environment.this.id
  resource_group_name          = azurerm_resource_group.apps.name
  revision_mode                = "Multiple"

  identity {
    type         = "UserAssigned"
    identity_ids = [azurerm_user_assigned_identity.orders.id]
  }

  registry {
    server   = azurerm_container_registry.this.login_server
    identity = azurerm_user_assigned_identity.orders.id
  }

  ingress {
    external_enabled = false
    target_port      = 8080
    traffic_weight {
      latest_revision = true
      percentage      = 100
    }
  }

  template {
    min_replicas = 1
    max_replicas = 30

    container {
      name   = "api"
      image  = "${azurerm_container_registry.this.login_server}/orders-api:1.4.2"
      cpu    = 0.5
      memory = "1Gi"
    }

    custom_scale_rule {
      name             = "sb-queue"
      custom_rule_type = "azure-servicebus"
      metadata = {
        queueName    = "orders"
        messageCount = "20"
        namespace    = "sbns-orders-prod"
      }
    }
  }
}

The scale rule is KEDA underneath: this app scales on Service Bus queue depth, one replica per twenty messages, up to thirty replicas. HTTP apps scale on concurrent requests by default. Set min_replicas to zero for true scale to zero on background processors, and to one or more for user facing APIs where a cold start is unacceptable.

Dapr: The Useful Sidecar

Container Apps has first class Dapr integration, and it is worth using for two building blocks in particular. Service invocation gives you mTLS and retries between apps with a simple localhost call to the sidecar, no service mesh to operate. Pub sub abstracts the broker: your code publishes to a topic through the Dapr API, and a component definition binds it to Service Bus today, or something else tomorrow, without code changes. State management similarly wraps Cosmos DB or Redis behind a key value API. The discipline required: treat Dapr components as part of your Terraform, scope each component to the apps that need it, and use managed identity in the component auth rather than connection strings.

Revisions and Safe Rollouts

Revision mode Multiple is the deployment superpower. Every template change creates an immutable revision, and traffic weights split between them: deploy 1.5.0 at ten percent, watch error rates in Log Analytics, shift to fifty, then a hundred, and keep the old revision warm for instant rollback by weight flip. It is canary deployment without Argo, Flagger, or any of the machinery you would maintain on AKS.

Where the Boundary with AKS Sits

Choose AKS when you need daemon style workloads, custom CRDs and operators, GPU scheduling nuance, privileged containers, or a service mesh you control. Choose Container Apps when the unit of thought is “a service that scales on load” rather than “a cluster I administer”. Plenty of platforms run both: AKS for the core, Container Apps for everything that does not justify cluster overhead. The wrong answer is running a three node AKS cluster to host four small APIs, and I see that wrong answer weekly.

Cheers
Osama

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.