The Dapr project has been of interest to me since I first heard about it from Howard in late 2019. Earlier that year I'd been working with a Client who was migrating their hosting and development model to Kubernetes, and whilst they were seeing the benefits from having a consistent deployment model some more traditional challenges remained.
One was configuration-related, or more specifically the question of service discovery; for scenarios where services need to talk to each other directly (rather than via a queue, for example) how could they best manage all that configuration such that it was always up-to-date, across all services? A common approach to this challenge is to manage the configuration centrally and rely on the automated deployment process to apply any changes. However, this implies that a deployment event is required for each service when such a configuration change takes place, which can make such changes higher friction.
Clearly there are other options for addressing this, whether it's a home-grown central configuration database integrated with the services or perhaps a service mesh type infrastructure solution and many options in-between. However, such solutions typically come at the cost of additional complexity - whether at the application level, infrastructure level or both.
This is why Dapr has been so interesting to me, looking at it more from the platform perspective. The prospect of being able to easily build systems with service discovery, secrets management and distributed tracing - and all without the complexity of deploying additional infrastructure or having to 'bloat' your code with such concerns.
The icing on the cake for me, again from a platform perspective, is the idea that you can build systems that need not be tightly coupled to particular flavours of cloud platform services. Need to deploy to AWS instead of Azure? No problem, Dapr allows you to swap between different implementations just using configuration.
Also consider that Dapr supports multiple platform services within a single cloud provider. This allows organisations to flexibly choose or change which service they use with minimal development effort. For example, they might negotiate a cost-effective reservation for a different platform service (as part of some other new system) and wish to take advantage of those savings across other existing systems. The real key, in my opinion, is that you can do all these things without having to necessarily write and maintain more of your own code.
Of course, it's important to not characterise Dapr solely as some kind of multi-cloud utility knife - indeed for most of our customers multi-cloud is far from the most significant concern (or at least should be!). Instead, I think of Dapr as presenting you with a number of doorways for starting your adoption. One of those might take you a more tactical route whereby you can solve a practical platform-related challenge. Another door might offer a more architectural route, allowing you to design your systems more flexibly and focus on the required capabilities rather than a specific implementation of them.
The door you choose will depend on your particular set of challenges, however, regardless of which door you enter through you ultimately end up in the same room - where the full gamut of everything that Dapr has to offer is there for you to exploit as an when opportunity arises.
At least that's what Dapr promises (and much more, the above only scratches the surface of what it offers).
This series of blogs will use the excellent Traffic Control sample application as a basis for getting 'hands-on' with Dapr and seeing just how easy it is to achieve the above.
My goal is to iteratively update the sample to migrate it away from using container-based infrastructure services and instead utilise Azure platform services - eventually hosting the application itself inside the recently announced Azure Container Apps. Along the way, we'll be able to see how Dapr simplifies this type of undertaking and hopefully uncover some useful nuggets.
I'll update this post as I progress so it serves as an index for the series, but in the meantime here are some suggested next steps that should be useful if you want to follow along:
- Browse the documentation site to learn more about Dapr
- Download the Dapr for .NET developers e-book - the sample we're using supports this book and is a great resource for learning about Dapr
- Fork the Traffic Control application repo and make sure you can get it running in 'self-hosted' mode - the repo contains a thorough README that should get you up and running
- Checkout Barry's excellent post to get the lowdown on Project Bicep - we'll be using this to implement any Infrastructure-as-Code (IaC) needed to get our platform services setup
The running order below may change if we encounter interesting diversions, but right now the plan for this series is as follows:
- Episode 1 - Switching out RabbitMQ for Azure ServiceBus (this will also be more IaC-heavy as we get things setup)
- Episode 2 - Migrating secrets management to use Azure Key Vault
- Episode 3 - Switching out MQTT for Azure Storage Queues
- Episode 4 - Running the services in Docker and keeping an efficient dev inner loop
- Episode 5 - Hosting in Azure Container Apps