Service-Bus-Automatisierung (Plattformseite)¶
Diese Seite ist für das Plattform-Team (die integration platform engineers). Sie beschreibt die drei Layer der Service-Bus- Verwaltung, wie das Terraform der Automatisierung funktioniert, was es braucht, wie du es ausführst und wie du Fehler suchst. Workload- Teams: siehe Service Bus.
Referenzdesign
Die Variablennamen und Standardwerte stammen aus dem Terraform der Automatisierung. Deine Plattform betreibt möglicherweise eine andere Version oder andere Namensmuster. Prüfe den Code, den du ausführst.
Die drei Layer¶
Die Service-Bus-Verwaltung ist so aufgeteilt, dass der Owner der „Rohre“ und der Owner des „Inhalts“ unabhängig arbeiten können (ADR-012).
| Layer | Inhalt | Wo der Code liegt |
|---|---|---|
| 1. Shared Service | Der Premium-Namespace, sein private endpoint, die Managed Identity für Verschlüsselungs-Keys, optional ein Customer-managed Key | Der Shared-Services-Code, deployt in den Shared-Services-spoke (Shared Services) |
| 2. Spoke extension | Berechtigungen eines Integration-spokes auf dem Namespace, einmal pro spoke beim Deployment des spokes erstellt | Der Code der spoke extension (Spoke extensions) |
| 3. Service-Bus-Automatisierung | Queues, Topics, Subscriptions, Regeln und die Zugriffsgruppen pro Entity, aus JSON-Dateien | Der Control-Plane-Code (diese Seite) |
Deploye in dieser Reihenfolge: Layer 1, dann Layer 2, dann Layer 3. Ein Layer validiert, dass der Layer darunter existiert. Wenn die Layer auseinanderlaufen (zum Beispiel zeigt die Extension auf einen gelöschten Namespace), schlägt die Automatisierung fehl.
Layer 1: Shared Service¶
- Ein Service-Bus-Namespace mit der Premium SKU. Premium wird für private endpoints und Customer-managed Keys gebraucht (ADR-001).
- Ein private endpoint in einem Subnetz des Shared-Services-spokes. Der öffentliche Netzwerkzugriff ist aus, und der Namespace ist nur über den private endpoint erreichbar. Lokale (schlüsselbasierte) Authentifizierung ist im Referenz-Shared-Service deaktiviert.
- Microsoft-managed Verschlüsselung ist der Standard. Ein Customer-managed Key lässt sich konfigurieren. Die User-assigned Managed Identity dafür wird immer deployt.
- Messaging Units (Kapazität) werden vom Plattform-Team manuell skaliert. Im Referenzcode muss die Kapazität 1, 2, 4, 8 oder 16 sein. Skalieren kann Verbindungen kurz zurücksetzen, behandle es also als operative Änderung.
- Die Standardwerte für Partitionierung werden zentral angewendet. Das Erhöhen der Partitionen auf einem laufenden Namespace ist destruktiv und braucht einen Migrationsplan.
- Geo-Disaster-Recovery ist optional.
- Eine Plattform-Policy kann Service-Bus-Namespaces im Besitz eines workloads verbieten, was zentralisiertes Messaging durchsetzt.
Layer 2: Spoke extension¶
Die Extension bereitet einen Integration-spoke so vor, dass sein Service Principal Entities verwalten kann, aber nicht den Rest des Namespace. Die Quelle der Integration Platform beschreibt sie so:
- Zwei Custom Roles pro spoke: eine, die alle Aktionen nur auf Queues, Topics und Subscriptions erlaubt, und eine, die Lesezugriff nur auf die Namespace-Ressource gibt, nicht auf ihre Kinder.
- Eine Gruppe Service Bus Namespace Readers mit den Owners, Contributors und Readers des spokes als Standardmitglieder.
- Eine Gruppe Service Bus Entity Contributors für die Owners und Contributors des spokes, für Support-Aktivitäten.
- Die Namen aller Gruppen sind konfigurierbar.
Prüfe die Extension auf deiner Plattform
Die allgemeine Dokumentation der Extension listet die Rollen etwas anders auf (eingebaute Data-Sender- und Receiver- Rollen auf dem Namespace, eine Reader-Gruppe und Manager-Rechte für den Deployment Principal des spokes), siehe Was jede Extension erstellt. Prüfe die Rollen der Extension-Version, die du betreibst, bevor du dich auf eine der beiden Beschreibungen verlässt.
Layer 3: die Automatisierung¶
Die Automatisierung liest Konfigurationsdateien aus einem Ordner, erstellt die Entities und die Gruppen und weist die Rollen zu.
flowchart TB
cfg["configuration folder<br/>queues.json, topics.json, workload.json<br/>in any subfolder"] --> tf["Terraform root: infra/service-bus"]
tf --> mod["entities module"]
mod --> q["queues sbq-..."]
mod --> t["topics sbt-..., subscriptions sbts-..., rules"]
mod --> g["Entra ID groups<br/>(in the administrative unit)"]
g --> r["Role assignments on entities"]
g --> rd["Membership of the platform readers group"]
Wichtige Eigenschaften:
- Rekursive Erkennung (ADR-003): Alle Dateien mit den Namen
queues.json,topics.jsonundworkload.jsonim Ordner und seinen Unterordnern werden zusammengeführt. Das Ordnerlayout ist frei. - Konfiguration, nicht Code (ADR-002): Workload-Teams liefern Daten, das Terraform erzwingt Namen und Einstellungen.
- Gruppenbasierter Zugriff (ADR-005, ADR-007): siehe unten.
- Reprocessing-Queues (ADR-008): eine Queue pro Subscription.
- Die Automatisierung liest den vorhandenen Namespace (sie erstellt ihn nicht) und braucht dessen subscription, Ressourcengruppe und Namen.
Ressourcen und Namen¶
| Objekt | Azure-Name | Hinweise |
|---|---|---|
| Queue | sbq-<workload>-<name> |
|
| Topic | sbt-<workload>-<name> |
|
| Subscription | sbts-<subscription workload>-<subscription name> |
Leitet an die generierte Queue weiter, wenn auto_generate_queue_for_topic_subscription true ist |
| Generierte Queue | sbq-<subscription workload>-<topic name>-<subscription name> |
Erbt Größe und Einstellungen zur Duplikaterkennung vom Topic |
| Sender-Gruppe | aus integration_workload_entity_sender_group_naming |
Eine pro Queue und Topic |
| Receiver-Gruppe | aus integration_workload_entity_receiver_group_naming |
Eine pro Queue und pro nicht weitergeleiteter Subscription |
| Operators-Gruppe | aus integration_workload_operators_group_naming |
Eine pro workload |
Gruppen werden in den angegebenen Administrative Units erstellt, sind security-enabled und haben zwei Owner: die Identität, die die
Automatisierung ausführt, und den Service Principal des workloads. Die Operators-Gruppe hat die Automatisierungsidentität als Owner. Rollen
werden auf der Entity zugewiesen (Azure Service Bus Data Sender, Azure Service Bus Data Receiver). Die Operators-Gruppe bekommt
beide auf jeder Entity des workloads. Die Reader-Gruppe des workloads und die Operators-Gruppe werden zur Platform
Readers Group hinzugefügt, die aus der spoke extension stammt.
Gruppennamen entstehen, indem {workload} und {entity} in den Templates ersetzt werden. Ein Template ohne {entity} gibt
jeder Entity denselben Gruppennamen, nutze also für die Sender- und Receiver-Muster beide Platzhalter. Entra ID begrenzt die Länge von
Gruppennamen, daher können sehr lange workload- und Entity-Namen ein Problem sein (ADR-007).
Variablen¶
| Variable | Bedeutung | Standard |
|---|---|---|
service_bus_subscription_id |
Subscription des Namespace | erforderlich |
service_bus_resource_group_name |
Ressourcengruppe des Namespace | erforderlich |
service_bus_namespace_name |
Name des Namespace | erforderlich |
integration_platform_administrative_unit_ids |
Administrative Units für die Gruppen | erforderlich |
integration_platform_readers_group_object_id |
Gruppe mit Lesezugriff auf den Namespace (aus der Extension) | erforderlich |
integration_workload_operators_group_naming |
Namensmuster der Operators-Gruppe mit {workload} |
erforderlich |
integration_workload_entity_sender_group_naming |
Namensmuster der Sender-Gruppe | erforderlich |
integration_workload_entity_receiver_group_naming |
Namensmuster der Receiver-Gruppe | erforderlich |
auto_generate_queue_for_topic_subscription |
Eine Queue pro Subscription generieren | true |
configuration_folder_path |
Ordner mit den JSON-Dateien | erforderlich |
Der Output groups listet pro workload die Object-IDs der Sender- und Receiver-Gruppen auf. Gib sie dem Workload-
Team oder lass es die Gruppen nachschlagen.
Beispiel (nutze deine eigenen Werte):
service_bus_subscription_id = "<subscription-id>"
service_bus_resource_group_name = "<resource-group>"
service_bus_namespace_name = "<namespace>"
integration_platform_administrative_unit_ids = ["<administrative-unit-id>"]
integration_platform_readers_group_object_id = "<group-object-id>"
configuration_folder_path = "./configurations"
integration_workload_operators_group_naming = "<prefix>-{workload}-operators"
integration_workload_entity_sender_group_naming = "<prefix>-{workload}-{entity}-sender"
integration_workload_entity_receiver_group_naming = "<prefix>-{workload}-{entity}-receiver"
Die Automatisierung ausführen¶
Die Voraussetzungen stehen unter Voraussetzungen. Normalerweise führt eine pipeline diese Schritte aus. In einem Entwicklungs-Setup kannst du sie von Hand ausführen.
cd infra/service-bus
terraform init
terraform validate
terraform plan -out=tfplan
terraform apply tfplan
Die Root-Konfiguration nutzt ein azurerm-Backend mit Entra-ID-Authentifizierung, übergib die Backend-Einstellungen also bei init.
Die Provider sind azurerm (4.x) und azuread (3.x). Das Root braucht Terraform 1.10.1 oder neuer.
Lies den Plan:
- Neue Queues, Topics und Gruppen aus den JSON-Dateien sind zu erwarten.
- Keine unerwarteten Löschungen. Eine entfernte Entity entfernt ihre Gruppen und die Nachrichten darin.
- Prüfe die Namen gegen die Namensmuster.
Prüfe nach dem Apply im Portal: Die Queues und Topics existieren auf dem Namespace, die Gruppen existieren in Microsoft Entra ID (in der Administrative Unit), und die Rollenzuweisungen liegen auf den Entities.
Checkliste für das pull-request-Review¶
| Prüfung | Warum |
|---|---|
Der Dateiname ist genau queues.json oder topics.json, das JSON ist gültig, name und workload sind vorhanden |
Sonst wird die Entity stillschweigend nicht gefunden |
| Der workload hat eine Workload-Definition | Ohne sie schlägt der Plan fehl |
| Keine doppelten Entity-Namen über Ordner hinweg | Ordner werden zusammengeführt, ein Duplikat ist schwer zu sehen (ADR-003) |
Die Einstellungen sind sinnvoll (max_delivery_count, TTL, Größe) |
Die Namespace-Kapazität wird geteilt |
| Der Plan hat keine unerwarteten Löschungen | Das Löschen einer Entity löscht ihre Nachrichten |
| Ein neuer Sender außerhalb des spokes hat eine Anfrage für eine Firewallregel | Verbindungen sind nicht implizit |
Review-Regeln für Konfigurationsänderungen allgemein: Änderungen sicher durchführen.
Fehlersuche¶
| Symptom | Prüfen |
|---|---|
| Queues oder Topics werden nicht erstellt | Stimmt configuration_folder_path? Existieren die Dateien (**/queues.json, Groß-/Kleinschreibung beachten)? Ist das JSON gültig? Sind name und workload vorhanden? |
| Gruppen werden nicht erstellt | Ist integration_platform_administrative_unit_ids gesetzt? Hat die Identität, die die Automatisierung ausführt, die Rolle Groups Administrator mit Scope auf die Administrative Unit? Lief das Apply? |
| Berechtigungsfehler auf dem Namespace | Stimmt die subscription-ID? Hat die Identität Owner oder Contributor auf der Ressourcengruppe des Namespace? Hat sie Zugriff auf das State-Backend? |
| Eine Anwendung bekommt „unauthorized“, nachdem sie einer Gruppe hinzugefügt wurde | Warte einige Minuten, bis sich die Gruppenänderung verteilt hat. Prüfe die richtige Gruppe (Sender oder Receiver, richtige Entity). |
| Der Plan schlägt wegen eines fehlenden workloads fehl | Ergänze die Workload-Definition für jeden workload, der in einer Queue, einem Topic oder einer Subscription verwendet wird. |