Azure Event Grid: The Eventing Backbone Between Everything

The messaging posts covered Service Bus (commands that must not be lost) and Event Hubs (streams to be analyzed). The third pillar completes the taxonomy: Event Grid carries discrete events, facts that something happened, a blob was created, a VM was deallocated, an order was placed, published once and pushed to whoever subscribed. It is the reactive nervous system of the platform, and half its value is already running whether you use it or not.

System Topics: The Platform Narrates Itself

Nearly every Azure service publishes system events: storage blob created and deleted, resource group write and delete operations via the subscription topic, Key Vault certificate nearing expiry (the rotation post’s trigger), container registry image pushed, Policy state changes. Subscribing is the cheapest automation primitive in Azure, and the estate this series built runs on it in a dozen places already named: the blob triggered Data Factory pipelines, the secret rotation functions, the image push triggering deployment metadata updates, the policy compliance events feeding the governance dashboards. The pattern to adopt deliberately: for any “when X happens, do Y” requirement, check the system topic catalog before writing a polling loop, because the polling loop costs compute forever and lags by its interval, while the subscription costs nothing at rest and fires in seconds.

resource "azurerm_eventgrid_system_topic" "storage" {
  name                   = "egst-datalake"
  location               = "westeurope"
  resource_group_name    = azurerm_resource_group.data.name
  source_arm_resource_id = azurerm_storage_account.datalake.id
  topic_type             = "Microsoft.Storage.StorageAccounts"
}

resource "azurerm_eventgrid_system_topic_event_subscription" "new_files" {
  name                = "sub-new-files"
  system_topic        = azurerm_eventgrid_system_topic.storage.name
  resource_group_name = azurerm_resource_group.data.name

  included_event_types = ["Microsoft.Storage.BlobCreated"]

  subject_filter {
    subject_begins_with = "/blobServices/default/containers/inbound/"
  }

  service_bus_queue_endpoint_id = azurerm_servicebus_queue.ingest.id

  dead_letter_identity { type = "SystemAssigned" }
  storage_blob_dead_letter_destination {
    storage_account_id          = azurerm_storage_account.ops.id
    storage_blob_container_name = "eventgrid-deadletters"
  }
}

Delivery Semantics and the Handler Contract

Event Grid pushes with at least once delivery and retries on failure with backoff for up to 24 hours, then dead letters to the blob container you configured, and configuring it is not optional for the reasons the Service Bus post made structural: an unmonitored dead letter destination is silent event loss. Handlers therefore carry the familiar contract, idempotent by event ID, fast to acknowledge (offload real work to a queue, exactly what the subscription above does by targeting Service Bus rather than a webhook), and honest about poison events. Filtering happens at the subscription, subject prefixes and advanced filters on event data, so consumers receive only their slice and the fan out stays cheap. Custom topics extend the model to your own domains, application events published as CloudEvents (use the CloudEvents schema for anything new, it is the standard the ecosystem converged on), and partner topics bring third party SaaS events into the same subscription machinery. Namespaces add the pull delivery and MQTT broker capability, the latter turning Event Grid into the ingestion front door for IoT fleets speaking MQTT natively, bridging device telemetry into the same routing fabric, a thread the IoT posts later in this series will pull.

Choosing Among the Three

The taxonomy that settles architecture meetings: a command someone must process exactly sensibly, with ordering and transactions, is Service Bus; a firehose to aggregate and replay is Event Hubs; a fact to broadcast to unknown subscribers is Event Grid, and combinations are normal, Event Grid announcing that data landed, Service Bus queuing the processing, Event Hubs carrying the resulting telemetry. Wire all three into the observability stack, alert on dead letter depth and delivery failure metrics, publish from your applications with managed identity over private endpoints, and the estate gains the property this whole series has been assembling piece by piece: things happen because events happened, declaratively subscribed, individually retried, and visible when they fail.

Cheers
Osama

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.