Configure Azure Event Grid Subscriptions

The azure-native:eventgrid:EventSubscription resource, part of the Pulumi Azure Native provider, defines event subscriptions that route events from Event Grid sources to destinations like Event Hubs, Functions, Storage Queues, or webhooks. This guide focuses on four capabilities: destination configuration for different Azure services, subject-based event filtering, dead letter handling for failed deliveries, and subscription scopes.

Event subscriptions reference existing Event Grid topics or event sources, and destination resources that must be provisioned separately. The examples are intentionally small. Combine them with your own Event Grid topics, destination infrastructure, and filtering logic.

Route events to Event Hub with subject filtering

Event-driven architectures often begin by routing events from Event Grid topics to Event Hubs, where downstream consumers can process them at scale.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const eventSubscription = new azure_native.eventgrid.EventSubscription("eventSubscription", {
    destination: {
        endpointType: "EventHub",
        resourceId: "/subscriptions/55f3dcd4-cac7-43b4-990b-a139d62a1eb2/resourceGroups/TestRG/providers/Microsoft.EventHub/namespaces/ContosoNamespace/eventhubs/EH1",
    },
    eventSubscriptionName: "examplesubscription1",
    filter: {
        isSubjectCaseSensitive: false,
        subjectBeginsWith: "ExamplePrefix",
        subjectEndsWith: "ExampleSuffix",
    },
    scope: "subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg/providers/Microsoft.EventGrid/topics/exampletopic1",
});
import pulumi
import pulumi_azure_native as azure_native

event_subscription = azure_native.eventgrid.EventSubscription("eventSubscription",
    destination={
        "endpoint_type": "EventHub",
        "resource_id": "/subscriptions/55f3dcd4-cac7-43b4-990b-a139d62a1eb2/resourceGroups/TestRG/providers/Microsoft.EventHub/namespaces/ContosoNamespace/eventhubs/EH1",
    },
    event_subscription_name="examplesubscription1",
    filter={
        "is_subject_case_sensitive": False,
        "subject_begins_with": "ExamplePrefix",
        "subject_ends_with": "ExampleSuffix",
    },
    scope="subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg/providers/Microsoft.EventGrid/topics/exampletopic1")
package main

import (
	eventgrid "github.com/pulumi/pulumi-azure-native-sdk/eventgrid/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := eventgrid.NewEventSubscription(ctx, "eventSubscription", &eventgrid.EventSubscriptionArgs{
			Destination: &eventgrid.EventHubEventSubscriptionDestinationArgs{
				EndpointType: pulumi.String("EventHub"),
				ResourceId:   pulumi.String("/subscriptions/55f3dcd4-cac7-43b4-990b-a139d62a1eb2/resourceGroups/TestRG/providers/Microsoft.EventHub/namespaces/ContosoNamespace/eventhubs/EH1"),
			},
			EventSubscriptionName: pulumi.String("examplesubscription1"),
			Filter: &eventgrid.EventSubscriptionFilterArgs{
				IsSubjectCaseSensitive: pulumi.Bool(false),
				SubjectBeginsWith:      pulumi.String("ExamplePrefix"),
				SubjectEndsWith:        pulumi.String("ExampleSuffix"),
			},
			Scope: pulumi.String("subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg/providers/Microsoft.EventGrid/topics/exampletopic1"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var eventSubscription = new AzureNative.EventGrid.EventSubscription("eventSubscription", new()
    {
        Destination = new AzureNative.EventGrid.Inputs.EventHubEventSubscriptionDestinationArgs
        {
            EndpointType = "EventHub",
            ResourceId = "/subscriptions/55f3dcd4-cac7-43b4-990b-a139d62a1eb2/resourceGroups/TestRG/providers/Microsoft.EventHub/namespaces/ContosoNamespace/eventhubs/EH1",
        },
        EventSubscriptionName = "examplesubscription1",
        Filter = new AzureNative.EventGrid.Inputs.EventSubscriptionFilterArgs
        {
            IsSubjectCaseSensitive = false,
            SubjectBeginsWith = "ExamplePrefix",
            SubjectEndsWith = "ExampleSuffix",
        },
        Scope = "subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg/providers/Microsoft.EventGrid/topics/exampletopic1",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.eventgrid.EventSubscription;
import com.pulumi.azurenative.eventgrid.EventSubscriptionArgs;
import com.pulumi.azurenative.eventgrid.inputs.EventSubscriptionFilterArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var eventSubscription = new EventSubscription("eventSubscription", EventSubscriptionArgs.builder()
            .destination(EventHubEventSubscriptionDestinationArgs.builder()
                .endpointType("EventHub")
                .resourceId("/subscriptions/55f3dcd4-cac7-43b4-990b-a139d62a1eb2/resourceGroups/TestRG/providers/Microsoft.EventHub/namespaces/ContosoNamespace/eventhubs/EH1")
                .build())
            .eventSubscriptionName("examplesubscription1")
            .filter(EventSubscriptionFilterArgs.builder()
                .isSubjectCaseSensitive(false)
                .subjectBeginsWith("ExamplePrefix")
                .subjectEndsWith("ExampleSuffix")
                .build())
            .scope("subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg/providers/Microsoft.EventGrid/topics/exampletopic1")
            .build());

    }
}
resources:
  eventSubscription:
    type: azure-native:eventgrid:EventSubscription
    properties:
      destination:
        endpointType: EventHub
        resourceId: /subscriptions/55f3dcd4-cac7-43b4-990b-a139d62a1eb2/resourceGroups/TestRG/providers/Microsoft.EventHub/namespaces/ContosoNamespace/eventhubs/EH1
      eventSubscriptionName: examplesubscription1
      filter:
        isSubjectCaseSensitive: false
        subjectBeginsWith: ExamplePrefix
        subjectEndsWith: ExampleSuffix
      scope: subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg/providers/Microsoft.EventGrid/topics/exampletopic1

When events arrive at the topic, Event Grid evaluates the filter against each event’s subject field. The subjectBeginsWith and subjectEndsWith properties define prefix and suffix patterns; only matching events flow to the destination. The destination property specifies the Event Hub’s resource ID, and the scope property identifies which Event Grid topic publishes the events.

Invoke Azure Functions with dead letter handling

Serverless processing pipelines route events to Azure Functions for transformation or business logic, with dead letter destinations capturing failed deliveries.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const eventSubscription = new azure_native.eventgrid.EventSubscription("eventSubscription", {
    deadLetterDestination: {
        blobContainerName: "contosocontainer",
        endpointType: "StorageBlob",
        resourceId: "/subscriptions/55f3dcd4-cac7-43b4-990b-a139d62a1eb2/resourceGroups/TestRG/providers/Microsoft.Storage/storageAccounts/contosostg",
    },
    destination: {
        endpointType: "AzureFunction",
        resourceId: "/subscriptions/55f3dcd4-cac7-43b4-990b-a139d62a1eb2/resourceGroups/TestRG/providers/Microsoft.Web/sites/ContosoSite/funtions/ContosoFunc",
    },
    eventSubscriptionName: "examplesubscription1",
    filter: {
        isSubjectCaseSensitive: false,
        subjectBeginsWith: "ExamplePrefix",
        subjectEndsWith: "ExampleSuffix",
    },
    scope: "subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg/providers/Microsoft.EventGrid/topics/exampletopic1",
});
import pulumi
import pulumi_azure_native as azure_native

event_subscription = azure_native.eventgrid.EventSubscription("eventSubscription",
    dead_letter_destination={
        "blob_container_name": "contosocontainer",
        "endpoint_type": "StorageBlob",
        "resource_id": "/subscriptions/55f3dcd4-cac7-43b4-990b-a139d62a1eb2/resourceGroups/TestRG/providers/Microsoft.Storage/storageAccounts/contosostg",
    },
    destination={
        "endpoint_type": "AzureFunction",
        "resource_id": "/subscriptions/55f3dcd4-cac7-43b4-990b-a139d62a1eb2/resourceGroups/TestRG/providers/Microsoft.Web/sites/ContosoSite/funtions/ContosoFunc",
    },
    event_subscription_name="examplesubscription1",
    filter={
        "is_subject_case_sensitive": False,
        "subject_begins_with": "ExamplePrefix",
        "subject_ends_with": "ExampleSuffix",
    },
    scope="subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg/providers/Microsoft.EventGrid/topics/exampletopic1")
package main

import (
	eventgrid "github.com/pulumi/pulumi-azure-native-sdk/eventgrid/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := eventgrid.NewEventSubscription(ctx, "eventSubscription", &eventgrid.EventSubscriptionArgs{
			DeadLetterDestination: &eventgrid.StorageBlobDeadLetterDestinationArgs{
				BlobContainerName: pulumi.String("contosocontainer"),
				EndpointType:      pulumi.String("StorageBlob"),
				ResourceId:        pulumi.String("/subscriptions/55f3dcd4-cac7-43b4-990b-a139d62a1eb2/resourceGroups/TestRG/providers/Microsoft.Storage/storageAccounts/contosostg"),
			},
			Destination: &eventgrid.AzureFunctionEventSubscriptionDestinationArgs{
				EndpointType: pulumi.String("AzureFunction"),
				ResourceId:   pulumi.String("/subscriptions/55f3dcd4-cac7-43b4-990b-a139d62a1eb2/resourceGroups/TestRG/providers/Microsoft.Web/sites/ContosoSite/funtions/ContosoFunc"),
			},
			EventSubscriptionName: pulumi.String("examplesubscription1"),
			Filter: &eventgrid.EventSubscriptionFilterArgs{
				IsSubjectCaseSensitive: pulumi.Bool(false),
				SubjectBeginsWith:      pulumi.String("ExamplePrefix"),
				SubjectEndsWith:        pulumi.String("ExampleSuffix"),
			},
			Scope: pulumi.String("subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg/providers/Microsoft.EventGrid/topics/exampletopic1"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var eventSubscription = new AzureNative.EventGrid.EventSubscription("eventSubscription", new()
    {
        DeadLetterDestination = new AzureNative.EventGrid.Inputs.StorageBlobDeadLetterDestinationArgs
        {
            BlobContainerName = "contosocontainer",
            EndpointType = "StorageBlob",
            ResourceId = "/subscriptions/55f3dcd4-cac7-43b4-990b-a139d62a1eb2/resourceGroups/TestRG/providers/Microsoft.Storage/storageAccounts/contosostg",
        },
        Destination = new AzureNative.EventGrid.Inputs.AzureFunctionEventSubscriptionDestinationArgs
        {
            EndpointType = "AzureFunction",
            ResourceId = "/subscriptions/55f3dcd4-cac7-43b4-990b-a139d62a1eb2/resourceGroups/TestRG/providers/Microsoft.Web/sites/ContosoSite/funtions/ContosoFunc",
        },
        EventSubscriptionName = "examplesubscription1",
        Filter = new AzureNative.EventGrid.Inputs.EventSubscriptionFilterArgs
        {
            IsSubjectCaseSensitive = false,
            SubjectBeginsWith = "ExamplePrefix",
            SubjectEndsWith = "ExampleSuffix",
        },
        Scope = "subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg/providers/Microsoft.EventGrid/topics/exampletopic1",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.eventgrid.EventSubscription;
import com.pulumi.azurenative.eventgrid.EventSubscriptionArgs;
import com.pulumi.azurenative.eventgrid.inputs.StorageBlobDeadLetterDestinationArgs;
import com.pulumi.azurenative.eventgrid.inputs.EventSubscriptionFilterArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var eventSubscription = new EventSubscription("eventSubscription", EventSubscriptionArgs.builder()
            .deadLetterDestination(StorageBlobDeadLetterDestinationArgs.builder()
                .blobContainerName("contosocontainer")
                .endpointType("StorageBlob")
                .resourceId("/subscriptions/55f3dcd4-cac7-43b4-990b-a139d62a1eb2/resourceGroups/TestRG/providers/Microsoft.Storage/storageAccounts/contosostg")
                .build())
            .destination(AzureFunctionEventSubscriptionDestinationArgs.builder()
                .endpointType("AzureFunction")
                .resourceId("/subscriptions/55f3dcd4-cac7-43b4-990b-a139d62a1eb2/resourceGroups/TestRG/providers/Microsoft.Web/sites/ContosoSite/funtions/ContosoFunc")
                .build())
            .eventSubscriptionName("examplesubscription1")
            .filter(EventSubscriptionFilterArgs.builder()
                .isSubjectCaseSensitive(false)
                .subjectBeginsWith("ExamplePrefix")
                .subjectEndsWith("ExampleSuffix")
                .build())
            .scope("subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg/providers/Microsoft.EventGrid/topics/exampletopic1")
            .build());

    }
}
resources:
  eventSubscription:
    type: azure-native:eventgrid:EventSubscription
    properties:
      deadLetterDestination:
        blobContainerName: contosocontainer
        endpointType: StorageBlob
        resourceId: /subscriptions/55f3dcd4-cac7-43b4-990b-a139d62a1eb2/resourceGroups/TestRG/providers/Microsoft.Storage/storageAccounts/contosostg
      destination:
        endpointType: AzureFunction
        resourceId: /subscriptions/55f3dcd4-cac7-43b4-990b-a139d62a1eb2/resourceGroups/TestRG/providers/Microsoft.Web/sites/ContosoSite/funtions/ContosoFunc
      eventSubscriptionName: examplesubscription1
      filter:
        isSubjectCaseSensitive: false
        subjectBeginsWith: ExamplePrefix
        subjectEndsWith: ExampleSuffix
      scope: subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg/providers/Microsoft.EventGrid/topics/exampletopic1

Event Grid attempts delivery to the Function endpoint specified in destination.resourceId. If delivery fails after retries, the event moves to the dead letter destination, a blob container in Azure Storage. The deadLetterDestination property specifies the storage account and container name where failed events accumulate for later inspection or reprocessing.

Queue events in Azure Storage for async processing

Applications that need durable message queuing route events to Storage Queues, where workers can poll and process them independently.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const eventSubscription = new azure_native.eventgrid.EventSubscription("eventSubscription", {
    deadLetterDestination: {
        blobContainerName: "contosocontainer",
        endpointType: "StorageBlob",
        resourceId: "/subscriptions/55f3dcd4-cac7-43b4-990b-a139d62a1eb2/resourceGroups/TestRG/providers/Microsoft.Storage/storageAccounts/contosostg",
    },
    destination: {
        endpointType: "StorageQueue",
        queueName: "queue1",
        resourceId: "/subscriptions/d33c5f7a-02ea-40f4-bf52-07f17e84d6a8/resourceGroups/TestRG/providers/Microsoft.Storage/storageAccounts/contosostg",
    },
    eventSubscriptionName: "examplesubscription1",
    filter: {
        isSubjectCaseSensitive: false,
        subjectBeginsWith: "ExamplePrefix",
        subjectEndsWith: "ExampleSuffix",
    },
    scope: "subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg/providers/Microsoft.EventGrid/topics/exampletopic1",
});
import pulumi
import pulumi_azure_native as azure_native

event_subscription = azure_native.eventgrid.EventSubscription("eventSubscription",
    dead_letter_destination={
        "blob_container_name": "contosocontainer",
        "endpoint_type": "StorageBlob",
        "resource_id": "/subscriptions/55f3dcd4-cac7-43b4-990b-a139d62a1eb2/resourceGroups/TestRG/providers/Microsoft.Storage/storageAccounts/contosostg",
    },
    destination={
        "endpoint_type": "StorageQueue",
        "queue_name": "queue1",
        "resource_id": "/subscriptions/d33c5f7a-02ea-40f4-bf52-07f17e84d6a8/resourceGroups/TestRG/providers/Microsoft.Storage/storageAccounts/contosostg",
    },
    event_subscription_name="examplesubscription1",
    filter={
        "is_subject_case_sensitive": False,
        "subject_begins_with": "ExamplePrefix",
        "subject_ends_with": "ExampleSuffix",
    },
    scope="subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg/providers/Microsoft.EventGrid/topics/exampletopic1")
package main

import (
	eventgrid "github.com/pulumi/pulumi-azure-native-sdk/eventgrid/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := eventgrid.NewEventSubscription(ctx, "eventSubscription", &eventgrid.EventSubscriptionArgs{
			DeadLetterDestination: &eventgrid.StorageBlobDeadLetterDestinationArgs{
				BlobContainerName: pulumi.String("contosocontainer"),
				EndpointType:      pulumi.String("StorageBlob"),
				ResourceId:        pulumi.String("/subscriptions/55f3dcd4-cac7-43b4-990b-a139d62a1eb2/resourceGroups/TestRG/providers/Microsoft.Storage/storageAccounts/contosostg"),
			},
			Destination: &eventgrid.StorageQueueEventSubscriptionDestinationArgs{
				EndpointType: pulumi.String("StorageQueue"),
				QueueName:    pulumi.String("queue1"),
				ResourceId:   pulumi.String("/subscriptions/d33c5f7a-02ea-40f4-bf52-07f17e84d6a8/resourceGroups/TestRG/providers/Microsoft.Storage/storageAccounts/contosostg"),
			},
			EventSubscriptionName: pulumi.String("examplesubscription1"),
			Filter: &eventgrid.EventSubscriptionFilterArgs{
				IsSubjectCaseSensitive: pulumi.Bool(false),
				SubjectBeginsWith:      pulumi.String("ExamplePrefix"),
				SubjectEndsWith:        pulumi.String("ExampleSuffix"),
			},
			Scope: pulumi.String("subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg/providers/Microsoft.EventGrid/topics/exampletopic1"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var eventSubscription = new AzureNative.EventGrid.EventSubscription("eventSubscription", new()
    {
        DeadLetterDestination = new AzureNative.EventGrid.Inputs.StorageBlobDeadLetterDestinationArgs
        {
            BlobContainerName = "contosocontainer",
            EndpointType = "StorageBlob",
            ResourceId = "/subscriptions/55f3dcd4-cac7-43b4-990b-a139d62a1eb2/resourceGroups/TestRG/providers/Microsoft.Storage/storageAccounts/contosostg",
        },
        Destination = new AzureNative.EventGrid.Inputs.StorageQueueEventSubscriptionDestinationArgs
        {
            EndpointType = "StorageQueue",
            QueueName = "queue1",
            ResourceId = "/subscriptions/d33c5f7a-02ea-40f4-bf52-07f17e84d6a8/resourceGroups/TestRG/providers/Microsoft.Storage/storageAccounts/contosostg",
        },
        EventSubscriptionName = "examplesubscription1",
        Filter = new AzureNative.EventGrid.Inputs.EventSubscriptionFilterArgs
        {
            IsSubjectCaseSensitive = false,
            SubjectBeginsWith = "ExamplePrefix",
            SubjectEndsWith = "ExampleSuffix",
        },
        Scope = "subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg/providers/Microsoft.EventGrid/topics/exampletopic1",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.eventgrid.EventSubscription;
import com.pulumi.azurenative.eventgrid.EventSubscriptionArgs;
import com.pulumi.azurenative.eventgrid.inputs.StorageBlobDeadLetterDestinationArgs;
import com.pulumi.azurenative.eventgrid.inputs.EventSubscriptionFilterArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var eventSubscription = new EventSubscription("eventSubscription", EventSubscriptionArgs.builder()
            .deadLetterDestination(StorageBlobDeadLetterDestinationArgs.builder()
                .blobContainerName("contosocontainer")
                .endpointType("StorageBlob")
                .resourceId("/subscriptions/55f3dcd4-cac7-43b4-990b-a139d62a1eb2/resourceGroups/TestRG/providers/Microsoft.Storage/storageAccounts/contosostg")
                .build())
            .destination(StorageQueueEventSubscriptionDestinationArgs.builder()
                .endpointType("StorageQueue")
                .queueName("queue1")
                .resourceId("/subscriptions/d33c5f7a-02ea-40f4-bf52-07f17e84d6a8/resourceGroups/TestRG/providers/Microsoft.Storage/storageAccounts/contosostg")
                .build())
            .eventSubscriptionName("examplesubscription1")
            .filter(EventSubscriptionFilterArgs.builder()
                .isSubjectCaseSensitive(false)
                .subjectBeginsWith("ExamplePrefix")
                .subjectEndsWith("ExampleSuffix")
                .build())
            .scope("subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg/providers/Microsoft.EventGrid/topics/exampletopic1")
            .build());

    }
}
resources:
  eventSubscription:
    type: azure-native:eventgrid:EventSubscription
    properties:
      deadLetterDestination:
        blobContainerName: contosocontainer
        endpointType: StorageBlob
        resourceId: /subscriptions/55f3dcd4-cac7-43b4-990b-a139d62a1eb2/resourceGroups/TestRG/providers/Microsoft.Storage/storageAccounts/contosostg
      destination:
        endpointType: StorageQueue
        queueName: queue1
        resourceId: /subscriptions/d33c5f7a-02ea-40f4-bf52-07f17e84d6a8/resourceGroups/TestRG/providers/Microsoft.Storage/storageAccounts/contosostg
      eventSubscriptionName: examplesubscription1
      filter:
        isSubjectCaseSensitive: false
        subjectBeginsWith: ExamplePrefix
        subjectEndsWith: ExampleSuffix
      scope: subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg/providers/Microsoft.EventGrid/topics/exampletopic1

The destination property targets a specific queue within a Storage Account. Event Grid serializes each event as a queue message, and the queueName property identifies which queue receives the events. Workers poll the queue using standard Storage Queue APIs, decoupling event arrival from processing.

Push events to HTTP endpoints via webhook

External services or custom APIs receive events through webhook endpoints, enabling integration with systems outside Azure.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const eventSubscription = new azure_native.eventgrid.EventSubscription("eventSubscription", {
    destination: {
        endpointType: "WebHook",
        endpointUrl: "https://azurefunctionexample.azurewebsites.net/runtime/webhooks/EventGrid?functionName=EventGridTrigger1&code=PASSWORDCODE",
    },
    eventSubscriptionName: "examplesubscription1",
    filter: {
        isSubjectCaseSensitive: false,
        subjectBeginsWith: "ExamplePrefix",
        subjectEndsWith: "ExampleSuffix",
    },
    scope: "subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg/providers/Microsoft.EventGrid/topics/exampletopic1",
});
import pulumi
import pulumi_azure_native as azure_native

event_subscription = azure_native.eventgrid.EventSubscription("eventSubscription",
    destination={
        "endpoint_type": "WebHook",
        "endpoint_url": "https://azurefunctionexample.azurewebsites.net/runtime/webhooks/EventGrid?functionName=EventGridTrigger1&code=PASSWORDCODE",
    },
    event_subscription_name="examplesubscription1",
    filter={
        "is_subject_case_sensitive": False,
        "subject_begins_with": "ExamplePrefix",
        "subject_ends_with": "ExampleSuffix",
    },
    scope="subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg/providers/Microsoft.EventGrid/topics/exampletopic1")
package main

import (
	eventgrid "github.com/pulumi/pulumi-azure-native-sdk/eventgrid/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := eventgrid.NewEventSubscription(ctx, "eventSubscription", &eventgrid.EventSubscriptionArgs{
			Destination: &eventgrid.WebHookEventSubscriptionDestinationArgs{
				EndpointType: pulumi.String("WebHook"),
				EndpointUrl:  pulumi.String("https://azurefunctionexample.azurewebsites.net/runtime/webhooks/EventGrid?functionName=EventGridTrigger1&code=PASSWORDCODE"),
			},
			EventSubscriptionName: pulumi.String("examplesubscription1"),
			Filter: &eventgrid.EventSubscriptionFilterArgs{
				IsSubjectCaseSensitive: pulumi.Bool(false),
				SubjectBeginsWith:      pulumi.String("ExamplePrefix"),
				SubjectEndsWith:        pulumi.String("ExampleSuffix"),
			},
			Scope: pulumi.String("subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg/providers/Microsoft.EventGrid/topics/exampletopic1"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var eventSubscription = new AzureNative.EventGrid.EventSubscription("eventSubscription", new()
    {
        Destination = new AzureNative.EventGrid.Inputs.WebHookEventSubscriptionDestinationArgs
        {
            EndpointType = "WebHook",
            EndpointUrl = "https://azurefunctionexample.azurewebsites.net/runtime/webhooks/EventGrid?functionName=EventGridTrigger1&code=PASSWORDCODE",
        },
        EventSubscriptionName = "examplesubscription1",
        Filter = new AzureNative.EventGrid.Inputs.EventSubscriptionFilterArgs
        {
            IsSubjectCaseSensitive = false,
            SubjectBeginsWith = "ExamplePrefix",
            SubjectEndsWith = "ExampleSuffix",
        },
        Scope = "subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg/providers/Microsoft.EventGrid/topics/exampletopic1",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.eventgrid.EventSubscription;
import com.pulumi.azurenative.eventgrid.EventSubscriptionArgs;
import com.pulumi.azurenative.eventgrid.inputs.EventSubscriptionFilterArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var eventSubscription = new EventSubscription("eventSubscription", EventSubscriptionArgs.builder()
            .destination(WebHookEventSubscriptionDestinationArgs.builder()
                .endpointType("WebHook")
                .endpointUrl("https://azurefunctionexample.azurewebsites.net/runtime/webhooks/EventGrid?functionName=EventGridTrigger1&code=PASSWORDCODE")
                .build())
            .eventSubscriptionName("examplesubscription1")
            .filter(EventSubscriptionFilterArgs.builder()
                .isSubjectCaseSensitive(false)
                .subjectBeginsWith("ExamplePrefix")
                .subjectEndsWith("ExampleSuffix")
                .build())
            .scope("subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg/providers/Microsoft.EventGrid/topics/exampletopic1")
            .build());

    }
}
resources:
  eventSubscription:
    type: azure-native:eventgrid:EventSubscription
    properties:
      destination:
        endpointType: WebHook
        endpointUrl: https://azurefunctionexample.azurewebsites.net/runtime/webhooks/EventGrid?functionName=EventGridTrigger1&code=PASSWORDCODE
      eventSubscriptionName: examplesubscription1
      filter:
        isSubjectCaseSensitive: false
        subjectBeginsWith: ExamplePrefix
        subjectEndsWith: ExampleSuffix
      scope: subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg/providers/Microsoft.EventGrid/topics/exampletopic1

The destination.endpointUrl property specifies the HTTP endpoint that receives event payloads. Event Grid validates the endpoint during subscription creation by sending a validation event; your endpoint must respond correctly to complete the handshake. After validation, Event Grid delivers events as HTTP POST requests with JSON payloads.

Subscribe to resource group events

Infrastructure monitoring tracks resource lifecycle events at the resource group level, capturing creation, deletion, and modification of any resource within the group.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const eventSubscription = new azure_native.eventgrid.EventSubscription("eventSubscription", {
    destination: {
        endpointType: "WebHook",
        endpointUrl: "https://requestb.in/15ksip71",
    },
    eventSubscriptionName: "examplesubscription2",
    filter: {
        isSubjectCaseSensitive: false,
        subjectBeginsWith: "ExamplePrefix",
        subjectEndsWith: "ExampleSuffix",
    },
    scope: "subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg",
});
import pulumi
import pulumi_azure_native as azure_native

event_subscription = azure_native.eventgrid.EventSubscription("eventSubscription",
    destination={
        "endpoint_type": "WebHook",
        "endpoint_url": "https://requestb.in/15ksip71",
    },
    event_subscription_name="examplesubscription2",
    filter={
        "is_subject_case_sensitive": False,
        "subject_begins_with": "ExamplePrefix",
        "subject_ends_with": "ExampleSuffix",
    },
    scope="subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg")
package main

import (
	eventgrid "github.com/pulumi/pulumi-azure-native-sdk/eventgrid/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := eventgrid.NewEventSubscription(ctx, "eventSubscription", &eventgrid.EventSubscriptionArgs{
			Destination: &eventgrid.WebHookEventSubscriptionDestinationArgs{
				EndpointType: pulumi.String("WebHook"),
				EndpointUrl:  pulumi.String("https://requestb.in/15ksip71"),
			},
			EventSubscriptionName: pulumi.String("examplesubscription2"),
			Filter: &eventgrid.EventSubscriptionFilterArgs{
				IsSubjectCaseSensitive: pulumi.Bool(false),
				SubjectBeginsWith:      pulumi.String("ExamplePrefix"),
				SubjectEndsWith:        pulumi.String("ExampleSuffix"),
			},
			Scope: pulumi.String("subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var eventSubscription = new AzureNative.EventGrid.EventSubscription("eventSubscription", new()
    {
        Destination = new AzureNative.EventGrid.Inputs.WebHookEventSubscriptionDestinationArgs
        {
            EndpointType = "WebHook",
            EndpointUrl = "https://requestb.in/15ksip71",
        },
        EventSubscriptionName = "examplesubscription2",
        Filter = new AzureNative.EventGrid.Inputs.EventSubscriptionFilterArgs
        {
            IsSubjectCaseSensitive = false,
            SubjectBeginsWith = "ExamplePrefix",
            SubjectEndsWith = "ExampleSuffix",
        },
        Scope = "subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.eventgrid.EventSubscription;
import com.pulumi.azurenative.eventgrid.EventSubscriptionArgs;
import com.pulumi.azurenative.eventgrid.inputs.EventSubscriptionFilterArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var eventSubscription = new EventSubscription("eventSubscription", EventSubscriptionArgs.builder()
            .destination(WebHookEventSubscriptionDestinationArgs.builder()
                .endpointType("WebHook")
                .endpointUrl("https://requestb.in/15ksip71")
                .build())
            .eventSubscriptionName("examplesubscription2")
            .filter(EventSubscriptionFilterArgs.builder()
                .isSubjectCaseSensitive(false)
                .subjectBeginsWith("ExamplePrefix")
                .subjectEndsWith("ExampleSuffix")
                .build())
            .scope("subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg")
            .build());

    }
}
resources:
  eventSubscription:
    type: azure-native:eventgrid:EventSubscription
    properties:
      destination:
        endpointType: WebHook
        endpointUrl: https://requestb.in/15ksip71
      eventSubscriptionName: examplesubscription2
      filter:
        isSubjectCaseSensitive: false
        subjectBeginsWith: ExamplePrefix
        subjectEndsWith: ExampleSuffix
      scope: subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourceGroups/examplerg

The scope property targets a resource group rather than a specific topic. Event Grid automatically publishes events for all resource operations within that group. The filter property still applies, allowing you to narrow events by subject patterns even when monitoring broad scopes.

Subscribe to subscription-wide events

Enterprise monitoring captures events across an entire Azure subscription, providing visibility into resource operations, policy compliance, and security events.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const eventSubscription = new azure_native.eventgrid.EventSubscription("eventSubscription", {
    destination: {
        endpointType: "WebHook",
        endpointUrl: "https://requestb.in/15ksip71",
    },
    eventSubscriptionName: "examplesubscription3",
    filter: {
        isSubjectCaseSensitive: false,
    },
    scope: "subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4",
});
import pulumi
import pulumi_azure_native as azure_native

event_subscription = azure_native.eventgrid.EventSubscription("eventSubscription",
    destination={
        "endpoint_type": "WebHook",
        "endpoint_url": "https://requestb.in/15ksip71",
    },
    event_subscription_name="examplesubscription3",
    filter={
        "is_subject_case_sensitive": False,
    },
    scope="subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4")
package main

import (
	eventgrid "github.com/pulumi/pulumi-azure-native-sdk/eventgrid/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := eventgrid.NewEventSubscription(ctx, "eventSubscription", &eventgrid.EventSubscriptionArgs{
			Destination: &eventgrid.WebHookEventSubscriptionDestinationArgs{
				EndpointType: pulumi.String("WebHook"),
				EndpointUrl:  pulumi.String("https://requestb.in/15ksip71"),
			},
			EventSubscriptionName: pulumi.String("examplesubscription3"),
			Filter: &eventgrid.EventSubscriptionFilterArgs{
				IsSubjectCaseSensitive: pulumi.Bool(false),
			},
			Scope: pulumi.String("subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var eventSubscription = new AzureNative.EventGrid.EventSubscription("eventSubscription", new()
    {
        Destination = new AzureNative.EventGrid.Inputs.WebHookEventSubscriptionDestinationArgs
        {
            EndpointType = "WebHook",
            EndpointUrl = "https://requestb.in/15ksip71",
        },
        EventSubscriptionName = "examplesubscription3",
        Filter = new AzureNative.EventGrid.Inputs.EventSubscriptionFilterArgs
        {
            IsSubjectCaseSensitive = false,
        },
        Scope = "subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.eventgrid.EventSubscription;
import com.pulumi.azurenative.eventgrid.EventSubscriptionArgs;
import com.pulumi.azurenative.eventgrid.inputs.EventSubscriptionFilterArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var eventSubscription = new EventSubscription("eventSubscription", EventSubscriptionArgs.builder()
            .destination(WebHookEventSubscriptionDestinationArgs.builder()
                .endpointType("WebHook")
                .endpointUrl("https://requestb.in/15ksip71")
                .build())
            .eventSubscriptionName("examplesubscription3")
            .filter(EventSubscriptionFilterArgs.builder()
                .isSubjectCaseSensitive(false)
                .build())
            .scope("subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4")
            .build());

    }
}
resources:
  eventSubscription:
    type: azure-native:eventgrid:EventSubscription
    properties:
      destination:
        endpointType: WebHook
        endpointUrl: https://requestb.in/15ksip71
      eventSubscriptionName: examplesubscription3
      filter:
        isSubjectCaseSensitive: false
      scope: subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4

Setting scope to a subscription ID enables monitoring of all resources across the subscription. This configuration captures events from every resource group and resource, making it suitable for centralized logging, compliance auditing, or security monitoring. The filter property with isSubjectCaseSensitive controls whether subject matching is case-sensitive.

Beyond these examples

These snippets focus on specific event subscription features: destination types, subject-based filtering, dead letter handling, and scope levels. They’re intentionally minimal rather than full event-driven architectures.

The examples reference pre-existing infrastructure such as Event Grid topics or event sources, destination resources like Event Hubs, Functions, Storage Accounts, and Service Bus, and resource groups and subscriptions. They focus on configuring the subscription rather than provisioning the surrounding infrastructure.

To keep things focused, common subscription patterns are omitted, including:

  • Retry policies (maxDeliveryAttempts, eventTimeToLiveInMinutes)
  • Managed identity authentication (deliveryWithResourceIdentity, deadLetterWithResourceIdentity)
  • Event delivery schemas (CloudEventSchemaV1_0, CustomInputSchema)
  • Advanced filters (numberIn, stringContains, boolEquals)
  • Expiration time configuration
  • Labels for subscription organization

These omissions are intentional: the goal is to illustrate how each subscription feature is wired, not provide drop-in event routing modules. See the EventSubscription resource reference for all available configuration options.

Let's configure Azure Event Grid Subscriptions

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Configuration & Setup
What destination types can I use for event subscriptions?
Event Grid supports multiple destination types: EventHub, AzureFunction, HybridConnection, ServiceBusQueue, ServiceBusTopic, StorageQueue, and WebHook. Each destination type requires an endpointType and specific configuration like resourceId or endpointUrl.
What scopes can I create event subscriptions for?
You can create subscriptions at multiple levels: Azure subscriptions, resource groups, individual resources, or EventGrid topics. The scope property accepts resource IDs at any of these levels.
What are the naming requirements for event subscriptions?
Event subscription names must be 3 to 64 characters long and use only alphanumeric letters.
Event Filtering & Delivery
How do I filter events by subject?
Configure the filter property with subjectBeginsWith and subjectEndsWith to match event subjects. Set isSubjectCaseSensitive to control case sensitivity (defaults to false in examples).
What happens to events that can't be delivered?
Configure deadLetterDestination to send undeliverable events to a storage blob container. Specify endpointType as StorageBlob, along with blobContainerName and resourceId.
How do I configure retry behavior for failed deliveries?
Use the retryPolicy property to configure the maximum number of delivery attempts and time to live for events.
What's the default event delivery schema?
The default is EventGridSchema. You can change this using the eventDeliverySchema property.
Identity & Authentication
What's the difference between using Event Grid's identity versus managed identity for delivery?
Use destination and deadLetterDestination to authenticate with Event Grid’s identity. Use deliveryWithResourceIdentity and deadLetterWithResourceIdentity to authenticate with the managed identity from the parent resource (topic or domain).
Immutability & Constraints
Which properties can't be changed after creation?
The scope and eventSubscriptionName properties are immutable and cannot be modified after the event subscription is created.

Using a different cloud?

Explore messaging guides for other cloud providers: