CloudTrips benötigt eine vollständige wiederholbare Umgebung? Mit Bicep erstellen
CloudTrips kann einen Speicher-Workload bereitstellen. Eine nutzbare Anwendungsgrundlage benötigt jedoch zusätzlich einen sicheren Ort für Geheimnisse und ein gemeinsames Monitoringziel. Würden diese Ressourcen manuell erstellt, hätten DEV, TEST und PROD unterschiedliche Namen, Tags, Einstellungen und Bereitstellungsverläufe.
Erstelle die vollständige Grundlage über einen einzigen Bicep-Einstiegspunkt auf Abonnementebene. In diesem Lernpfad bedeutet „vollständige Umgebung“:
- eine Ressourcengruppe
- ein Speicherkonto mit umgebungsspezifischen Containern
- einen Key Vault mit Azure RBAC
- einen Log-Analytics-Arbeitsbereich
- eine arbeitsbereichsbasierte Application-Insights-Ressource
- einheitliche Tags für Besitzer, Kosten, Umgebung und Verwaltung
Anwendungscompute und Netzwerk liegen außerhalb dieses Labs. Sie können später als weitere Module ergänzt werden, ohne die hier aufgebaute Struktur zu ändern.
Dieses Abschluss-Lab baut auf folgenden Trips auf: Bereitstellungsbereiche verwenden und Azure Verified Modules verwenden. Schließe sie zuerst ab, da dieses Lab deren Einstiegspunkt auf Abonnementebene, Parameterdateien, modularen Workload und Storage-Wrapper erweitert. Der Trip zu Deployment Stacks ist ein separates Lebenszyklus-Lab und nicht erforderlich.
Das Key-Vault-Modul hinzufügen
Erstelle cloudtrips-bicep/modules/key-vault.bicep. Der Name ist
deterministisch und zugleich global eindeutig, weil er die Umgebung mit einem
Hash der Ressourcengruppen-ID kombiniert:
param environment string
param location string
param tags object
var keyVaultName = 'kvct${toLower(environment)}${uniqueString(resourceGroup().id)}'
resource keyVault 'Microsoft.KeyVault/vaults@2026-02-01' = {
name: keyVaultName
location: location
tags: tags
properties: {
accessPolicies: []
enablePurgeProtection: true
enableRbacAuthorization: true
enableSoftDelete: true
enabledForDeployment: false
enabledForDiskEncryption: false
enabledForTemplateDeployment: false
networkAcls: {
bypass: 'AzureServices'
defaultAction: 'Allow'
ipRules: []
virtualNetworkRules: []
}
publicNetworkAccess: 'Enabled'
sku: {
family: 'A'
name: 'standard'
}
softDeleteRetentionInDays: 7
tenantId: tenant().tenantId
}
}
output keyVaultName string = keyVault.name
output keyVaultId string = keyVault.id
output keyVaultUri string = keyVault.properties.vaultUri
Das Modul erstellt die Vault-Grenze, aber keine Geheimnisse. Geheimniswerte
dürfen nicht in das Repository geschrieben werden.
enableRbacAuthorization: true bedeutet, dass der Zugriff über Azure-Rollen
und nicht über ältere Key-Vault-Zugriffsrichtlinien vergeben wird.
Purge Protection ist aktiviert und kann später nicht mehr deaktiviert werden. Der öffentliche Netzwerkzugriff hält die Lernbereitstellung ohne virtuelles Netzwerk nutzbar. In einem Produktionsdesign kann der Vault zusätzlich hinter einem Private Endpoint liegen.
Das Monitoringmodul hinzufügen
Erstelle cloudtrips-bicep/modules/monitoring.bicep. Es stellt zuerst den
Log-Analytics-Arbeitsbereich bereit und verbindet Application Insights damit:
param environment string
param location string
param tags object
var resourceSuffix = uniqueString(resourceGroup().id)
var logAnalyticsWorkspaceName = 'log-ct-${toLower(environment)}-${resourceSuffix}'
var applicationInsightsName = 'appi-ct-${toLower(environment)}-${resourceSuffix}'
resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2025-07-01' = {
name: logAnalyticsWorkspaceName
location: location
tags: tags
properties: {
features: {
disableLocalAuth: false
enableLogAccessUsingOnlyResourcePermissions: true
}
publicNetworkAccessForIngestion: 'Enabled'
publicNetworkAccessForQuery: 'Enabled'
retentionInDays: 30
sku: {
name: 'PerGB2018'
}
workspaceCapping: {
dailyQuotaGb: 1
}
}
}
resource applicationInsights 'Microsoft.Insights/components@2020-02-02' = {
name: applicationInsightsName
location: location
tags: tags
kind: 'web'
properties: {
Application_Type: 'web'
DisableIpMasking: false
DisableLocalAuth: false
Flow_Type: 'Bluefield'
IngestionMode: 'LogAnalytics'
RetentionInDays: 90
SamplingPercentage: 100
WorkspaceResourceId: logAnalyticsWorkspace.id
publicNetworkAccessForIngestion: 'Enabled'
publicNetworkAccessForQuery: 'Enabled'
}
}
output logAnalyticsWorkspaceName string = logAnalyticsWorkspace.name
output logAnalyticsWorkspaceId string = logAnalyticsWorkspace.id
output applicationInsightsName string = applicationInsights.name
output applicationInsightsId string = applicationInsights.id
WorkspaceResourceId: logAnalyticsWorkspace.id ist eine symbolische Referenz.
Bicep leitet daraus ab, dass Application Insights auf den Arbeitsbereich warten
muss.
Das tägliche Limit von einem Gigabyte begrenzt versehentliche Datenaufnahme in der Lernumgebung. Monitoringressourcen können dennoch Azure-Kosten verursachen.
Den Einstiegspunkt zum Umgebungsorchestrator machen
Behalte die vorhandenen Parameter in cloudtrips-bicep/main.bicep. Ergänze ein
gemeinsames Tagobjekt, damit jedes neue Modul dieselben Geschäftsdaten erhält:
var commonTags = {
Application: applicationName
CostCenter: costCenter
Environment: toUpper(environment)
ManagedBy: 'Bicep'
Owner: owner
}
Behalte das vorhandene Modul storage und ergänze:
module keyVault './modules/key-vault.bicep' = {
name: '${deployment().name}-key-vault'
params: {
environment: environment
location: location
tags: commonTags
}
}
module monitoring './modules/monitoring.bicep' = {
name: '${deployment().name}-monitoring'
params: {
environment: environment
location: location
tags: commonTags
}
}
Gib die wichtigen Modulergebnisse und eine kompakte Bereitstellungszusammenfassung aus:
output keyVaultName string = keyVault.outputs.keyVaultName
output keyVaultId string = keyVault.outputs.keyVaultId
output keyVaultUri string = keyVault.outputs.keyVaultUri
output logAnalyticsWorkspaceName string = monitoring.outputs.logAnalyticsWorkspaceName
output logAnalyticsWorkspaceId string = monitoring.outputs.logAnalyticsWorkspaceId
output applicationInsightsName string = monitoring.outputs.applicationInsightsName
output applicationInsightsId string = monitoring.outputs.applicationInsightsId
output environmentSummary object = {
applicationInsightsName: monitoring.outputs.applicationInsightsName
keyVaultName: keyVault.outputs.keyVaultName
logAnalyticsWorkspaceName: monitoring.outputs.logAnalyticsWorkspaceName
resourceGroupName: resourceGroup().name
storageAccountName: storage.outputs.storageAccountName
}
Reiche diese Outputs durch subscription.bicep weiter. Diese Datei bleibt der
einzige Befehlseinstiegspunkt, der die Ressourcengruppe erstellt und darin
anschließend main.bicep ausführt.
Die Parameterdateien der Umgebungen vervollständigen
Die vorhandenen Parameterdateien auf Ressourcengruppenebene funktionieren weiter, weil sich der Eingabevertrag nicht geändert hat. Ergänze neben der vorhandenen TEST-Datei Abonnementdateien für DEV und PROD:
environments/dev.subscription.bicepparamenvironments/test.subscription.bicepparamenvironments/prod.subscription.bicepparam
Jede Datei verweist auf subscription.bicep und liefert einen eigenen
Ressourcengruppennamen, eine Redundanzstufe, eine Kostenstelle, eine
Containerliste und die Entscheidung zum Audit-Container. PROD verwendet zum
Beispiel Standard_ZRS, drei Anwendungscontainer und den Audit-Container. DEV
bleibt bei Standard_LRS und nur uploads.
Die vollständige Lösung validieren
Prüfe im Stammverzeichnis des Repositorys jeden Einstiegspunkt und jedes neue Modul:
az bicep lint \
--file cloudtrips-bicep/modules/key-vault.bicep
az bicep lint \
--file cloudtrips-bicep/modules/monitoring.bicep
az bicep lint \
--file cloudtrips-bicep/main.bicep
az bicep lint \
--file cloudtrips-bicep/subscription.bicep
Kompiliere die Verträge aller drei Umgebungen:
az bicep build-params \
--file cloudtrips-bicep/environments/dev.subscription.bicepparam \
--stdout > /dev/null
az bicep build-params \
--file cloudtrips-bicep/environments/test.subscription.bicepparam \
--stdout > /dev/null
az bicep build-params \
--file cloudtrips-bicep/environments/prod.subscription.bicepparam \
--stdout > /dev/null
Fahre fort, wenn alle Befehle ohne Diagnosemeldungen abgeschlossen werden.
Der freigegebene TEST-Snapshot muss sich jetzt ändern, weil Key Vault und Monitoring beabsichtigte Ergänzungen sind. Prüfe die kompilierte Änderung und erzeuge danach mit demselben deterministischen Kontext wie zuvor die neue Baseline:
"$HOME/.azure/bin/bicep" snapshot cloudtrips-bicep/environments/test.bicepparam \
--mode overwrite \
--subscription-id 00000000-0000-0000-0000-000000000000 \
--resource-group rg-cloudtrips-bicep-test-weu \
--location westeurope \
--deployment-name deploy-cloudtrips-storage-test
"$HOME/.azure/bin/bicep" snapshot cloudtrips-bicep/environments/test.bicepparam \
--mode validate \
--subscription-id 00000000-0000-0000-0000-000000000000 \
--resource-group rg-cloudtrips-bicep-test-weu \
--location westeurope \
--deployment-name deploy-cloudtrips-storage-test
Die vollständige TEST-Umgebung in der Vorschau prüfen
Wähle das TEST-Abonnement aus und führe die Azure-Preflightvalidierung aus:
az account set \
--subscription "<Name oder ID des CloudTrips-TEST-Abonnements>"
az deployment sub validate \
--name validate-cloudtrips-complete-test \
--location westeurope \
--parameters cloudtrips-bicep/environments/test.subscription.bicepparam \
--validation-level Provider \
--query "properties.provisioningState" \
--output tsv
Das Ergebnis sollte Succeeded sein. Prüfe nun die Liveänderung:
az deployment sub what-if \
--name preview-cloudtrips-complete-test \
--location westeurope \
--parameters cloudtrips-bicep/environments/test.subscription.bicepparam \
--validation-level Provider
Die Vorschau sollte den Key Vault, den Log-Analytics-Arbeitsbereich,
Application Insights und deren Modulbereitstellungen erstellen. Sie darf das
vorhandene Speicherkonto oder seine Container nicht neu erstellen. Bereits
bekannte Standardwerte der Provider können weiterhin als Modify erscheinen.

Die Umgebung bereitstellen und prüfen
Stelle die vollständige TEST-Grundlage bereit:
az deployment sub create \
--name deploy-cloudtrips-complete-test \
--location westeurope \
--parameters cloudtrips-bicep/environments/test.subscription.bicepparam \
--query "properties.outputs.environmentSummary.value" \
--output yaml
Die Zusammenfassung sollte die TEST-Ressourcengruppe und die deterministischen Namen des Speicherkontos, des Key Vaults, des Log-Analytics-Arbeitsbereichs und von Application Insights enthalten.

Liste die bereitgestellten Ressourcen der obersten Ebene auf:
az resource list \
--resource-group rg-cloudtrips-bicep-test-weu \
--query "[].{name:name,type:type,location:location}" \
--output table
Bestätige, dass die Ressourcengruppe das Speicherkonto, den Key Vault, den Log-Analytics-Arbeitsbereich und Application Insights enthält. Öffne die Ressourcengruppe im Azure-Portal und prüfe die erwarteten Werte für TEST, Besitzer und Kostenstelle in den gemeinsamen Tags.


Die Wiederholbarkeit der Bereitstellung beweisen
Führe nach der Bereitstellung denselben
az deployment sub what-if-Befehl erneut aus. Es dürfen keine neuen
Ressourcennamen, Ersetzungen oder unerwarteten Löschungen erscheinen.
Standardwerte der Azure-Provider können weiterhin als Modify angezeigt
werden, die vier Ressourcen der obersten Ebene müssen jedoch dieselben bleiben.
Das Ergebnis ist wiederholbar, weil Umgebungsunterschiede in Parameterdateien liegen, die Benennung deterministisch ist, Dienste in Module getrennt sind, Abhängigkeiten aus symbolischen Referenzen entstehen und der Einstiegspunkt auf Abonnementebene den Bereichswechsel verwaltet. CloudTrips kann dieselbe Anwendungsgrundlage nun konsistent prüfen und erneut erstellen, anstatt sie manuell zusammenzubauen.