Ejercicio: revisar la plantilla de Bicep existente

Completado

En nuestro escenario, nos sentamos a revisar la plantilla con los compañeros del equipo de control de calidad.

A medida que avanzamos juntos por la plantilla, nuestros compañeros comienzan a hacer una serie de preguntas sobre la estructura y los componentes del archivo. Parecen un poco confusos. ¿Quizá vendría bien mejorar la plantilla de algún modo para que sea más fácil de leer y entender?

Echemos un vistazo a la siguiente plantilla, que no habíamos visto antes. ¿Entendemos todo lo que la plantilla hace? ¿Cuántos problemas podríamos detectar? ¿Qué podríamos hacer para mejorar la plantilla?

param location string = resourceGroup().location

@allowed([
  'F1'
  'D1'
  'B1'
  'B2'
  'B3'
  'S1'
  'S2'
  'S3'
  'P1'
  'P2'
  'P3'
  'P4'
])
param skuName string = 'F1'

@minValue(1)
param skuCapacity int = 1
param sqlAdministratorLogin string

@secure()
param sqlAdministratorLoginPassword string

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'

var hostingPlanName = 'hostingplan${uniqueString(resourceGroup().id)}'
var sqlserverName = 'toywebsite${uniqueString(resourceGroup().id)}'
var storageAccountName = 'toywebsite${uniqueString(resourceGroup().id)}'

resource storageAccount 'Microsoft.Storage/storageAccounts@2023-05-01' = {
  name: storageAccountName
  location: 'eastus'
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
  properties: {
    accessTier: 'Hot'
  }

  resource blobServices 'blobServices' existing = {
    name: 'default'
  }
}

resource container1 'Microsoft.Storage/storageAccounts/blobServices/containers@2023-05-01' = {
  parent: storageAccount::blobServices
  name: container1Name
}

resource sqlserver 'Microsoft.Sql/servers@2023-08-01-preview' = {
  name: sqlserverName
  location: location
  properties: {
    administratorLogin: sqlAdministratorLogin
    administratorLoginPassword: sqlAdministratorLoginPassword
    version: '12.0'
  }
}

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
  }
}

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
  ]
}

resource productmanuals 'Microsoft.Storage/storageAccounts/blobServices/containers@2023-05-01' = {
  name: '${storageAccount.name}/default/${productmanualsName}'
}
resource hostingPlan 'Microsoft.Web/serverfarms@2023-12-01' = {
  name: hostingPlanName
  location: location
  sku: {
    name: skuName
    capacity: skuCapacity
  }
}

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}': {}
    }
  }
}

// We don't need this anymore. We use a managed identity to access the database instead.
//resource webSiteConnectionStrings 'Microsoft.Web/sites/config@2020-06-01' = {
//  name: '${webSite.name}/connectionstrings'
//  properties: {
//    DefaultConnection: {
//      value: 'Data Source=tcp:${sqlserver.properties.fullyQualifiedDomainName},1433;Initial Catalog=${databaseName};User Id=${sqlAdministratorLogin}@${sqlserver.properties.fullyQualifiedDomainName};Password=${sqlAdministratorLoginPassword};'
//      type: 'SQLAzure'
//    }
//  }
//}

resource msi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-07-31-preview' = {
  name: managedIdentityName
  location: location
}

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
  }
}

resource AppInsights_webSiteName 'Microsoft.Insights/components@2020-02-02' = {
  name: 'AppInsights'
  location: location
  kind: 'web'
  properties: {
    Application_Type: 'web'
  }
}

Crear y guardar el archivo de Bicep

A lo largo de este módulo, realizaremos algunos cambios que mejorarán la plantilla. Seguiremos los procedimientos recomendados para que la plantilla sea más fácil de leer y comprender, así como más manejable para los compañeros.

En primer lugar, debemos crear el archivo de Bicep y guardarlo localmente para poder trabajar con él.

  1. Abra Visual Studio Code.

  2. Cree un archivo con el nombre main.bicep.

  3. Copie la plantilla de Bicep anterior y péguela en el archivo.

  4. Guarde los cambios en el archivo.

Importante

El proceso consistente en mejorar el código reorganizándolo y cambiándolo de nombre se denomina refactorización. Al refactorizar código, es aconsejable usar un sistema de control de versiones, como Git. Gracias al control de versiones, podemos realizar cambios en el código, deshacer esos cambios o volver a una versión anterior.

En este módulo, no es necesario usar Git para llevar un seguimiento del archivo, pero conviene hacerlo, así que considérelo como opción extra.