Übung: Umgestalten der Bicep-Datei
Nachdem Sie die Vorlage mit Ihren Kollegen überprüft haben, beschließen Sie, die Datei umzugestalten, um ihre Verwendung für die Kollegen zu vereinfachen. In dieser Übung wenden Sie die bewährten Methoden an, die Sie in den vorherigen Lerneinheiten kennengelernt haben.
Ihre Aufgabe
Überprüfen Sie die Bicep-Vorlage, die Sie zuvor gespeichert haben. Rufen Sie sich die Ratschläge aus der Lerneinheit zum Strukturieren Ihrer Vorlagen in Erinnerung. Versuchen Sie, Ihre Vorlage zu aktualisieren, damit sie für Ihre Kollegen leichter verständlich ist.
Die nächsten Abschnitte enthalten Verweise auf bestimmte Teile der Vorlage und Hinweise zu Dingen, die Sie ändern sollten. Wir stellen eine empfohlene Lösung bereit, jedoch muss Ihre Vorlage nicht damit übereinstimmen.
Tipp
Während der Umgestaltung sollten Sie sicherstellen, dass Ihre Bicep-Datei gültig ist und Sie nicht versehentlich Fehler eingeführt haben. Hierfür ist die Bicep-Erweiterung für Visual Studio Code hilfreich. Achten Sie auf rote oder gelbe Wellenlinien unter Ihrem Code, da sie auf einen Fehler oder eine Warnung hinweisen. Sie können auch eine Liste der Probleme in Ihrer Datei anzeigen, indem Sie Ansicht>Probleme auswählen.
Aktualisieren der Parameter
Die Bedeutung einiger Parameter in Ihrer Vorlage ist nicht ersichtlich. Betrachten Sie beispielsweise die folgenden Parameter:
@allowed([ 'F1' 'D1' 'B1' 'B2' 'B3' 'S1' 'S2' 'S3' 'P1' 'P2' 'P3' 'P4' ]) param skuName string = 'F1' @minValue(1) param skuCapacity int = 1
Zu welchem Zweck werden sie verwendet?
Tipp
Wenn Sie die Bedeutung eines Parameters ermitteln möchten, kann Visual Studio Code hilfreich sein. Klicken Sie an einer beliebigen Stelle in der Datei auf den Namen eines Parameters und halten Sie die Maustaste gedrückt (oder klicken Sie mit der rechten Maustaste auf den Parameter), und wählen Sie Alle Verweise suchen aus.
Muss in der Vorlage die Liste der zulässigen Werte für den
skuName
-Parameter angegeben werden? Welche Ressourcen sind betroffen, wenn unterschiedliche Werte für diese Parameter ausgewählt werden? Gibt es bessere Namen, die Sie den Parametern geben können?Tipp
Wenn Sie Bezeichner umbenennen, müssen Sie sie in allen Teilen der Vorlage konsistent umbenennen. Dies gilt insbesondere für Parameter, Variablen und Ressourcen, auf die Sie in der gesamten Vorlage verweisen.
Visual Studio Code bietet eine bequeme Möglichkeit zum Umbenennen von Symbolen: Wählen Sie den Bezeichner aus, den Sie umbenennen möchten, drücken Sie F2, geben Sie einen neuen Namen ein, und drücken Sie dann die EINGABETASTE:
Mit diesen Schritten wird der Bezeichner umbenannt und alle Verweise darauf werden automatisch aktualisiert.
Der Parameter
managedIdentityName
hat keinen Standardwert. Können Sie dies korrigieren oder den Namen automatisch in der Vorlage erstellen lassen (dies wäre die bessere Möglichkeit)?Sehen Sie sich die Definition des
roleDefinitionId
-Parameters an:param roleDefinitionId string = 'b24988ac-6180-42a0-ab88-20f7382dd24c'
Warum lautet der Standardwert
b24988ac-6180-42a0-ab88-20f7382dd24c
? Was bedeutet dieser lange Bezeichner? Wie kann eine andere Person erkennen, ob der Standardwert verwendet oder überschrieben werden soll? Was können Sie tun, um den Bezeichner zu verbessern? Ist die Verwendung dieses Parameters überhaupt sinnvoll?Tipp
Dieser Bezeichner ist die Rollendefinitions-ID der Rolle Mitwirkender für Azure. Wie können Sie diese Information verwenden, um die Vorlage zu verbessern?
Wie kann eine Person, die die Vorlage bereitstellt, den Zweck der einzelnen Parameter erkennen? Können Sie Beschreibungen hinzufügen, um die Benutzer Ihrer Vorlage zu unterstützen?
Hinzufügen eines Konfigurationssatzes
Sie sprechen mit Ihren Kollegen und entscheiden sich, für jede Ressource bestimmte SKUs abhängig von der bereitzustellenden Umgebung zu verwenden. Sie entscheiden sich für die folgenden SKUs für die einzelnen Ressourcen:
Resource SKU für Produktion SKU für Nicht-Produktion App Service-Plan S1, zwei Instanzen F1, eine Instanz Speicherkonto GRS LRS SQL-Datenbank S1 Basic Können Sie mit einem Konfigurationssatz die Parameterdefinitionen vereinfachen?
Aktualisieren der symbolischen Namen
Sehen Sie sich die symbolischen Namen für die Ressourcen in der Vorlage an. Wie können Sie diese verbessern?
Ihre Bicep-Vorlage enthält Ressourcen mit einer Vielzahl von Formaten der Groß-/Kleinschreibung für die symbolischen Namen, z. B.:
storageAccount
undwebSite
(camelCase-Schreibweise)roleassignment
undsqlserver
(Kleinschreibung)sqlserverName_databaseName
undAppInsights_webSiteName
(snake_case-Schreibweise)
Können Sie diese verschiedenen Schreibweisen vereinheitlichen?
Sehen Sie sich diese Ressource für die Rollenzuweisung an:
resource roleassignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { name: guid(roleDefinitionId, resourceGroup().id) properties: { principalType: 'ServicePrincipal' roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionId) principalId: msi.properties.principalId } }
Ist der symbolische Name für andere Benutzer dieser Vorlage aussagekräftig genug?
Tipp
Die Identität erfordert eine Rollenzuweisung, da die Web-App die verwaltete Identität zum Herstellen einer Verbindung mit dem Datenbankserver verwendet. Können Sie den Namen in der Vorlage anhand dieser Information aussagekräftiger machen?
Einige Ressourcen haben symbolische Namen, die nicht den aktuellen Namen der Azure-Ressourcen entsprechen:
resource hostingPlan 'Microsoft.Web/serverfarms@2023-12-01' = { // ... } resource webSite 'Microsoft.Web/sites@2023-12-01' = { // ... } resource msi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-07-31-preview' = { // ... }
Verwaltete Identitäten wurden früher als MSIs bezeichnet, App Service-Pläne wurden als Hostingpläne bezeichnet, und App Service-Apps wurden als Websites bezeichnet.
Können Sie diese Namen aktualisieren, um in Zukunft Verwirrung zu vermeiden?
Vereinfachen der Blobcontainerdefinitionen
Sehen Sie sich an, wie die Blobcontainer definiert sind:
resource container1 'Microsoft.Storage/storageAccounts/blobServices/containers@2023-05-01' = { parent: storageAccount::blobServices name: container1Name } resource productmanuals 'Microsoft.Storage/storageAccounts/blobServices/containers@2023-05-01' = { name: '${storageAccount.name}/default/${productmanualsName}' }
Für einen von ihnen wird die
parent
-Eigenschaft verwendet, und für den anderen wird sie nicht verwendet. Können Sie dies vereinheitlichen?Die Namen der Blobcontainer bleiben zwischen Umgebungen unverändert. Glauben Sie, dass die Namen mithilfe von Parametern angegeben werden müssen?
Es sind zwei Blobcontainer vorhanden. Können sie mithilfe einer Schleife bereitgestellt werden?
Aktualisieren der Ressourcennamen
Es sind einige Parameter vorhanden, die Ressourcennamen explizit festlegen:
param managedIdentityName string param roleDefinitionId string = 'b24988ac-6180-42a0-ab88-20f7382dd24c' param webSiteName string = 'webSite${uniqueString(resourceGroup().id)}' param container1Name string = 'productspecs' param productmanualsName string = 'productmanuals'
Lässt sich dies auf andere Weise durchführen?
Achtung
Beachten Sie, dass Ressourcen nicht umbenannt werden können, sobald sie bereitgestellt wurden. Gehen Sie beim Ändern bereits verwendeter Vorlagen vorsichtig vor, wenn Sie die Art und Weise ändern, in der durch die Vorlage Ressourcennamen erstellt werden. Wenn die Vorlage erneut bereitgestellt wird und die Ressource einen neuen Namen hat, erstellt Azure eine weitere Ressource. Die alte Ressource wird möglicherweise sogar gelöscht, wenn Sie sie im Modus Vollständig bereitstellen.
Sie brauchen sich hier keine Sorgen deswegen zu machen, da es sich nur um ein Beispiel handelt.
Der Ressourcenname des logischen SQL-Servers wird mithilfe einer Variablen festgelegt, obwohl er einen global eindeutigen Namen erfordert:
var sqlserverName = 'toywebsite${uniqueString(resourceGroup().id)}'
Wie können Sie dies verbessern?
Aktualisieren von Abhängigkeiten und untergeordneten Ressourcen
Unten ist eine Ihrer Ressourcen dargestellt, die die
dependsOn
-Eigenschaft enthält. Wird sie wirklich benötigt?resource sqlserverName_AllowAllAzureIPs 'Microsoft.Sql/servers/firewallRules@2023-08-01-preview' = { name: '${sqlserver.name}/AllowAllAzureIPs' properties: { endIpAddress: '0.0.0.0' startIpAddress: '0.0.0.0' } dependsOn: [ sqlserver ] }
Beachten Sie, wie diese untergeordneten Ressourcen in Ihrer Vorlage deklariert werden:
resource sqlserverName_databaseName 'Microsoft.Sql/servers/databases@2023-08-01-preview' = { name: '${sqlserver.name}/${databaseName}' location: location sku: { name: 'Basic' } properties: { collation: 'SQL_Latin1_General_CP1_CI_AS' maxSizeBytes: 1073741824 } } resource sqlserverName_AllowAllAzureIPs 'Microsoft.Sql/servers/firewallRules@2023-08-01-preview' = { name: '${sqlserver.name}/AllowAllAzureIPs' properties: { endIpAddress: '0.0.0.0' startIpAddress: '0.0.0.0' } dependsOn: [ sqlserver ] }
Wie können Sie die Deklaration dieser Ressourcen ändern? Gibt es weitere Ressourcen in der Vorlage, die ebenfalls aktualisiert werden sollten?
Aktualisieren von Eigenschaftswerten
Sehen Sie sich die Eigenschaften der SQL-Datenbankressource an:
resource sqlserverName_databaseName 'Microsoft.Sql/servers/databases@2023-08-01-preview' = { name: '${sqlserver.name}/${databaseName}' location: location sku: { name: 'Basic' } properties: { collation: 'SQL_Latin1_General_CP1_CI_AS' maxSizeBytes: 1073741824 } }
Ist es sinnvoll, den Wert der
name
-Eigenschaft der SKU hartzucodieren? Und was hat es mit den eigenartigen Werten für die Eigenschaftencollation
undmaxSizeBytes
auf sich?Tipp
Die Eigenschaften
collation
undmaxSizeBytes
sind auf die Standardwerte festgelegt. Wenn Sie die Werte nicht selbst angeben, werden die Standardwerte verwendet. Hilft Ihnen dies zu entscheiden, wie Sie diese Werte behandeln sollten?Können Sie die Art und Weise ändern, wie die Speicherverbindungszeichenfolge festgelegt wird, sodass der komplexe Ausdruck nicht inline mit der Ressource definiert wird?
resource webSite 'Microsoft.Web/sites@2023-12-01' = { name: webSiteName location: location properties: { serverFarmId: hostingPlan.id siteConfig: { appSettings: [ { name: 'APPINSIGHTS_INSTRUMENTATIONKEY' value: AppInsights_webSiteName.properties.InstrumentationKey } { name: 'StorageAccountConnectionString' value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};EndpointSuffix=${environment().suffixes.storage};AccountKey=${listKeys(storageAccount.id, storageAccount.apiVersion).keys[0].value}' } ] } } identity: { type: 'UserAssigned' userAssignedIdentities: { '${msi.id}': {} } } }
Reihenfolge der Elemente
Sind Sie mit der Reihenfolge der Elemente in der Datei einverstanden? Wie können Sie die Lesbarkeit der Datei verbessern, indem Sie die Elemente verschieben?
Werfen wir einen Blick auf die
databaseName
-Variable. Befindet sie sich an der richtigen Stelle?var databaseName = 'ToyCompanyWebsite' resource sqlserverName_databaseName 'Microsoft.Sql/servers/databases@2023-08-01-preview' = { name: '${sqlserver.name}/${databaseName}' location: location sku: { name: 'Basic' } properties: { collation: 'SQL_Latin1_General_CP1_CI_AS' maxSizeBytes: 1073741824 } }
Haben Sie die auskommentierte Ressource
webSiteConnectionStrings
bemerkt? Glauben Sie, dass dies in der Datei vorhanden sein muss?
Hinzufügen von Kommentaren, Tags und anderen Metadaten
Denken Sie an Inhalt der Vorlage, dessen Bedeutung nicht offensichtlich ist oder der eine zusätzliche Erläuterung erfordert. Können Sie Kommentare hinzufügen, um ihn für andere Benutzer, die die Datei in Zukunft möglicherweise öffnen, besser verständlich zu machen?
Sehen Sie sich die
identity
-Eigenschaft derwebSite
-Ressource an:resource webSite 'Microsoft.Web/sites@2023-12-01' = { name: webSiteName location: location properties: { serverFarmId: hostingPlan.id siteConfig: { appSettings: [ { name: 'APPINSIGHTS_INSTRUMENTATIONKEY' value: AppInsights_webSiteName.properties.InstrumentationKey } { name: 'StorageAccountConnectionString' value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};EndpointSuffix=${environment().suffixes.storage};AccountKey=${listKeys(storageAccount.id, storageAccount.apiVersion).keys[0].value}' } ] } } identity: { type: 'UserAssigned' userAssignedIdentities: { '${msi.id}': {} } } }
Finden Sie nicht auch, dass diese Syntax ungewöhnlich ist? Sind Sie der Meinung, dass ein erläuternder Kommentar erforderlich ist?
Sehen Sie sich die Ressource für die Rollenzuweisung an:
resource roleassignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { name: guid(roleDefinitionId, resourceGroup().id) properties: { principalType: 'ServicePrincipal' roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionId) principalId: msi.properties.principalId } }
Der Name der Ressource verwendet die
guid()
-Funktion. Ist es sinnvoll, den Grund dafür zu erläutern?Können Sie der Rollenzuweisung eine Beschreibung hinzufügen?
Können Sie jeder Ressource einen Satz von Tags hinzufügen?
Vorgeschlagene Lösung
Hier ist ein Beispiel dafür, wie Sie die Vorlage umgestalten können. Ihre Vorlage sieht möglicherweise nicht genau so aus, da Sie eventuell ein anderes Format verwenden.
@description('The location into which your Azure resources should be deployed.')
param location string = resourceGroup().location
@description('Select the type of environment you want to provision. Allowed values are Production and Test.')
@allowed([
'Production'
'Test'
])
param environmentType string
@description('A unique suffix to add to resource names that need to be globally unique.')
@maxLength(13)
param resourceNameSuffix string = uniqueString(resourceGroup().id)
@description('The administrator login username for the SQL server.')
param sqlServerAdministratorLogin string
@secure()
@description('The administrator login password for the SQL server.')
param sqlServerAdministratorLoginPassword string
@description('The tags to apply to each resource.')
param tags object = {
CostCenter: 'Marketing'
DataClassification: 'Public'
Owner: 'WebsiteTeam'
Environment: 'Production'
}
// Define the names for resources.
var appServiceAppName = 'webSite${resourceNameSuffix}'
var appServicePlanName = 'AppServicePLan'
var sqlServerName = 'sqlserver${resourceNameSuffix}'
var sqlDatabaseName = 'ToyCompanyWebsite'
var managedIdentityName = 'WebSite'
var applicationInsightsName = 'AppInsights'
var storageAccountName = 'toywebsite${resourceNameSuffix}'
var blobContainerNames = [
'productspecs'
'productmanuals'
]
@description('Define the SKUs for each component based on the environment type.')
var environmentConfigurationMap = {
Production: {
appServicePlan: {
sku: {
name: 'S1'
capacity: 2
}
}
storageAccount: {
sku: {
name: 'Standard_GRS'
}
}
sqlDatabase: {
sku: {
name: 'S1'
tier: 'Standard'
}
}
}
Test: {
appServicePlan: {
sku: {
name: 'F1'
capacity: 1
}
}
storageAccount: {
sku: {
name: 'Standard_LRS'
}
}
sqlDatabase: {
sku: {
name: 'Basic'
}
}
}
}
@description('The role definition ID of the built-in Azure \'Contributor\' role.')
var contributorRoleDefinitionId = 'b24988ac-6180-42a0-ab88-20f7382dd24c'
var storageAccountConnectionString = 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};EndpointSuffix=${environment().suffixes.storage};AccountKey=${listKeys(storageAccount.id, storageAccount.apiVersion).keys[0].value}'
resource sqlServer 'Microsoft.Sql/servers@2023-08-01-preview' = {
name: sqlServerName
location: location
tags: tags
properties: {
administratorLogin: sqlServerAdministratorLogin
administratorLoginPassword: sqlServerAdministratorLoginPassword
version: '12.0'
}
}
resource sqlDatabase 'Microsoft.Sql/servers/databases@2023-08-01-preview' = {
parent: sqlServer
name: sqlDatabaseName
location: location
sku: environmentConfigurationMap[environmentType].sqlDatabase.sku
tags: tags
}
resource sqlFirewallRuleAllowAllAzureIPs 'Microsoft.Sql/servers/firewallRules@2023-08-01-preview' = {
parent: sqlServer
name: 'AllowAllAzureIPs'
properties: {
endIpAddress: '0.0.0.0'
startIpAddress: '0.0.0.0'
}
}
resource appServicePlan 'Microsoft.Web/serverfarms@2023-12-01' = {
name: appServicePlanName
location: location
sku: environmentConfigurationMap[environmentType].appServicePlan.sku
tags: tags
}
resource appServiceApp 'Microsoft.Web/sites@2023-12-01' = {
name: appServiceAppName
location: location
tags: tags
properties: {
serverFarmId: appServicePlan.id
siteConfig: {
appSettings: [
{
name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
value: applicationInsights.properties.InstrumentationKey
}
{
name: 'StorageAccountConnectionString'
value: storageAccountConnectionString
}
]
}
}
identity: {
type: 'UserAssigned'
userAssignedIdentities: {
'${managedIdentity.id}': {} // This format is required when working with user-assigned managed identities.
}
}
}
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-05-01' = {
name: storageAccountName
location: location
sku: environmentConfigurationMap[environmentType].storageAccount.sku
kind: 'StorageV2'
properties: {
accessTier: 'Hot'
}
resource blobServices 'blobServices' existing = {
name: 'default'
resource containers 'containers' = [for blobContainerName in blobContainerNames: {
name: blobContainerName
}]
}
}
@description('A user-assigned managed identity that is used by the App Service app to communicate with a storage account.')
resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-07-31-preview'= {
name: managedIdentityName
location: location
tags: tags
}
@description('Grant the \'Contributor\' role to the user-assigned managed identity, at the scope of the resource group.')
resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(contributorRoleDefinitionId, resourceGroup().id) // Create a GUID based on the role definition ID and scope (resource group ID). This will return the same GUID every time the template is deployed to the same resource group.
properties: {
principalType: 'ServicePrincipal'
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', contributorRoleDefinitionId)
principalId: managedIdentity.properties.principalId
description: 'Grant the "Contributor" role to the user-assigned managed identity so it can access the storage account.'
}
}
resource applicationInsights 'Microsoft.Insights/components@2020-02-02' = {
name: applicationInsightsName
location: location
kind: 'web'
tags: tags
properties: {
Application_Type: 'web'
}
}
Tipp
Wenn Sie bei der Zusammenarbeit mit Ihren Kollegen GitHub oder Azure Repos verwenden, ist dies eine gute Gelegenheit, einen Pull Request zu übermitteln, um Ihre Änderungen in den Mainbranch zu integrieren. Es empfiehlt sich, einen Pull Requests zu übermitteln, nachdem Sie eine Umgestaltung durchgeführt haben.