Announcing Arcus

Arcus provides a set of open-source components that make it easier to build applications that run on Microsoft Azure

Announcing Arcus

TL;DR - Arcus provides a set of open-source components that make it easier to build applications that run on Microsoft Azure.

Over the past couple of years, Codit has had more and more customers that started building applications that run on Microsoft Azure.

During those projects, we have identified components that we had to implement over and over to build a boilerplate for our applications.

We are happy to announce Arcus, our open-source family of libraries and components that makes it easier to build applications for Microsoft Azure.

Our goal with Arcus is to fill the gaps that we experience, but don't want to reinvent the wheel. If there is already a component or library that does the job we prefer to support that community.

Today, I will show you what we have done up until today and where we are going.

Event Grid

GitHub | Docs

Our first component is Arcus Event Grid which provides capabilities to more easily integrate with Azure Event Grid:

  • Provides capability to handle Event Grid validation handshake
  • Provides capability to receive events
  • Provides capability to push typed or raw events
  • Provides infrastructure for integration testing (More in this blog post)
  • Provides support for using official Azure events (Deprecated in favor of official Azure schemas, see #46)

Let's have a quick look at how easily we can push events.

Pushing events

Getting started by pulling in our NuGet package

PM> Install-Package Arcus.EventGrid.Publishing

First we will create our own NewCarRegistered event:

var licensePlate = "1-TOM-337";
var eventSubject = "/cars/1-TOM-337";
var eventId = Guid.NewGuid().ToString();
var @event = new NewCarRegistered(eventId, eventSubject, licensePlate);

For the sake of this post the NewCarRegistered class is not included but you can have a look on GitHub and our docs how to do achieve this.

Next we will create an Event Grid Publisher and publish events to the topic.

var topicEndpoint = Configuration.GetValue<string>("Arcus:EventGrid:TopicEndpoint");
var endpointKey = Configuration.GetValue<string>("Arcus:EventGrid:EndpointKey");
var eventGridPublisher = await EventGridPublisherBuilder
                                    .ForTopic(topicEndpoint)
                                    .UsingAuthenticationKey(endpointKey)
                                    .Build();
eventGridPublisher.Publish(@event);

In this example, we only push one event, but we also support sending batches via PublishMany.

If you want to be more flexible in the event payload you can also publish raw events:

var eventId = Guid.NewGuid().ToString();
var eventType = "Arcus.Samples.Cars.NewCarRegistered";
var rawEventBody = "{\"LicensePlate\":\"1-TOM-337\"}";

eventGridPublisher.PublishRaw(eventId, eventType, rawEventBody);

Event Grid Proxy

GitHub | Docs

Integrating with Azure Event Grid is simple and, hopefully, Arcus Event Grid makes it even easier for you to do so!

However, in some cases, this is still overkill because we need to write custom code to push schemas while that code still needs to run somewhere.

It would be easier if we could just push events via HTTP, without having to worry what the endpoint is & how to authenticate!

This is exactly what Arcus Event Grid Proxy does! It is a simple Docker container which accepts HTTP requests and will forward it to the configured Azure Event Grid topic.

By using a Docker container, you can basically deploy it wherever you want - Be it on Service Fabric Mesh, as a side-car in Kubernetes, on-premises or simply on your laptop for local testing!

Using Arcus Event Grid Proxy

Just pull in the container and start pushing events to it:

⚡ tkerkhove@tomkerkhove C:\arcus
❯ docker run -d -p 8999:80 --name arcus arcusazure/azure-event-grid-proxy /
                           -e ARCUS_EVENTGRID_TOPICENDPOINT=<endpoint>    /
                           -e ARCUS_EVENTGRID_AUTHKEY=<key>

Sending events is just as simple as doing an HTTP POST to it with the event payload, or provide more context about the event.

⚡ tkerkhove@tomkerkhove C:\arcus
❯  curl -X POST "http://localhost:8999/api/v1/events/Arcus.NewCarRegistered" -H "accept: text/plain" -H "Content-Type: application/json" -d "{ \"licensePlate\": \"1-ABC-337\"}" –-include
HTTP/1.1 204 No Content
Date: Mon, 28 Jan 2019 17:49:43 GMT
X-Event-Id: e9ca21cc-50ed-4138-a760-1ca9b01b092f
X-Event-Subject: /
X-Event-Timestamp: 2019-01-28T17:49:43.9021889+00:00
X-Event-Data-Version: 1.0

The beauty is that it does not only allow you to get started very easily, it also allows you to send events to Azure Event Grid that don't support it yet without having to implement & run your own code on Azure to achieve this.

Use the correct tag for the job

Different use-cases require different image tags, that's why we provide three flavors of them.

We strongly recommend reading more about our tagging strategy and only use arcusazure/azure-event-grid-proxy:latest for POCs.

Security

GitHub | Docs

Security is one of thé most important aspect when building applications, this is no different on Microsoft Azure!

With Arcus Security we've started with a nice and simple secret provider that allows you to get secrets:

var clientId = Configuration.GetValue<string>("Arcus:ServicePrincipal:ClientId");
var clientKey = Configuration.GetValue<string>("Arcus:ServicePrincipal:AccessKey");
var keyVaultUri = Configuration.GetValue<string>("Arcus:KeyVault:Uri");

var vaultAuthenticator = new ServicePrincipalAuthenticator(clientId, clientKey);
var vaultConfiguration = new KeyVaultConfiguration(keyVaultUri);
var keyVaultSecretProvider = new KeyVaultSecretProvider(vaultAuthenticator, vaultConfiguration);
var secretValue = await keyVaultSecretProvider.Get("EventGrid-AuthKey");

You can easily get started with Azure Key Vault:

PM > Install-Package Arcus.Security.Secrets.AzureKeyVault

As of today we only support Azure Key Vault, but we might add more providers later on.

Authentication

Our aim was to make it super easy and provide seamless authentication by doing the Azure AD integration for you.

We have a couple of authentication schemes that are currently supported, but more will follow such as certificate authentication.

Caching Secrets

In order to avoid hitting the service limitations of Azure Key Vault we also allow you to cache secrets:

var keyVaultUri = Configuration.GetValue<string>("Arcus:KeyVault:Uri");
var vaultAuthenticator = new ManagedServiceIdentityAuthenticator();
var vaultConfiguration = new KeyVaultConfiguration(keyVaultUri);
var cachedSecretProvider = new KeyVaultSecretProvider(vaultAuthenticator, vaultConfiguration)
                                 . WithCaching();
var secretValue = await cachedSecretProvider.Get("EventGrid-AuthKey");

This will be stored in an in-memory cache to not leak the secrets and is configurable to fit your needs.

What's next?

While we already have some components covered, this is just the beginning!

We are planning to build upon our existing components but also expand to other areas:

  • We want to make certificate authentication easier (Building upon on our security component)
  • Provide a simple way to enforce shared access key authentication (Building upon on our security component)
  • Provide more authentication mechanisms for Azure Key Vault
  • ...

Want to learn more? You can get started here:

Area Description Links
General General request or suggestions for new areas File an Issue
Event Grid Requests & suggestions for Azure Event Grid integration Features - File an Issue
Event Grid Proxy Requests & suggestions for Azure Event Grid Docker container Features - File an Issue
Security Requests & suggestions for security integration(s) Features - File an Issue

We are open to suggestions and are happy to accept pull requests!

Thanks for reading,

Tom.