top of page

Dapr in Azure Container Apps

  • Cyril Sahula
  • 4 days ago
  • 3 min read

Updated: 3 days ago



We decided to use Azure Container Apps as a managed Kubernetes platform because it offers everything we need for our project, with acceptable limitations. During the process, we realised that Microsoft includes managed Dapr as part of the service—and we decided to use it. Why? I explain below—and I still don't regret it.



What is Dapr?

Dapr (Distributed Application Runtime) is an open-source, portable runtime that helps developers focus on coding and delivering business value without dealing with platform complexity or requiring deep infrastructure knowledge.


Dapr usage case
Dapr showcase

It provides building blocks—such as service invocation, pub/sub messaging, state management, and bindings—for cloud-native development.

The key point? These features are available via standard HTTP or gRPC APIs, abstracting away the underlying infrastructure.

You don’t need to deeply integrate SDKs or libraries. Instead, your service talks to the Dapr sidecar over a local network interface, and Dapr handles the rest. That simplicity is both elegant and powerful.


Picture with Dapr building blocks
Components overview

Cloud-Agnostic for free

Being cloud-agnostic wasn’t our primary goal—but it turns out that Dapr gives us that capability almost for free. It decouples application logic from the underlying infrastructure.

Need a message broker? Use Dapr’s pub/sub API. Whether it’s backed by Azure Service Bus, Kafka, or Redis doesn't matter to the application. The same applies to state stores, secret management, and service discovery. This gives us the flexibility to adapt our infrastructure without touching application code.


Picture with shows blocks and connectable services
Overview of proxy blocks with services behind

Dapr Is Perfect When Managed

In a managed environment like Azure Container Apps, Dapr becomes almost invisible to developers. Azure takes care of provisioning, scaling, and running the Dapr sidecars. There’s no need to manage Kubernetes manifests, sidecar injection, or upgrades.

This “it just works” experience allows our developers to focus on building features, not managing infrastructure. For us, Dapr in ACA became a seamless DevOps-to-code boundary.


LIGHTWEIGHT SERVICES

In a traditional microservice architecture, each service often includes direct dependencies on external systems like Azure Key Vault, Azure Service Bus (or Kafka/RabbitMQ), Redis, and others. This leads to increased complexity, heavier containers, and tighter coupling. With Dapr, these concerns are abstracted behind a single, lightweight SDK. The Dapr sidecar handles integrations, allowing the microservice itself to remain lean, portable, and easier to maintain. The SDK is well-supported and actively maintained by a large, vibrant open-source community.


Dapr Can Be Risky When Unmanaged

Dapr is a powerful abstraction—but like any abstraction, it has trade-offs. Running Dapr in an unmanaged environment (such as raw Kubernetes) requires caution. The sidecar must be healthy and synchronized with your app. Misconfigurations, version mismatches, or sidecar issues can lead to subtle bugs or outages.

While Dapr’s tooling is improving, the operational complexity in unmanaged environments can outweigh the benefits. That’s why we only recommend using Dapr where it’s either fully managed or very well automated.


Dapr Moves Infrastructure Dependencies to DevOps

Traditionally, developers had to integrate directly with infrastructure services like queues, databases, or caches. Dapr flips that model. Developers use Dapr APIs, and it’s the DevOps team that configures how those APIs connect to real infrastructure under the hood.

Need to switch from Redis to Cosmos DB? Just change the component configuration—no code changes. This separation of concerns reduces cognitive load and speeds up iteration. Developers gain velocity, and operators retain control.


More Tech Stacks ONE knowledge

Since Dapr communicates over HTTP and gRPC, it doesn’t care what language your service is written in. Whether it's Node.js, Go, Python, or .NET, all services can interact with Dapr using the same approach—via the provided SDKs.

Even in a small project like dream.jobs, we benefit from this flexibility. The backend is written in Kotlin, server-side rendering for the browser is done in Node.js, and AI components are in Python. All services use the Dapr SDK and share a single configuration in the cluster.


Abstraction = some disadvantages

Dapr’s abstraction is powerful, but it’s also generalized. Its APIs are designed to cover common patterns across many tools—which means they sometimes expose only a subset of what a specific service can do.

For example, Dapr’s pub/sub API may not support all advanced features of Azure Service Bus or Kafka. Similarly, its state store abstraction won’t provide full access to things like Cosmos DB’s consistency levels or Redis eviction policies.

That’s a trade-off we accept. For 90% of our use cases, the Dapr API is sufficient. But when we need a specific capability—like dead-letter queues or fine-tuned partitioning—we can bypass Dapr and talk directly to the underlying service. Dapr doesn’t block us; it just offers a solid default.


Final Thoughts

Most of the key benefits and risks are described above, but what I appreciate most is how Dapr helps the team be more efficient. Developers can focus on writing code and solving business problems, while a small DevOps team—even just one experienced engineer—can provide a scalable, secure platform.

In the end, the overall efficiency of your development team can be much higher.

bottom of page