AWS Open Source Blog
Expedite Production Ready Distributed Application Development with Dapr on AWS
Distributed applications are software systems that consist of multiple components or modules running on different infrastructure within a network. These components work together to achieve a common goal or provide a service, communicating and coordinating their actions across the network.
Most organizations build distributed applications for two main reasons. First, they have multiple development teams that need to work independently while contributing to a larger system. Second, they require a solution where components built using different programming languages can interact with each other.
Developing distributed applications is challenging because numerous components need to work cohesively. Developers must consider resiliency, observability, security, and scalability across multiple services and runtimes. Furthermore, distributed applications typically don’t operate in isolation; they interact with message brokers, data stores, and external services. Integrating with these resources requires knowledge of specific APIs and SDKs which increases the complexity to build such systems.
In this post, we will review how open source Dapr can help developers build reliable and secure distributed applications with in-built best practices and patterns. We will also describe common Dapr use cases on AWS.
About Dapr
Dapr (Distributed Application Runtime) is an open source project aiming to make secure and reliable microservices development easier, regardless of the programming language or framework. Dapr was accepted by the Cloud Native Computing Foundation (CNCF) with Incubating maturity level in November 2021. It is managed by a growing open source community and is trusted by large organizations.
Dapr provides building block APIs for communication, state, and workflow. Dapr runs in a separate process next to your application using a sidecar pattern. It offers best practices and patterns to develop distributed applications with built-in security, resiliency and observability. This helps you to focus on business logic rather than implementing boilerplate code.
The Dapr APIs are decoupled from the underlying resources, making Dapr a flexible solution. It can use various message brokers, state stores, secret stores, and other resources across AWS, open source solutions, and other cloud providers.
Dapr APIs and Components
Dapr’s modular architecture and pluggable components allow you to choose the APIs and components that best suit your application requirements, making it a flexible and extensible platform for building modern, cloud-native applications.
Depending on your business needs, you can choose APIs such as State Management, Publish/Subscribe, Workflow, Actors, Secrets and more. This diagram describes the APIs available in Dapr with some of the supported AWS and open source components.
You configure the underlying resources by adding Dapr component YAML files that describe the component type and include metadata on how to connect to the components.
There are over 100 components across all the Dapr APIs. Developers can benefit from the decoupling of APIs and components by using local components for development on their local machines, and switching to AWS based components for further development, testing, and production workloads in the cloud.
Dapr API Examples
When you build distributed applications with Dapr, you leverage Dapr building block APIs to quickly integrate with internal or external resources. This diagram shows how services use the Dapr APIs to communicate with each other and with configuration stores, secret stores, message brokers, state stores, and other services using bindings.
The application code that uses the Dapr APIs has no reference to specific client SDKs for the underlying resources. It remains the same when replacing one component for another of the same type. The resource-specific connection is abstracted away and is the responsibility of the Dapr sidecar.
The Dapr APIs are exposed via HTTP/gRPC and the APIs can be used with any programming language that can interact with these protocols. Client SDKs support is available for Python, NodeJS, .NET, Java, Go, Rust, C++ and PHP.
This example Python code snippet shows saving an order detail into an Amazon DynamoDB state store. The table specific details such as table, partition key, and time to live (TTL) are configured in the statestore.yaml file. By changing the statestore.yaml file, you can change the backend state store to another supported solution such as Amazon ElastiCache without changing application code.
Example Python Code Snippet:
Example statestore.yaml for DynamoDB:
Common Dapr use cases on AWS
Dapr APIs integrate with various AWS services to fulfill use cases around communication, state, and workflow management. This integration allows developers to leverage the capabilities of Dapr while taking advantage of the scalability, reliability, and security features provided by AWS.
Service Communication
In distributed systems, you need to establish service communication across multiple microservices considering security, service discovery, error handling, and observability.
Using Dapr’s Service Invocation API with Amazon Elastic Kubernetes Service (Amazon EKS), developers can easily communicate between different microservices with a standard set of APIs and in-built encryption, metrics, tracing, retries, and backoff handling.
The following diagram shows how Dapr Service Invocation works for two microservices hosted as different Amazon EKS applications.
- Application A hosted in an Amazon EKS pod calls its local Dapr sidecar (source) via http or gRPC.
- Source Dapr sidecar performs service discovery to understand the target application to invoke.
- After discovering the target service, source Dapr sidecar forwards the request to target Dapr sidecar. Invocation between Dapr sidecars is always through gRPC.
- The target Dapr sidecar invokes the Application B.
- The service response flows through the same way in the opposite direction.
Publish and Subscribe
For event-driven architectures, publish and subscribe (pub/sub) is a commonly used asynchronous communication pattern. Publishers are the components that generate messages to a message broker whereas subscribers are components that subscribe to one or more topics or channels.
This diagram shows an example of how multiple microservices applications communicate asynchronously with Dapr’s Pub/Sub API using Amazon EKS, Amazon Simple Notification Service (Amazon SNS) and Amazon Simple Queue Service (Amazon SQS).
By using Dapr’s Pub/Sub API, you can change the message broker backend by updating the pubsub.yaml component file without changing the application code. This makes it simple to switch to Amazon Managed Streaming for Apache Kafka (Amazon MSK) if you discover that it is a better fit for your use-case than AWS SMS and Amazon SQS. As the Dapr Pub/Sub API abstracts the messages that are produced and subscribed in the message broker, the producer and subscriber applications are not impacted by switching to Amazon MSK in this particular use-case.
If only some of your applications use Dapr, partial adoption of Dapr’s Pub/Sub API can also bring flexibility in architecture by leveraging different producer or subscriber applications. For example, Dapr sidecar proxies can be integrated with Amazon SNS and Amazon SQS for Amazon EKS based applications whereas other consumers such as AWS Fargate can directly poll the Amazon SQS queue for message processing.
Workflow Engine
Microservices orchestration is the process of managing and coordinating the interactions between multiple microservices in a distributed application architecture. Workflow orchestration involves coordinating the communication, data flow, and execution of various services to ensure that they work together seamlessly. One of the most important features of a workflow system is that the workflow execution is reliable. A workflow should always run to completion even if the workflow engine is temporarily not available.
Dapr Workflow offers durable execution of long running workflows where developers author these workflows as code. A large benefit of authoring workflows as code is that they can be unit tested, resulting in a well-documented and maintainable code base. Dapr Workflow can be combined with many AWS services to build stateful and fault-tolerant applications. Developers can benefit from the scale, performance, and cost efficiency of the AWS services as well as eliminating the need for managing the underlying infrastructure. As Dapr Workflow integrates with other Dapr APIs such as Service Invocation, Pub/Sub, State Management and so on, developers have the flexibility to choose different AWS services to design different communication and integration patterns across the application workflow.
Dapr Workflow provides workflow patterns developers can use to build reliable workflows such as task chaining, fan-out/fan-in, waiting for external events, and asynchronous HTTP response handling. Using these patterns with different AWS services within your applications can help design and implement production ready stateful and long running applications quickly with minimum effort. For example, if you are designing an e-commerce application where you want to process orders, store order data and state in a database, and send notifications to customers and fulfillment teams, you can use Dapr workflows to define the workflow using AWS services. A Dapr state store component can be configured to interact with DynamoDB to save order state. A Dapr Pub/Sub component can be configured to publish messages to an Amazon SNS topic for customer and fulfillment notifications. You define the tasks to be executed in a particular order and Dapr Workflow engine takes care of scheduling and execution of the tasks.
State Management
With Dapr’s State Management API building block, you can integrate different state stores on AWS such as DynamoDB or ElastiCache to design and manage your stateful applications. Without writing any boilerplate code for consistency and concurrency requirements for your state store, you can define the respective values within your statestore.yaml component file.
This diagram illustrates an example of how Dapr is integrated with DynamoDB to handle state management for an application.
Another benefit of using Dapr’s State Management API with AWS services is that it allows you to replace the state store with an alternative service depending on your business needs without changing the application code. By changing the component yaml file, users can easily move from Amazon DynamoDB to Amazon ElastiCache or vice versa to choose the developer experience that is right for them.
Getting Started with Dapr on Amazon EKS
Before you can run Dapr applications on an Amazon EKS cluster, you need to configure the following prerequisites:
- An AWS Identity and Access Management (IAM) user or role with required permissions
- A running Amazon EKS cluster
- The kubectl command line tool installed on your device or AWS CloudShell.
- The Dapr CLI for running Dapr related tasks, like running an application with a Dapr sidecar locally, or reviewing sidecar logs.
Once all the prerequisites are configured and installed, the next step is to install Dapr on your EKS cluster. To get the current context, run kubectl config current-context
command.
You can deploy Dapr on a different Amazon EKS cluster by updating the context. For example:
To initialize Dapr on your cluster, run the following command.
To check the Dapr installation on “dapr-system” namespace, run the following command.
You should see that dapr-dashboard, dapr-placement-server, dapr-sentry, dapr-operator and dapr-sidecar-injector are in “Running” state.
At this point, Dapr is deployed in your Amazon EKS cluster. You can follow Dapr Tutorials from the Dapr Docs, such as the Hello World Kubernetes tutorial or the Distributed Calculator to deploy Dapr sample applications to your Amazon EKS cluster.
Clean Up
To uninstall Dapr from the EKS cluster you can run the following command.
dapr uninstall -k
To delete the EKS cluster, you can run the “eksctl delete” command by specifying the cluster name. You can replace the your_cluster_name with your own cluster name.
eksctl delete cluster --name your_cluster_name
Conclusion
In this blog post, we provided an introduction to Dapr, an open source project to expedite distributed application development by providing integrated APIs for communication, state, and workflow. We looked at Dapr’s modular architecture which provides a swappable component model, standardized APIs, and built-in best-practices and patterns for distributed application development, allowing developers to be more efficient building microservices. After diving into Dapr features, we explained the common Dapr use cases on AWS for service invocation, pub/sub communication, workflow, and state management. You can start building applications with Dapr on Amazon EKS by following the Getting Started section and with quick starts available in Dapr documentation.
Please consider joining the Dapr Discord where thousands of developers get together and share their experiences. If you want to stay up to date with the latest Dapr developments and learn how customers use Dapr in production, join the bi-weekly Dapr Community Call live-stream.