Skip to main content

ยท 8 min read
Nitya Narasimhan

Welcome to Day 12 of #30DaysOfServerless!

So far we've looked at Azure Container Apps - what it is, how it enables microservices communication, and how it enables auto-scaling with KEDA compliant scalers. Today we'll shift gears and talk about Dapr - the Distributed Application Runtime - and how it makes microservices development with ACA easier with core building blocks and a sidecar architecture!

Ready? Let's go!


What We'll Coverโ€‹

  • What is Dapr and why use it?
  • Building Block APIs
  • Dapr Quickstart and Tutorials
  • Dapr-enabled ACA: A Sidecar Approach
  • Exercise: Build & Deploy a Dapr-enabled ACA.
  • Resources: For self-study!

Session slide by Nitya Narasimhan on Dapr, explaining microservices with sidecar patterns, API blocks, and practical examples.


Hello, Dapr!โ€‹

Building distributed applications is hard. Building reliable and portable microservces means having middleware that deals with challenges like service discovery, sync and async communications, state management, secure information sharing and more. Integrating these support services into your application can be challenging from both development and maintenance perspectives, adding complexity that is independent of the core application logic you want to focus on.

This is where Dapr (Distributed Application Runtime) shines - it's defined as::

a portable, event-driven runtime that makes it easy for any developer to build resilient, stateless and stateful applications that run on the cloud and edge and embraces the diversity of languages and developer frameworks.

But what does this actually mean to me as an app developer?


Dapr + Apps: A Sidecar Approachโ€‹

The strength of Dapr lies in its ability to:

  • abstract complexities of distributed systems middleware - with Building Block APIs that implement components using best practices to tackle key challenges.
  • implement a Sidecar Pattern with interactions via APIs - allowing applications to keep their codebase clean and focus on app logic.
  • be Incrementally Adoptable - allowing developers to start by integrating one API, then evolving to use more as and when needed.
  • be Platform Agnostic - allowing applications to be developed in a preferred language or framework without impacting integration capabilities.

The application-dapr sidecar interaction is illustrated below. The API abstraction allows applications to get the desired functionality without having to know how it was implemented, or without having to integrate Dapr-specific code into their codebase. Note how the sidecar process listens on port 3500 and the API provides clear routes for the specific building blocks supported by Dapr (e.g, /secrets, /state etc.)


Dapr Building Blocks: API Interactionsโ€‹

Dapr Building Blocks refers to HTTP and gRPC endpoints exposed by Dapr API endpoints exposed by the Dapr sidecar, providing key capabilities like state management, observability, service-to-service invocation, pub/sub messaging and more to the associated application.

Building Blocks: Under the Hood
The Dapr API is implemented by modular components that codify best practices for tackling the specific challenge that they represent. The API abstraction allows component implementations to evolve, or alternatives to be used , without requiring changes to the application codebase.

The latest Dapr release has the building blocks shown in the above figure. Not all capabilities are available to Azure Container Apps by default - check the documentation for the latest updates on this. For now, Azure Container Apps + Dapr integration provides the following capabilities to the application:

In the next section, we'll dive into Dapr-enabled Azure Container Apps. Before we do that, here are a couple of resources to help you explore the Dapr platform by itself, and get more hands-on experience with the concepts and capabilities:

  • Dapr Quickstarts - build your first Dapr app, then explore quickstarts for a core APIs including service-to-service invocation, pub/sub, state mangement, bindings and secrets management.
  • Dapr Tutorials - go beyond the basic quickstart and explore more realistic service integrations and usage scenarios. Try the distributed calculator example!

Integrate Dapr & Azure Container Appsโ€‹

Dapr currently has a v1.9 (preview) version, but Azure Container Apps supports Dapr v1.8. In this section, we'll look at what it takes to enable, configure, and use, Dapr integration with Azure Container Apps. It involves 3 steps: enabling Dapr using settings, configuring Dapr components (API) for use, then invoking the APIs.

Here's a simple a publisher-subscriber scenario from the documentation. We have two Container apps identified as publisher-app and subscriber-app deployed in a single environment. Each ACA has an activated daprd sidecar, allowing them to use the Pub/Sub API to communicate asynchronously with each other - without having to write the underlying pub/sub implementation themselves. Rather, we can see that the Dapr API uses a pubsub,azure.servicebus component to implement that capability.

Pub/sub example

Let's look at how this is setup.

1. Enable Dapr in ACA: Settingsโ€‹

We can enable Dapr integration in the Azure Container App during creation by specifying settings in one of two ways, based on your development preference:

  • Using Azure CLI: use custom commandline options for each setting
  • Using Infrastructure-as-Code (IaC): using properties for Bicep, ARM templates

Once enabled, Dapr will run in the same environment as the Azure Container App, and listen on port 3500 for API requests. The Dapr sidecar can be shared my multiple Container Apps deployed in the same environment.

There are four main settings we will focus on for this demo - the example below shows the ARM template properties, but you can find the equivalent CLI parameters here for comparison.

  • dapr.enabled - enable Dapr for Azure Container App
  • dapr.appPort - specify port on which app is listening
  • dapr.appProtocol - specify if using http (default) or gRPC for API
  • dapr.appId - specify unique application ID for service discovery, usage

These are defined under the properties.configuration section for your resource. Changing Dapr settings does not update the revision but it will restart ACA revisions and replicas. Here is what the relevant section of the ARM template looks like for the publisher-app ACA in the scenario shown above.

"dapr": {
"enabled": true,
"appId": "publisher-app",
"appProcotol": "http",
"appPort": 80
}

2. Configure Dapr in ACA: Componentsโ€‹

The next step after activating the Dapr sidecar, is to define the APIs that you want to use and potentially specify the Dapr components (specific implementations of that API) that you prefer. These components are created at environment-level and by default, Dapr-enabled containers apps in an environment will load the complete set of deployed components -- use the scopes property to ensure only components needed by a given app are loaded at runtime. Here's what the ARM template resources section looks like for the example above. This tells us that the environment has a dapr-pubsub component of type pubsub.azure.servicebus deployed - where that component is loaded by container apps with dapr ids (publisher-app, subscriber-app).

USING MANAGED IDENTITY + DAPR

The secrets approach used here is idea for demo purposes. However, we recommend using Managed Identity with Dapr in production. For more details on secrets, check out tomorrow's post on Secrets and Managed Identity in Azure Container Apps

{
"resources": [
{
"type": "daprComponents",
"name": "dapr-pubsub",
"properties": {
"componentType": "pubsub.azure.servicebus",
"version": "v1",
"secrets": [
{
"name": "sb-root-connectionstring",
"value": "value"
}
],
"metadata": [
{
"name": "connectionString",
"secretRef": "sb-root-connectionstring"
}
],
// Application scopes
"scopes": ["publisher-app", "subscriber-app"]

}
}
]
}

With this configuration, the ACA is now set to use pub/sub capabilities from the Dapr sidecar, using standard HTTP requests to the exposed API endpoint for this service.

Exercise: Deploy Dapr-enabled ACAโ€‹

In the next couple posts in this series, we'll be discussing how you can use the Dapr secrets API and doing a walkthrough of a more complex example, to show how Dapr-enabled Azure Container Apps are created and deployed.

However, you can get hands-on experience with these concepts by walking through one of these two tutorials, each providing an alternative approach to configure and setup the application describe in the scenario below:

Resourcesโ€‹

Here are the main resources to explore for self-study: