Viele Anwendungen brauchen getrennte Ereigniskanäle? Eine Event Grid Domain konfigurieren

Nutze eine Domain, wenn du viele zusammengehörige Ereigniskanäle unter einem gemeinsamen Veröffentlichungsendpunkt brauchst. Beispielsweise senden eine Bestell- und eine Rechnungsanwendung unterschiedliche Ereignisse. Jede erhält ein eigenes Domain Topic und eigene Event Subscriptions. Eine Event Grid Domain ist ein Container für diese Topics, kein Internet-Domainname.

Im vorherigen Trip hatte ein eigenständiges Topic seinen eigenen Endpunkt. Hier teilen sich beide Kanäle den Domain-Endpunkt. Der Sender setzt das Feld topic auf der obersten Ebene des Ereignisses, um den Kanal auszuwählen. Jeder Kanal leitet seine Ereignisse anschließend an eine eigene Storage-Queue weiter.

Ja, die Topics bleiben getrennt. Die Domain gibt ihnen eine gemeinsame Adresse zum Veröffentlichen von Ereignissen:

                 Ein gemeinsamer Domain-Endpunkt
                                |
                     Feld topic im Ereignis
                       /           \
               app-orders       app-billing
                   |                 |
              Orders-Queue      Billing-Queue
Was getrennt bleibt Was gemeinsam ist
Event Subscriptions, Filter und Ziele jedes Topics Der Veröffentlichungsendpunkt, die Konfiguration auf Domain-Ebene und—in diesem Lab—der Schlüssel zum Veröffentlichen

Der Sender ruft immer dieselbe Adresse auf. Im Ereignis wählt er mit "topic": "app-orders" oder "topic": "app-billing" den Kanal aus.

Verwende rg-cloudtrips-eventgrid-test-weu, stcteventsweu und deine Rolle Storage Queue Data Contributor aus dem vorherigen Trip. Nutze durchgehend deinen tatsächlichen Storage-Kontonamen. Das eigenständige Topic kann bestehen bleiben, gehört aber nicht zu dieser Route. Service-Bus-Ressourcen sind nicht nötig.

Domain und Queues erstellen

Suche im Azure-Portal nach Event Grid Domains → Create:

Subscription: CloudTrips TEST
Resource group: rg-cloudtrips-eventgrid-test-weu
Name: egd-ctappsweu
Region: West Europe
Input schema: Event Grid Schema

Lass öffentlichen Netzwerkzugriff und Schlüsselauthentifizierung für dieses Lab aktiviert. Ergänze bei einem bereits vergebenen Namen ein Suffix. Behalte die automatische Erstellung von Domain Topics bei: Die erste Event Subscription eines Kanals erstellt dessen Domain Topic.

Öffne dein Storage-Konto → Data storage → Queues und erstelle zwei Queues: app-orders und app-billing. Verwende dafür nicht die Queue order-events aus dem vorherigen Trip.

Aktiviere unter egd-ctappsweu → Identity → System assigned die Identität mit On und speichere. Weise am Storage-Konto → Access control (IAM) der verwalteten Identität von egd-ctappsweu die Rolle Storage Queue Data Message Sender zu. Die Identität des bisherigen eigenständigen Topics gewährt dieser neuen Domain keinen Zugriff. Warte einige Minuten auf die Übernahme der Rollenzuweisung.

Zwei Domain-Topic-Subscriptions erstellen

Öffne Cloud Shell → Bash. Passe bei Bedarf ct_storage und ct_domain an und führe den Block aus. Falls eine Anmeldung erforderlich ist, führe zuerst az login --use-device-code aus und folge den Anweisungen.

Die beiden Subscriptions verwenden unterschiedliche Quellressourcen-IDs mit den Endungen /topics/app-orders und /topics/app-billing. Dadurch entstehen zwei Domain Topics, die jeweils an ihre passende Queue zustellen. Erstelle für diese Übung keine Subscription auf Domain-Ebene; diese würde Ereignisse aus allen Topics erhalten.

az account show --output table
az account set --subscription 'CloudTrips TEST'

ct_rg='rg-cloudtrips-eventgrid-test-weu'
ct_domain='egd-ctappsweu'
ct_storage='stcteventsweu'

ct_domain_id=$(az eventgrid domain show   --resource-group "$ct_rg" --name "$ct_domain" --query id --output tsv)
ct_storage_id=$(az storage account show   --resource-group "$ct_rg" --name "$ct_storage" --query id --output tsv)

for ct_channel in app-orders app-billing; do
  az eventgrid event-subscription create     --name "es-$ct_channel-to-queue"     --source-resource-id "$ct_domain_id/topics/$ct_channel"     --event-delivery-schema EventGridSchema     --delivery-identity systemassigned     --delivery-identity-endpoint-type storagequeue     --delivery-identity-endpoint "$ct_storage_id/queueServices/default/queues/$ct_channel"     --output table || break
done

az eventgrid domain topic list   --resource-group "$ct_rg" --domain-name "$ct_domain" --output table

Schlägt ein Befehl fehl, behebe den gemeldeten Fehler und führe den Block erneut aus. Prüfe vor dem Fortfahren, dass beide Topics aufgelistet sind. Öffne im Portal egd-ctappsweu → Event Grid Topics (je nach Portalansicht Topics) und aktualisiere die Ansicht.

Screenshot 1: Topic-Liste der Domain mit app-orders und app-billing.

Topic-Liste der Domain mit app-orders und app-billing.

An beide Kanäle veröffentlichen

Führe in derselben Cloud-Shell-Sitzung diesen Block aus. Ändere bei Bedarf domain_name. Er nutzt integrierte Python-Bibliotheken und ruft den Domain-Schlüssel ab, ohne ihn auszugeben. Pakete oder Connection Strings sind nicht nötig. Dein Lab-Owner-Konto darf den Schlüssel abrufen.

python3 - <<'PYTHON'
import json
import subprocess
import uuid
from datetime import datetime, timezone
from urllib.request import Request, urlopen

resource_group = "rg-cloudtrips-eventgrid-test-weu"
domain_name = "egd-ctappsweu"

def az_value(*args):
    return subprocess.check_output(
        ["az", *args, "--output", "tsv"], text=True
    ).strip()

endpoint = az_value(
    "eventgrid", "domain", "show", "--resource-group", resource_group,
    "--name", domain_name, "--query", "endpoint"
)
key = az_value(
    "eventgrid", "domain", "key", "list", "--resource-group", resource_group,
    "--name", domain_name, "--query", "key1"
)
events = []
for channel, event_type, subject, data in [
    ("app-orders", "CloudTrips.OrderCreated", "orders/CT-6001",
     {"orderId": "CT-6001", "product": "Notebook"}),
    ("app-billing", "CloudTrips.InvoiceCreated", "invoices/INV-6001",
     {"invoiceId": "INV-6001", "amount": 12.50})
]:
    events.append({
        "topic": channel,
        "id": str(uuid.uuid4()),
        "eventType": event_type,
        "subject": subject,
        "eventTime": datetime.now(timezone.utc).isoformat(),
        "dataVersion": "1.0",
        "data": data
    })
request = Request(
    endpoint, data=json.dumps(events).encode("utf-8"),
    headers={"Content-Type": "application/json", "aeg-sas-key": key},
    method="POST"
)
with urlopen(request, timeout=30) as response:
    print(f"Accepted: HTTP {response.status}")
for event in events:
    print(f"{event['topic']}: {event['subject']} — ID {event['id']}")
PYTHON

Beide Ereignisse werden mit einer HTTP-Anfrage an denselben Endpunkt veröffentlicht. Das Feld topic wählt das Domain Topic aus, nicht subject oder eventType. Das Skript gibt die IDs aus, damit du die Queue-Nachrichten diesem Lauf zuordnen kannst.

Getrennte Zustellung prüfen

Öffne jede Queue unter Storage-Konto → Data storage → Queues, aktualisiere die Ansicht und prüfe den Nachrichtentext mit deiner Microsoft-Entra-Identität:

Zielqueue Erwartetes Ereignis Darf aus diesem Test nicht erhalten
app-orders CloudTrips.OrderCreated; CT-6001 INV-6001
app-billing CloudTrips.InvoiceCreated; INV-6001 CT-6001

Vergleiche die Ereignis-IDs mit Cloud Shell. Bietet die Ansicht Base64-Decodierung an, nutze sie nur bei codiertem Text. Event Grid kann Duplikate zustellen. Prüfe deshalb Inhalte und IDs, statt genau eine Zeile zu erwarten.

Screenshot 2: Queue app-orders mit dem Ereignis zu CT-6001.

Queue app-orders mit dem Ereignis zu CT-6001.

Screenshot 3: Queue app-billing mit dem Ereignis zu INV-6001.

Queue app-billing mit dem Ereignis zu INV-6001.

Bleibt eine Queue leer, kontrolliere, ob ihre Subscription erfolgreich erstellt wurde und auf die richtige Queue zeigt. Bleiben beide leer, prüfe Zustellidentität und Rollenzuweisung der Domain. Warte auf Rollenübernahme und Zustellwiederholungen, bevor du weitere Testereignisse sendest.

Was diese Trennung bedeutet

Die Domain organisiert Ereigniskanäle und ermöglicht es, Berechtigungen zur Subscription-Verwaltung auf einzelne Domain Topics zu begrenzen. Getrennte Topics isolieren die Sender nicht automatisch: Der hier verwendete Domain-Schlüssel darf an jedes Topic der Domain veröffentlichen. Gib diesen gemeinsamen Schlüssel nicht an Anwendungen weiter, die nicht in die Kanäle anderer Anwendungen schreiben dürfen. Dieses Lab demonstriert Routing, keine getrennten Anwendungsidentitäten oder Mandantensicherheitsgrenzen.

Für wenige unabhängige Kanäle können eigenständige Topics einfacher sein. Eine Domain wird nützlich, wenn viele zusammengehörige Kanäle zentral verwaltet werden sollen. Die Zustellung nutzt weiterhin die Event-Grid-Wiederholungsversuche, kann Duplikate enthalten und garantiert keine Reihenfolge.

Abschluss

Behalte die Ressourcen für weitere Event-Grid-Szenarien. Andernfalls lösche egd-ctappsweu und die beiden neuen Storage-Queues. Lösche die gesamte Lab-Ressourcengruppe erst, wenn du auch das bisherige Topic und dessen Queue nicht mehr brauchst. Event-Grid-Operationen und Storage-Nutzung können Kosten verursachen.