Serverless architecture is becoming transformative in the way businesses create solutions and products. Serverless solutions, sitting in the sweet spot between PaaS (platform as a service) and SaaS (software as a service), abstract the underlying infrastructure, allowing developers to focus on solving business problems instead. The abstraction of infrastructure also means that developers don’t need to be concerned about scalability or performance of the platform since that’s all handled by the service. There are servers, after all, but they are hidden away. On Azure, the serverless platform consists mainly of Azure Functions and Logic Apps along with other services, such as Cosmos DB and Azure Active Directory, providing support around data and authentication. With the availability of Serverless platforms, many developer teams have decided to move their applications ‘up the stack’ adopting Azure Functions and Logic Apps to create scalable, highly performing, and reliable services with minimal or no code at all.
Azure Functions is the serverless compute service that allows developers to write custom code to respond to various events. These events or triggers such as Cosmos DB or Blob Storage triggers are predefined and offered right out of the box. If an Azure Function needs to respond to a document change in Cosmos DB or a new blob upload in storage, then developers can quickly configure this through a selection of triggers. In addition to the predefined triggers, the Azure Functions team recently released a preview of its extensible bindings framework which can be used to create a custom binding for consumption by an Azure Function.
Azure Logic Apps is the serverless integration engine that can be used to connect to various Azure and non-Azure services and orchestrate complex workflows with predefined building blocks. Logic Apps can be extremely powerful and versatile because they provide over 190 predefined connectors such as ServiceNow, DropBox, OneDrive, and GoogleDocs, along with an extensible model to create custom connectors. One of the greatest strengths of Logic Apps is that one can define complex workflows with no code at all, since all connectors, conditions and actions are defined as JSON. Consequently, eliminating code also eliminates the chances of introducing bugs.
Both Azure Functions and Logic Apps enable developers to focus on creating applications without worrying about infrastructure, provisioning, or scaling. Once an Azure Function or a Logic App is deployed, the code can respond to events automatically. Instead of implementing elaborate polling methods or schedules that run regardless of the state of the source system, Azure Functions and Logic Apps can optimise any solution by only running when there’s a corresponding event. There has been, however, a bit of the story missing, a gap in the whole serverless fabric. What was missing was the ability to manage, in one central place, the way the events are received and routed.
It’s important to highlight that these events are not restricted to the Azure platform. The desired service should be able to capture and respond to any event that any application, platform, or service may generate.
Azure Event Grid was introduced to make it even easier to build event-based and serverless applications on Azure. Azure Event Grid is a fully-managed event routing service running on top of Azure Service Fabric. This is one of the many Azure solutions that rely on Service Fabric. Cosmos DB, for example, also runs on top of Service Fabric and demonstrates the same characteristics: incredibly scalable, highly available, globally present. It’s interesting to see how Service Fabric is not only an Azure Service that developers can utilise to build microservices on Azure, but it’s also a piece of engineering that’s heavily used internally by Azure for its infrastructure!
In its simplest form, Event Grid is a service that can be used to raise events from anywhere to anywhere and react accordingly. Event Grid has first-class support for events coming from Azure services at the Subscription, Resource Group, and Resource levels. These are built-in events that developers and infrastructure admins can leverage to programmatically respond to various events. However, it’s important to clarify that not all service events are surfaced through Event Grid currently. This is expected to change quickly as Event Grid becomes a key service for managing infrastructure. Where Event Grid really shines is the support for custom events generated by application and third-party systems. These can either be custom topics or custom webhooks, and Event Grid becomes the central hub to manage all native and custom events in one place.
The anatomy of Event Grid
EventGrid consists of several components:
- Event Subscribers or Handlers
Events are the payload generated by a resource or an application. Think of it as something similar to a message that gets pushed to a queue. The event payload contains all the necessary information about the event such as time, data, and source. Each event is atomic and self-contained, and because each source is different, events can be quite different from one another.
An event publisher is anything that can generate an event. This could be an Azure resource or subscription that emits an event when something changes (new user added, resource settings amended, etc.) or an application that generates custom events such as a mobile application that’s gone offline. Publishers are responsible for pushing the events to Event Grid. For built-in publishers, there are no code requirements, but for custom events, developers will need to write the appropriate code to communicate with Event Grid
Event topics are used to categorize various events. Think of topics as buckets or queues. Each topic exposes a public endpoint that publishers can use to send events. The nice thing about topics is that they expose a schema so that subscribers can easily create code to consume each event accordingly. Topics are split to System (built-in) and Custom (application and 3rd party)
Event Subscriptions define which events on a topic a subscriber is interested in. The subscription holds all necessary information about how events should be routed to all interested subscribers. One powerful subscription feature is the ability to filter which events to listen to. Filters can be applied to event types or the event subject
Security and Authentication with Event Grid
For a service to be appealing to an enterprise, it needs to provide a solid security model. Azure Event Grid comes with three types of authentication
- Event subscriptions
- Event publishing
- Webhook event delivery
When creating a subscription to an event, users need to have the Microsoft.EventGrid/EventSubscriptions/Write permission on the required resource. Both in the case of system topics and custom topics, the permission is required because you need to be able to write a subscription at the scope of the resource. In the case of a system topic, the permission allows you to write a new event subscription at the scope of the resource publishing the event. For example, to subscribe to events raised by a virtual machine (VM) you need permissions at this level:
On the other hand, for custom topics you need permission to write a new event subscription at the scope of the Event Grid topic. The format of this resource is slightly different as per the example below:
Event publishing takes advantage of either secret keys or Shared Access Signatures (SAS). SAS provides more fine-grained control as it can have a specific scope and duration and can easily be revoked but, unfortunately, it’s not fully supported by all webhook systems. If the subscriber can’t leverage SAS, then the use of the secret key is recommended. To enforce authentication, you need to provide the appropriate HTTP header value. For SAS authentication you need use an aeg-sas-token and for key authentication you need to use an aeg-sas-key. You can grab the topic key from the portal:
Alternatively, you can run the following command in the Azure CLI or Azure Cloud Shell:
az eventgrid topic key list --output table --resource-group <resourceGroupName> --name <topicName>
The SAS token needs to be calculated programmatically. You can find more information in the official documentation.
Webhooks don’t provide an advanced authentication method. Instead, the Event Grid uses a handshake to validate the webhook subscription when first registering a webhook against a topic. The Event Grid sends a POST request with a validation code to prove that you own the endpoint. If the application doesn’t respond by echoing back the validation code, then the subscription will fail. Event Grid does not deliver events to WebHook endpoints that have not passed the validation. However, this is not all there is. If you want to harden security, then your application could implement key authentication. Consequently, when you register a new subscriber endpoint in Azure Event Grid, the HTTP URL endpoint can include your authentication key in the query string. This query string will be included in each and every subsequent call to your endpoint. Your application will need to receive and validate the key with every incoming call. This way you eliminate the MitM (Man in the Middle) threat and make DoS (Denial of Service) attacks much harder.
Built-in Retry mechanism
Like Azure Service Bus, Event Grid has built-in retry operations to ensure reliable event delivery. Event Grid attempts to deliver each message at least once for each registered subscription. Events are sent to each subscription immediately. However, if a webhook does not acknowledge receipt of an event within 60 seconds of the first delivery attempt, Event Grid retries to deliver the event.
To keep track of delivery statuses, Event Grid uses HTTP response codes. It follows the standard HTTP response codes:
- 200 OK
- 202 Accepted
- 400 Bad Request
- 401 Unauthorized
- 404 Not Found
- 408 Request timeout
- 414 URI Too Long
- 500 Internal Server Error
- 503 Service Unavailable
- 504 Gateway Timeout
In case of a failure, Event Grid uses an exponential back-off policy based on the following values with an element of randomization to improve delivery durability:
- 10 seconds
- 30 seconds
- 1 minute
- 5 minutes
- 10 minutes
- 30 minutes
- 1 hour
During the preview, the maximum retry duration is two hours, but this is expected to increase to twenty-four hours when the service goes into General Availability.
Walkthrough: Email to admin when a new account is added to a subscription
One of the great things about the tight integration between Event Grid and Azure is the ability to easily respond to events raised by changes to resources in a subscription or changes to the subscription itself. In this example, we examine the steps required to setup a Logic App to subscribe to subscription changes and when a new account is added in Azure Active Directory. This can be extremely useful for security and auditing purposes as subscription admins need to know when changes like this happen. Once a change is detected, the Logic App is configured to send an email. With no filters, the Logic App would listen and respond to all events, so we need to be a lot more specific and reduce the load.
Head to the Azure Portal and create a new Logic App as shown in the following screenshot:
You’ll see a description of the feature and a Create button at the bottom of the screen. Click Create to get to the Create logic app screen where you will provide the Name, Subscription, Resource group and Location. Click Create once again when these details are filled in.
Once the creation process is completed, open the Logic App designer and select the Blank Logic App template:
In the designer, type Event Grid to find the appropriate connector/trigger, then select the Azure Event Grid – When a resource event occurs.
Press the Sign In button and enter your Azure account credentials.
In the When a resource event occurs dialog, select the Subscription, Resource Type, Resource Name to monitor and Prefix Filter. You will need to click Show Advanced Options to see all the fields. In this instance, I’ve set the values to:
Subscription: the subscription where I wish to connect and run my Logic App
Resource Type: Microsoft.Resources.subscriptions
Resource Name: the subscription that we wish to monitor for account changes
Prefix Filter: To ensure that the Logic App only listens to Azure Active Directory changes, we need to add a Prefix filter. Otherwise, the Logic App will respond to every event incurring unnecessary charges. The prefix needs to have the following value which will cause the event to fire when a change to an account is made at the subscription level:
An easy way to work out the subscription ID is to use the Peek Code functionality in the designer (click on the … at the top right-hand corner of the designer card). The subscription ID can be found in many places in the code, so just pick one and copy the value as per the example below:
You can also provide a value for the Subscription Name, which is the name that the Event Grid will assign to this subscription. In the end, your connector configuration should look like this:
Make sure you save the Logic App before continuing to the next step.
We then need to add an Action to send the email in response to the captured event. We could use a third-party service like SendGrid but, in this instance, it’s easier to use Office 365 to send the email. Click the New Step -> Add an Action to configure the Office 365 action.
Select Office 365 Outlook.
Search for and select Office 365 Outlook – Send an email.
If this is the first time using the Office 365 Connector, you’ll be prompted to log in. Note that this must be an Office 365 account which may not be the same account you used to connect to Azure.
Configure the email action with the destination email address, subject and body. In each of these fields, you can add one of the predefined Event Grid event properties along with free text. You can use one or more properties from the right-hand pane and you can use the same property more than once. The free text can be before, between or after the properties so there’s a lot of freedom on how you compose the final email. Make sure you save the Logic App like we did earlier.
After saving, the Logic App will wait for an event to fire. When an account change takes place, the Event Grid raises an event and the Logic App up executes sending an email like the one below:
There’s a corresponding log in the Logic App Overview panel.
Finally, if we check the Event Grid subscriptions, we can find the one that was just configured through the process of creating the Logic App.
Event Grid Management and Costs
Event Grid topics and subscriptions can be managed using the Azure Portal, the Azure CLI or Azure PowerShell with full feature parity. As for running costs, Event Grid is very inexpensive to run in true Serverless fashion. The cost is based on the total number of operations performed. Operations include all ingress (incoming events), advanced match, delivery attempts and management calls. At the time of this writing, the first 100,000 events per month are free, and subsequent events are charged at £0.224 per 1M operations. This Azure Cost Calculator page (https://azure.microsoft.com/en-gb/pricing/details/event-grid ) has a few examples that showcase how inexpensive it is to run Event Grid to include Event Grid in your solution.
Azure Event Grid is transforming the way we create, subscribe and manage events. It’s the one central place to manage all events across multiple platforms and promotes a new, event-based programming model which is more efficient and scalable than the traditional polling or scheduled-based approach. Microsoft Azure is undergoing an exciting transformation and Event Grid is at the heart of all this. With excellent integration with Azure Functions and Logic Apps, developers can quickly solve complex problems using a scalable and cost-effective set of services. Make sure you take Azure Event Grid for a test.