Oefening: Uw Bicep-bestand herstructureren
Nadat u uw sjabloon met uw collega's hebt gecontroleerd, besluit u het bestand te herstructureren om het voor hen gemakkelijker te maken om mee te werken. In deze oefening past u de aanbevolen procedures toe die u in de voorgaande lessen hebt geleerd.
Uw taak
Bekijk de Bicep-sjabloon die u eerder hebt opgeslagen. Denk na over het advies dat u hebt gelezen over het structuren van uw sjablonen. Werk uw sjabloon bij zodat uw collega's het gemakkelijker kunnen begrijpen.
In de volgende secties verwijzen we naar specifieke onderdelen van de sjabloon en enkele hints over dingen die u mogelijk wilt wijzigen. We bieden een voorgestelde oplossing, maar uw sjabloon kan er anders uitzien, wat perfect in orde is.
Tip
Wanneer u het herstructureringsproces doorloopt, is het goed om ervoor te zorgen dat uw Bicep-bestand geldig is en dat u niet per ongeluk fouten hebt geïntroduceerd. De Bicep-extensie voor Visual Studio Code helpt hierbij. Let op rode of gele golvende lijnen onder uw code, omdat deze duiden op een fout of waarschuwing. U kunt ook een lijst met de problemen in uw bestand bekijken door Problemen weergeven>te selecteren.
De parameters bijwerken
Sommige parameters in uw sjabloon zijn niet duidelijk. Denk bijvoorbeeld aan deze parameters:
@allowed([ 'F1' 'D1' 'B1' 'B2' 'B3' 'S1' 'S2' 'S3' 'P1' 'P2' 'P3' 'P4' ]) param skuName string = 'F1' @minValue(1) param skuCapacity int = 1
Waar worden ze voor gebruikt?
Tip
Als u een parameter hebt die u wilt begrijpen, kan Visual Studio Code u hierbij helpen. Selecteer en houd een parameternaam ingedrukt (of klik er met de rechtermuisknop op) en selecteer Alle verwijzingen zoeken.
Moet de sjabloon de lijst met toegestane waarden voor de
skuName
parameter opgeven? Welke resources worden beïnvloed door verschillende waarden voor deze parameters te kiezen? Zijn er betere namen die u de parameters kunt geven?Tip
Wanneer u de naam van id's wijzigt, moet u de naam consistent wijzigen in alle onderdelen van uw sjabloon. Dit is met name belangrijk voor parameters, variabelen en resources waarnaar u in uw sjabloon verwijst.
Visual Studio Code biedt een handige manier om de naam van symbolen te wijzigen: selecteer de id die u wilt wijzigen, selecteer F2, voer een nieuwe naam in en selecteer vervolgens Enter:
Met deze stappen wijzigt u de naam van de id en werkt u automatisch alle verwijzingen ernaar bij.
De
managedIdentityName
parameter heeft geen standaardwaarde. Kunt u dat oplossen of, nog beter, de naam automatisch maken in de sjabloon?Bekijk de
roleDefinitionId
parameterdefinitie:param roleDefinitionId string = 'b24988ac-6180-42a0-ab88-20f7382dd24c'
Waarom is er een standaardwaarde van
b24988ac-6180-42a0-ab88-20f7382dd24c
? Wat betekent die lange id? Hoe weet iemand anders of deze standaardwaarde moet gebruiken of overschrijven? Wat kunt u doen om de id te verbeteren? Is het zelfs zinvol om dit als parameter te hebben?Tip
Deze id is de definitie-id van de rol inzender voor Azure. Hoe kunt u die informatie gebruiken om de sjabloon te verbeteren?
Wanneer iemand de sjabloon implementeert, hoe weet hij of zij waar elke parameter voor is? Kunt u enkele beschrijvingen toevoegen om de gebruikers van uw sjabloon te helpen?
Een configuratieset toevoegen
U spreekt uw collega's aan en besluit specifieke SKU's te gebruiken voor elke resource, afhankelijk van de omgeving die wordt geïmplementeerd. U besluit over deze SKU's voor elk van uw resources:
Bron SKU voor productie SKU voor niet-productie App Service-plan S1, twee exemplaren F1, één exemplaar Opslagaccount GRS LRS SQL-database S1 Basis Kunt u een configuratieset gebruiken om de parameterdefinities te vereenvoudigen?
De symbolische namen bijwerken
Bekijk de symbolische namen voor de resources in de sjabloon. Wat kunt u doen om ze te verbeteren?
Uw Bicep-sjabloon bevat resources met een verscheidenheid aan hoofdlettergebruiksstijlen voor hun symbolische namen, zoals:
-
storageAccount
enwebSite
, die camelCase-hoofdlettergebruik gebruiken. -
roleassignment
ensqlserver
, die gebruikmaken van platte hoofdlettergebruik. -
sqlserverName_databaseName
enAppInsights_webSiteName
, die slang hoofdlettergebruik gebruiken.
Kunt u deze herstellen om één stijl consistent te gebruiken?
-
Bekijk deze resource voor roltoewijzing:
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 } }
Is de symbolische naam beschrijvend genoeg om iemand anders te helpen met deze sjabloon te werken?
Tip
De reden waarom de identiteit een roltoewijzing nodig heeft, is dat de web-app de beheerde identiteit gebruikt om verbinding te maken met de databaseserver. Helpt dat u om dit in de sjabloon te verduidelijken?
Een paar resources hebben symbolische namen die niet overeenkomen met de huidige namen van Azure-resources:
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' = { // ... }
Beheerde identiteiten worden msis genoemd, App Service-abonnementen worden hostingplannen genoemd en App Service-apps worden websites genoemd.
Kunt u deze bijwerken naar de nieuwste namen om verwarring in de toekomst te voorkomen?
De blobcontainerdefinities vereenvoudigen
Bekijk hoe de blobcontainers worden gedefinieerd:
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}' }
Een van hen gebruikt de
parent
eigenschap en de andere niet. Kunt u deze oplossen om consistent te zijn?De namen van de blobcontainers veranderen niet tussen omgevingen. Denkt u dat de namen moeten worden opgegeven met behulp van parameters?
Er zijn twee blobcontainers. Kunnen ze worden geïmplementeerd met behulp van een lus?
De resourcenamen bijwerken
Er zijn enkele parameters waarmee resourcenamen expliciet worden ingesteld:
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'
Is er een andere manier om dit te doen?
Let op
Houd er rekening mee dat de naam van resources niet kan worden gewijzigd zodra ze zijn geïmplementeerd. Wanneer u sjablonen wijzigt die al in gebruik zijn, moet u voorzichtig zijn wanneer u de manier wijzigt waarop de sjabloon resourcenamen maakt. Als de sjabloon opnieuw wordt geïmplementeerd en de resource een nieuwe naam heeft, maakt Azure een andere resource. De oude resource kan zelfs worden verwijderd als u deze in de modus Volledig implementeert.
U hoeft zich hier geen zorgen te maken, omdat dit slechts een voorbeeld is.
De resourcenaam van de logische SQL-server wordt ingesteld met behulp van een variabele, ook al heeft deze een wereldwijd unieke naam nodig:
var sqlserverName = 'toywebsite${uniqueString(resourceGroup().id)}'
Hoe kun je dit verbeteren?
Afhankelijkheden en onderliggende resources bijwerken
Hier volgt een van uw resources, die een
dependsOn
eigenschap bevat. Heeft het echt nodig?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 ] }
U ziet hoe deze onderliggende resources worden gedeclareerd in uw sjabloon:
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 ] }
Hoe kunt u wijzigen hoe deze resources worden gedeclareerd? Zijn er andere resources in de sjabloon die ook moeten worden bijgewerkt?
Eigenschapswaarden bijwerken
Bekijk de resource-eigenschappen van de SQL-database:
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 } }
Is het zinvol om de eigenschapswaarde van
name
de SKU in code te codeeren? En wat zijn die rare waarden voor decollation
enmaxSizeBytes
eigenschappen?Tip
De
collation
enmaxSizeBytes
eigenschappen worden ingesteld op de standaardwaarden. Als u de waarden zelf niet opgeeft, worden de standaardwaarden gebruikt. Helpt dat u om te bepalen wat u met hen moet doen?Kunt u de manier wijzigen waarop de opslag verbindingsreeks is ingesteld, zodat de complexe expressie niet inline is gedefinieerd met de resource?
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}': {} } } }
Volgorde van elementen
Bent u tevreden met de volgorde van de elementen in het bestand? Hoe kunt u de leesbaarheid van het bestand verbeteren door de elementen te verplaatsen?
Bekijk de
databaseName
variabele. Behoort het tot waar het nu is?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 } }
Hebt u de uitgecommentareerde resource gezien?
webSiteConnectionStrings
Denk je dat dat in het bestand moet staan?
Opmerkingen, tags en andere metagegevens toevoegen
Denk na over iets in de sjabloon die misschien niet duidelijk is of die aanvullende uitleg nodig heeft. Kunt u opmerkingen toevoegen om het duidelijker te maken voor anderen die het bestand in de toekomst kunnen openen?
Bekijk de eigenschap van
webSite
deidentity
resource: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}': {} } } }
Die syntaxis is vreemd, hè? Denkt u dat dit een opmerking nodig heeft om het uit te leggen?
Bekijk de resource voor roltoewijzing:
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 } }
De resourcenaam maakt gebruik van de
guid()
functie. Zou het helpen om uit te leggen waarom?Kunt u een beschrijving toevoegen aan de roltoewijzing?
Kunt u een set tags toevoegen aan elke resource?
Voorgestelde oplossing
Hier volgt een voorbeeld van hoe u de sjabloon kunt herstructureren. Uw sjabloon ziet er mogelijk niet precies zo uit, omdat uw stijl mogelijk anders is.
@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'
}
}
Tip
Als u met uw collega's werkt met GitHub of Azure-opslagplaatsen, is dit een goed moment om een pull-aanvraag in te dienen om uw wijzigingen te integreren in de hoofdvertakking. Het is een goed idee om pull-aanvragen in te dienen nadat u een deel van het herstructureren van werk hebt uitgevoerd.