Azure Event Grid Concepts

Event Routing and Event-Driven Architecture


Introduction

Azure Event Grid is a fully managed event routing service that enables you to build event-driven architectures. It connects event sources to event handlers, making it easy to react to state changes across your applications and services.

This comprehensive guide covers:

  • Core components — Topics, subscriptions, handlers
  • Event structure — Understanding event schema
  • Event types — System vs custom events
  • Delivery patterns — Push-based event delivery
  • Filtering — Event routing based on content

Architecture Overview

How Event Grid Works

┌─────────────────────────────────────────────────────────────────────┐
│                    EVENT GRID ARCHITECTURE                          │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   ┌──────────────┐                    ┌──────────────────────┐      │
│   │   Event      │   Event            │   Event              │      │
│   │   Source     │   Topic            │   Handler            │      │
│   │              │                    │                      │      │
│   │  ┌─────────┐ │                    │  ┌────────────────┐  │      │
│   │  │ Storage │ │─────── Events ──────▶│  │ Azure        │  │      │
│   │  │         │ │                    │  │ Functions      │  │      │
│   │  └─────────┘ │                    │  └────────────────┘  │      │
│   │              │                    │                      │      │
│   │  ┌─────────┐ │                    │  ┌────────────────┐  │      │
│   │  │ Cosmos  │ │                    │  │ Logic Apps     │  │      │
│   │  │ DB      │ │                    │  └────────────────┘  │      │
│   │  └─────────┘ │                    │                      │      │
│   │              │                    │  ┌────────────────┐  │      │
│   │  ┌─────────┐ │                    │  │ Webhooks       │  │      │
│   │  │ Custom  │ │                    │  └────────────────┘  │      │
│   │  │ App     │ │                    │                      │      │
│   │  └─────────┘ │                    │                      │      │
│   └──────────────┘                    └──────────────────────┘      │
│                                                                     │
│   Event Grid Topic ─── Filters events ─── Routes to handlers        │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

Event Grid Components

Topics

Topics act as the endpoint where publishers send events. There are two types:

System Topics

  • Built-in topics for Azure services
  • Automatically created when you subscribe to Azure service events
  • Examples: Storage, Cosmos DB, Service Bus, Event Hubs

Custom Topics

  • Created by users for application events
  • Fully controlled by the developer
  • Used for custom application events

Event Subscriptions

A subscription defines:

  • Which events to receive (filters)
  • Where to send events (endpoint)
  • How to deliver events (delivery options)

Event Handlers

The final destination for events:

  • Azure Functions
  • Logic Apps
  • Webhooks (HTTP endpoints)
  • Azure Event Hubs
  • Azure Service Bus Queues/Topics
  • Storage Queues

Event Structure

Event Schema

{
  "id": "event-id-12345",
  "subject": "orders/12345",
  "eventType": "order.created",
  "eventTime": "2024-01-15T10:30:00Z",
  "data": {
    "orderId": "12345",
    "customerId": "cust-001",
    "total": 99.99,
    "items": [
      {"productId": "prod-1", "quantity": 2}
    ]
  },
  "dataVersion": "1.0",
  "metadataVersion": "1"
}

Event Properties

PropertyDescriptionRequired
idUnique event identifierYes
subjectEvent source pathYes
eventTypeType of eventYes
eventTimeTimestamp of eventYes
dataEvent payloadYes
dataVersionVersion of data schemaNo
topicSource of the eventNo

CloudEvents Schema

{
  "specversion": "1.0",
  "type": "order.created",
  "source": "/subscriptions/.../resourceGroups/.../providers/Microsoft.Storage/storageAccounts/myaccount",
  "id": "event-id-12345",
  "time": "2024-01-15T10:30:00Z",
  "data": {
    "orderId": "12345"
  }
}

Creating and Managing Topics

Create Custom Topic

# Create Event Grid topic
az eventgrid topic create \
  --name orders-topic \
  --resource-group my-rg \
  --location eastus \
  --input-schema CloudEventSchemaV1_0

# Get topic endpoint
az eventgrid topic show \
  --name orders-topic \
  --resource-group my-rg \
  --query "endpoint"

# Get topic key
az eventgrid topic key show \
  --name orders-topic \
  --resource-group my-rg \
  --query "key1"

Topic Properties

// Topic configuration
var topicOptions = new TopicProperties
{
    InputSchema = EventGridEvent.Schema,  // or CloudEventV1Schema
    PublicNetworkAccess = "Enabled",
    InboundIpRules = new List<InboundIpRule>
    {
        new InboundIpRule("192.168.1.0/24", "Allow")
    }
};

Publishing Events

.NET SDK

using Azure.Messaging.EventGrid;

// Create publisher client
var topicCredential = new AzureKeyCredential("your-topic-key");
var publisher = new EventGridPublisherClient(
    new Uri("https://orders-topic.eastus-1.eventgrid.azure.net"),
    topicCredential);

// Create event
var orderEvent = new EventGridEvent(
    subject: "orders/12345",
    eventType: "order.created",
    dataVersion: "1.0",
    data: new
    {
        orderId = "12345",
        customerId = "cust-001",
        total = 99.99
    });

// Send event
await publisher.SendEventAsync(orderEvent);

// Send multiple events
var events = new EventGridEvent[]
{
    new EventGridEvent(...),
    new EventGridEvent(...)
};
await publisher.SendEventsAsync(events);

REST API

curl -X POST https://orders-topic.eventgrid.azure.net/api/events \
  -H "Content-Type: application/json" \
  -H "aeg-sas-key: your-topic-key" \
  -d '[
    {
      "id": "12345",
      "subject": "orders/12345",
      "eventType": "order.created",
      "eventTime": "2024-01-15T10:30:00Z",
      "data": {
        "orderId": "12345"
      },
      "dataVersion": "1.0"
    }
  ]'

Subscribing to Events

Create Subscription

# Webhook subscription
az eventgrid event-subscription create \
  --name order-handler \
  --resource-group my-rg \
  --topic-name orders-topic \
  --endpoint-type webhook \
  --endpoint https://myfunction.azurewebsites.net/api/handler

# Azure Function subscription
az eventgrid event-subscription create \
  --name order-function \
  --resource-group my-rg \
  --topic-name orders-topic \
  --endpoint-type azurefunction \
  --endpoint /subscriptions/.../resourceGroups/.../providers/Microsoft.Web/sites/myfunction/functions/handler

Filter Events

# Filter by event type
az eventgrid event-subscription create \
  --name order-created \
  --resource-group my-rg \
  --topic-name orders-topic \
  --endpoint https://myfunction.azurewebsites.net/api/handler \
  --filter-include-subject-pattern "orders/*" \
  --filter-event-type-string order.created

Subscription Filters

{
  "filters": {
    "subjectBeginsWith": "orders/",
    "subjectEndsWith": ".pdf",
    "includedEventTypes": ["order.created", "order.updated"],
    "advancedFilters": [
      {
        "key": "data.total",
        "operatorType": "GreaterThan",
        "value": 100
      }
    ]
  }
}

Event Handlers

Azure Functions

[FunctionName("OrderEventHandler")]
public async Task Run(
    [EventGridTrigger] EventGridEvent eventGridEvent,
    ILogger log)
{
    log.LogInformation($"Event Type: {eventGridEvent.EventType}");
    log.LogInformation($"Subject: {eventGridEvent.Subject}");
    
    switch (eventGridEvent.EventType)
    {
        case "order.created":
            await HandleOrderCreated(eventGridEvent.Data);
            break;
        case "order.updated":
            await HandleOrderUpdated(eventGridEvent.Data);
            break;
    }
}

Logic Apps

{
  "trigger": {
    "type": "EventTrigger",
    "inputs": {
      "topic": "/subscriptions/xxx/resourceGroups/my-rg/providers/Microsoft.EventGrid/topics/orders-topic"
    }
  },
  "actions": {
    "Send_Email": {
      "type": "Office365",
      "inputs": {
        "body": {
          "Subject": "New Order",
          "Body": "@triggerBody()"
        }
      }
    }
  }
}

Delivery and Retry

Retry Policy

{
  "retryPolicy": {
    "maxDeliveryAttempts": 3,
    "eventTimeToLive": "PT1H"
  }
}

Dead Letter

{
  "deadLetterDestination": {
    "endpointType": "StorageBlob",
    "properties": {
      "resourceId": "/subscriptions/.../storageAccounts/mystorage",
      "blobContainerName": "eventgrid-deadletter"
    }
  }
}

Best Practices

PracticeDescription
Use CloudEventsIndustry-standard format
Implement retryHandle transient failures
Use dead letterCapture failed events
Filter appropriatelyOnly subscribe to needed events
Monitor deliveryTrack delivery status

Security

# Enable managed identity on topic
az eventgrid topic update \
  --name orders-topic \
  --resource-group my-rg \
  --identity system-assigned

Related Topics


Azure Integration Hub - Intermediate Level