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!
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:
- Service-to-Service Invocation for synchronous communications
- State management for transactions and CRUD operations
- Pub/Sub messaging for asynchronous (message-driven) communications
- Bindings for seamless workflow integrations using event triggers
- Actors for encapsulated & reusable objects that enable reliable, scalable behaviors
- Observability to monitor application events for health and performance
- Secrets for securely accessing sensitive values.
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.
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 Appdapr.appPort
- specify port on which app is listeningdapr.appProtocol
- specify if usinghttp
(default) orgRPC
for APIdapr.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
).
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:
- Tutorial 1: Deploy a Dapr-enabled ACA using Azure CLI
- Tutorial 2: Deploy a Dapr-enabled ACA using Bicep or ARM templates
Resourcesโ
Here are the main resources to explore for self-study: