# Infrastruktur (Bicep)

> Aufbau des Bicep-Deployments: Module und Parameterfluss, Ressourcen, App-Settings der Function App, Managed Identity und Rollen, Alerts, Marketplace-Artefakte.

---

Site [llms.txt](/llms.txt)

---

Einstiegspunkt ist `bicep/main.bicep`. Das Deployment läuft im Scope einer bestehenden
Resource Group (Bicep-Default, kein explizites `targetScope`), im Modus Incremental.
Die Parameter aus Anwendersicht sind unter
[Installation](/docs/einrichtung/installation/) beschrieben; hier geht es um den inneren
Aufbau.

## Module und Parameterfluss

```mermaid
flowchart TD
    MAIN["main.bicep"]

    SA["storageaccount.bicep"]
    AI["applicationinsights.bicep"]
    ASP["appserviceplan.bicep"]
    SB["servicebus.bicep"]
    ALERT["metricalerts.bicep<br/>if enableAlerts"]
    DASH["dashboard.bicep<br/>if enableGrafanaDashboard"]
    FUNC["azurefunction.bicep"]
    ROLES["roleassignments.bicep<br/>if enableManagedIdentity"]

    MAIN --> SA & AI & ASP & SB & ALERT & DASH & FUNC & ROLES

    SA -->|"id, name"| FUNC
    AI -->|"connectionString, id"| FUNC
    AI -->|"id"| DASH
    ASP -->|"id"| FUNC
    SB -->|"authorizationRuleId, name"| FUNC
    SB -->|"id"| ALERT
    FUNC -->|"principalId"| ROLES
    SA -->|"id"| ROLES
    SB -->|"id"| ROLES
```

Die Abhängigkeiten ergeben sich über Modul-Outputs, es gibt keine Zyklen. Zusätzlich legt
`main.bicep` ein leeres Tracking-Deployment für die Microsoft-Partner-Attribution an.

## Ressourcen

| Ressource | Typ | SKU / Eigenschaften | Modul |
|---|---|---|---|
| Storage Account `st<name>` | `Microsoft.Storage/storageAccounts` | StorageV2, Standard_LRS, TLS 1.2 | storageaccount |
| Table Service mit vier Tabellen | `…/tableServices/tables` | `connections`, `jobs`, `mappings`, `watermark` | storageaccount |
| Application Insights `appi<name>` | `Microsoft.Insights/components` | Retention 90 Tage, klassisch (ohne eigenen Log-Analytics-Workspace) | applicationinsights |
| App Service Plan `asp<name>` | `Microsoft.Web/serverfarms` | Y1 (`capacity 0`) oder EP1–EP3, Windows | appserviceplan |
| Service Bus Namespace `sb<name>` | `Microsoft.ServiceBus/namespaces` | Basic | servicebus |
| Sieben Queues | `…/namespaces/queues` | siehe unten | servicebus |
| Authorization Rule `sbexportFunction` | `…/authorizationRules` | Send + Listen | servicebus |
| Function App `func<name>` | `Microsoft.Web/sites` | kind `functionapp`, FTPS only, `netFrameworkVersion 10.0`, System-Identity immer aktiv | azurefunction |
| Grafana-Dashboard | `Microsoft.Dashboard/dashboards` | eingebettete JSON-Definition | dashboard |
| Action Group + fünf Metric Alerts | `Microsoft.Insights/actionGroups`, `metricAlerts` | nur mit `enableAlerts` | metricalerts, dlqmetricalert |
| Rollenzuweisungen | `Microsoft.Authorization/roleAssignments` | nur mit `enableManagedIdentity` | roleassignments |

## Queues

Alle Queues haben `deadLetteringOnMessageExpiration = true`, TTL `defaultMessageTimeToLive`
(Default `P14D`) und `lockDuration` (Default `PT30S`).

| Queue | Zweck | MaxDeliveryCount |
|---|---|---|
| `sbqhighexport`, `sbqexport`, `sbqlowexport` | Verarbeitung nach Priorität | `maxDeliveryCount` (Default 3) |
| `sbqtransitivehigh`, `sbqtransitivestandart`, `sbqtransitivelow` | Ablage bei Konflikten im Ziel (HTTP 409); kein Trigger | `maxDeliveryCount × 2` |
| `sbqignored` | Veraltete Nachrichten bei `SkipOutdatedMessages`; kein Trigger | `maxDeliveryCount` |

Die Schreibweise `standart` ist in Code und Bicep konsistent und darf nicht geändert werden,
weil bestehende Deployments die Queue unter diesem Namen besitzen.

## App-Settings der Function App

| Setting | Quelle |
|---|---|
| `APPLICATIONINSIGHTS_CONNECTION_STRING` | Output des AI-Moduls |
| `AzureWebJobsStorage` bzw. `AzureWebJobsStorage__accountName` | Key-basiert per `listKeys()` oder identitätsbasiert, je nach `enableManagedIdentity` |
| `ExportQueueServiceBus` bzw. `ExportQueueServiceBus__fullyQualifiedNamespace` | analog für den Service Bus |
| `TARGET_BASED_SCALING_ENABLED` | `0`, nur im schlüsselbasierten Modus (ohne `enableManagedIdentity`) |
| `WEBSITE_CONTENTAZUREFILECONNECTIONSTRING` | immer key-basiert (Content Share) |
| `FUNCTIONS_EXTENSION_VERSION`, `FUNCTIONS_WORKER_RUNTIME` | `~4`, `dotnet-isolated` |
| `WEBSITE_RUN_FROM_PACKAGE` | `1` |
| `GetChangesTimerExpression` | Parameter, Default `*/15 * * * * *` |
| `SkipOutdatedMessages` | Parameter, Default `false` |
| `TELEMETRY_CONTROL`, `TELEMETRY_INFO_SAMPLE_RATE`, `TELEMETRY_DEPENDENCY_SAMPLE_RATE`, `TELEMETRY_DEPENDENCY_SLOW_MS` | Parameter, siehe [Logging](/docs/betrieb/logging/) |
| `AzureWebJobs.<Name>.Disabled` | aus dem Array `disabledFunctions` |

`alwaysOn` wird nicht gesetzt. Für Premium-Pläne kann das manuell nachgezogen werden.

## Managed Identity und Rollen

Die System-Identity der Function App wird **immer** angelegt. Mit
`enableManagedIdentity = true` entfallen die Schlüssel in den App-Settings, stattdessen
weist `roleassignments.bicep` folgende Rollen zu:

| Rolle | Ressource | Grund |
|---|---|---|
| Storage Table Data Contributor | Storage Account | Konfigurationstabellen, Durable-Tabellen |
| Storage Blob Data Owner | Storage Account | Durable-Hub-Blobs |
| Storage Queue Data Contributor | Storage Account | Durable-Hub-Queues |
| Azure Service Bus Data Sender | Namespace | Enqueue |
| Azure Service Bus Data Receiver | Namespace | Dequeue |
| Azure Service Bus Data Owner | Namespace | Queue-Laufzeitdaten für die MCP-Tools `list_queue_statuses` und `get_queue_status` |

`SettingsService` liefert Connection-Strings tolerant (null statt Exception);
`StorageService` und `ServiceBusService` bauen ihre Clients aus dem Connection-String, wenn
vorhanden, sonst über `DefaultAzureCredential`.

## Alerts

Mit `enableAlerts` entstehen eine Action Group (E-Mail an `notificationEmail`), vier
DLQ-Alerts auf `DeadletteredMessages` (Info ≥ 1, Warning > 50, Error > 200, Critical > 500,
Schwellen parametrisierbar) und ein Queue-Längen-Alert auf `ActiveMessages > 300000`. Alle
Alerts sind namespace-weit (`EntityName = *`). Anwendersicht:
[Monitoring & Alerts](/docs/betrieb/monitoring/).

## Netzwerk

Es gibt keine VNet-Integration, keine Private Endpoints und keine IP-Restriktionen.
Storage, Service Bus und Function App sind öffentlich erreichbar; Transport ist TLS 1.2
bzw. HTTPS. Netzwerk-Isolation wäre eine Erweiterung des Bicep-Deployments.

## Parameterdateien

`bicep/params/databridge.sample.bicepparam` ist die Vorlage mit allen Parametern.
Kundenspezifische Parameterdateien liegen daneben im Repository und werden von
`cicd/manage/deploy_bicep.yml` verwendet. `storageKind` erlaubt nur `StorageV2`; ältere
Parameterdateien mit `Storage` schlagen an der Validierung fehl.

## Marketplace-Artefakte

- `bicep/marketplace/mainTemplate.json` wird mit `GenerateMarketplace.sh` aus `main.bicep`
  erzeugt und muss nach jeder Bicep-Änderung neu generiert und committet werden.
- `createUiDefinition.json` ist Handarbeit und bildet die Parameter auf den
  Marketplace-Assistenten ab.

## CI/CD

- `cicd/manage/build_and_deploy_functionapp.yml` baut das Zip, setzt die Version
  (`VersionMajor.VersionMinor.yyyy.MMdd`) und veröffentlicht ein globales Artefakt.
- `cicd/manage/deploy_bicep.yml` rollt Infrastruktur und Zip je Kunde aus.
- `cicd/manage/build_docfx_and_publish.yml` baut und veröffentlicht diese Dokumentation
  (der Dateiname stammt noch aus der DocFX-Zeit).
