Ejercicio: Refactorización del archivo de Bicep

Completado

En el ejercicio anterior, creó un archivo de Bicep inicial que contiene la máquina virtual del camión de juguete y los recursos asociados. pero la plantilla de Bicep no sigue los procedimientos recomendados y es un poco difícil de leer. En esta unidad, refactorizará el archivo.

Durante el proceso de refactorización, hará lo siguiente:

  • Actualizar los nombres simbólicos de los recursos y parámetros.
  • Quitar los recursos, propiedades y parámetros redundantes.
  • Agregar variables y parámetros para que el archivo de Bicep sea reutilizable.

Actualización de los nombres simbólicos del recurso

  1. En Visual Studio Code, abra el archivo main.bicep.

  2. Seleccione el nombre simbólico del recurso del grupo de seguridad de red, cuyo nombre es networkSecurityGroups_ToyTruckServer_nsg_name_resource o similar.

    Cambie el nombre simbólico. Presione F2, o bien haga clic con el botón derecho y seleccione Cambiar el nombre del símbolo.

    Escriba el nombrenetworkSecurityGroup y presione Entrar. Visual Studio Code actualiza el nombre y todas las referencias dentro del archivo.

  3. Repita este proceso para cada recurso. Cambie el nombre de los recursos como se muestra en la tabla siguiente.

    Nota:

    Los nombres de los recursos de su implementación serán ligeramente diferentes a los de la tabla. Busque los recursos que tengan nombres parecidos a estos.

    Tipo de recurso Nombre simbólico actual Nombre simbólico nuevo
    Dirección IP pública publicIPAddresses_ToyTruckServer_ip_name_resource publicIPAddress
    Máquina virtual virtualMachines_ToyTruckServer_name_resource virtualMachine
    Virtual network virtualNetworks_ToyTruck_vnet_name_resource virtualNetwork
    Subnet virtualNetworks_ToyTruck_vnet_name_default defaultSubnet
    interfaz de red networkInterfaces_toytruckserver890_name_resource networkInterface

Eliminación del recurso de subred redundante

Actualmente, la subred de la red virtual está definida dos veces. Se define una vez en el recurso virtualNetwork y nuevamente como su propio recurso secundario denominado defaultSubnet. pero no tiene sentido definirla dos veces.

  1. Elimine el recurso defaultSubnet.

    Observe que el recurso networkInterface ahora muestra un problema, ya que hace referencia al identificador de recurso de la subred predeterminada:

    Screenshot of Visual Studio Code that shows the network interface resource definition. The error is highlighted.

  2. Actualice el recurso virtualNetwork para incluir una referencia existing a la subred. Al agregar la referencia existing, se puede volver a hacer referencia a la subred dentro del código de Bicep sin necesidad de volver a definirla:

    resource virtualNetwork 'Microsoft.Network/virtualNetworks@2020-11-01' = {
      name: virtualNetworks_ToyTruck_vnet_name
      location: 'westus'
      properties: {
        addressSpace: {
          addressPrefixes: [
            '10.0.0.0/16'
          ]
        }
        subnets: [
          {
            name: 'default'
            properties: {
              addressPrefix: '10.0.0.0/24'
              delegations: []
              privateEndpointNetworkPolicies: 'Enabled'
              privateLinkServiceNetworkPolicies: 'Enabled'
            }
          }
        ]
        virtualNetworkPeerings: []
        enableDdosProtection: false
      }
    
      resource defaultSubnet 'subnets' existing = {
        name: 'default'
      }
    }
    
  3. Actualice el recurso networkInterface para hacer referencia al identificador del recurso de la subred:

    resource networkInterface 'Microsoft.Network/networkInterfaces@2022-05-01' = {
      name: networkInterfaces_toytruckserver890_name
      location: 'westus3'
      properties: {
        ipConfigurations: [
          {
            name: 'ipconfig1'
            properties: {
              privateIPAddress: '10.0.0.4'
              privateIPAllocationMethod: 'Dynamic'
              publicIPAddress: {
                id: publicIPAddress.id
              }
              subnet: {
                id: virtualNetwork::defaultSubnet.id
              }
              primary: true
              privateIPAddressVersion: 'IPv4'
            }
          }
        ]
        dnsSettings: {
          dnsServers: []
        }
        enableAcceleratedNetworking: true
        enableIPForwarding: false
        disableTcpStateTracking: false
        networkSecurityGroup: {
          id: networkSecurityGroup.id
        }
        nicType: 'Standard'
      }
    }
    

    Observará un error que indica que la expresión participa de un ciclo. Podrá corregirlo en el paso siguiente.

  4. Vaya a la propiedad subnets del recurso virtualNetwork y quite id: defaultSubnet.id para resolver el error.

Cambio de los parámetros a variables

No es necesario que los parámetros de la plantilla sean parámetros, Ahora cambiará el nombre de los parámetros a nombres más significativos y los convertirá en variables.

  1. Seleccione el nombre simbólico del parámetro virtualNetworks_ToyTruck_vnet_name. Cambie su nombre a virtualNetworkName.

  2. Cambie el parámetro a una variable. No olvide quitar el tipo, ya que las definiciones de variables no incluyen tipos:

    var virtualNetworkName = 'ToyTruck-vnet'
    
  3. Repita el proceso para cada parámetro. Cambie el nombre de los parámetros tal como se muestra en la tabla siguiente.

    Observe que el valor de networkInterfaceName incluye un número de tres dígitos. El número es diferente para diferentes implementaciones. Asegúrese de copiar el valor de la variable de la plantilla de referencia.

    Nombre del parámetro actual Nuevo nombre de la variable
    virtualMachines_ToyTruckServer_name virtualMachineName
    networkInterfaces_toytruckserver890_name networkInterfaceName
    publicIPAddresses_ToyTruckServer_ip_name publicIPAddressName
    networkSecurityGroups_ToyTruckServer_nsg_name networkSecurityGroupName
  4. Compruebe que las declaraciones de variable tienen un aspecto similar al del ejemplo siguiente:

    var virtualNetworkName = 'ToyTruck-vnet'
    var virtualMachineName = 'ToyTruckServer'
    var networkInterfaceName = 'YOUR-NETWORK-INTERFACE-NAME'
    var publicIPAddressName = 'ToyTruckServer-ip'
    var networkSecurityGroupName = 'ToyTruckServer-nsg'
    

Actualización de las ubicaciones de los recursos

Actualmente, todos los recursos usan una ubicación codificada de forma rígida. Ahora agregará un parámetro para que la plantilla sea más reutilizable.

  1. En la parte superior del archivo, agregue un parámetro nuevo y un decorador de descripción para dejar claro el propósito del parámetro:

    @description('The location where resources are deployed.')
    param location string = resourceGroup().location
    
  2. Actualice cada recurso para usar el parámetro location en lugar de la ubicación codificada de forma rígida westus3.

Adición de parámetros y variables

En algunos lugares de su plantilla donde sería más adecuado utilizar parámetros o variables se incluyen algunos valores codificados de forma rígida. Ahora agregará parámetros para las propiedades que pudieran cambiar entre implementaciones y variables para los valores que no vayan a cambiar.

  1. En la parte superior del archivo main.bicep, debajo del parámetro location, agregue los siguientes parámetros:

    @description('The name of the size of the virtual machine to deploy.')
    param virtualMachineSizeName string = 'Standard_D2s_v3'
    
    @description('The name of the storage account SKU to use for the virtual machine\'s managed disk.')
    param virtualMachineManagedDiskStorageAccountType string = 'Premium_LRS'
    
    @description('The administrator username for the virtual machine.')
    param virtualMachineAdminUsername string = 'toytruckadmin'
    
    @description('The administrator password for the virtual machine.')
    @secure()
    param virtualMachineAdminPassword string
    
    @description('The name of the SKU of the public IP address to deploy.')
    param publicIPAddressSkuName string = 'Standard'
    
    @description('The virtual network address range.')
    param virtualNetworkAddressPrefix string
    
    @description('The default subnet address range within the virtual network')
    param virtualNetworkDefaultSubnetAddressPrefix string
    

    Algunos de los parámetros tienen valores predeterminados y otros no. Más adelante, creará un archivo de parámetros para establecer la mayoría de estos valores.

  2. Agregue las declaraciones de variables nuevas siguientes debajo de la variable networkSecurityGroupName:

    var virtualNetworkDefaultSubnetName = 'default'
    var virtualMachineImageReference = {
      publisher: 'canonical'
      offer: '0001-com-ubuntu-server-focal'
      sku: '20_04-lts-gen2'
      version: 'latest'
    }
    
  3. Agregue la declaración de variable siguiente. Reemplace los valores por el nombre del disco del sistema operativo de su propia plantilla de referencia.

    var virtualMachineOSDiskName = 'YOUR-OS-DISK-NAME'
    

    El valor de virtualMachineOSDiskName es único. El valor es diferente para cada implementación. Asegúrese de copiar el valor de la variable de la plantilla de referencia.

    Advertencia

    Asegúrese de copiar los valores correctos de las variables virtualMachineOSDiskName y networkInterfaceName. De lo contrario, Azure no detectará que está declarando recursos existentes y podría intentar crear recursos nuevos.

    Sus declaraciones de variable ahora deberían tener un aspecto similar al de este ejemplo:

    var virtualNetworkName = 'ToyTruck-vnet'
    var virtualMachineName = 'ToyTruckServer'
    var networkInterfaceName = 'YOUR-NETWORK-INTERFACE-NAME'
    var publicIPAddressName = 'ToyTruckServer-ip'
    var networkSecurityGroupName = 'ToyTruckServer-nsg'
    var virtualNetworkDefaultSubnetName = 'default'
    var virtualMachineImageReference = {
      publisher: 'canonical'
      offer: '0001-com-ubuntu-server-focal'
      sku: '20_04-lts-gen2'
      version: 'latest'
    }
    var virtualMachineOSDiskName = 'YOUR-OS-DISK-NAME'
    
  4. Actualice el recurso publicIPAddress para que haga referencia a un parámetro:

    Propiedad Parámetro
    sku.name publicIPAddressSkuName
  5. Actualice el recurso virtualMachine para hacer referencia a los parámetros y variables:

    Propiedad Parámetro o variable
    hardwareProfile.vmSize virtualMachineSizeName
    storageProfile.imageReference virtualMachineImageReference
    Use el nombre de la variable para reemplazar los valores del objeto, incluidas las llaves.
    storageProfile.osDisk.name virtualMachineOSDiskName
    storageProfile.osDisk.managedDisk.storageAccountType virtualMachineManagedDiskStorageAccountType
    osProfile.adminUsername virtualMachineAdminUsername
    osProfile.adminPassword
    Agregue esta propiedad debajo de osProfile.adminUsername.
    virtualMachineAdminPassword
  6. Actualice el recurso virtualNetwork para hacer referencia a los parámetros y variables:

    Propiedad Parámetro o variable
    addressSpace.addressPrefixes virtualNetworkAddressPrefix
    subnets.name virtualNetworkDefaultSubnetName
    subnets.addressPrefix virtualNetworkDefaultSubnetAddressPrefix
  7. Actualice el recurso anidado defaultSubnet del recurso virtualNetwork:

    Propiedad Variable
    name virtualNetworkDefaultSubnetName

Eliminación de propiedades innecesarias

El proceso de exportación agrega propiedades redundantes a muchos recursos. Siga estos pasos para quitar las propiedades innecesarias.

  1. En el recurso networkSecurityGroup, quite properties, ya que la propiedad securityRules está vacía.

  2. En el recurso publicIPAddress, quite las siguientes propiedades:

    • La propiedad ipAddress, ya que Azure la establece automáticamente
    • La propiedad ipTags, ya que está vacía
  3. En el recurso virtualMachine, quite las siguientes propiedades:

    • La propiedad storageProfile.osDisk.managedDisk.id, ya que Azure la determina automáticamente cuando se implementa la máquina virtual

      Importante

      Si no quita esta propiedad, la plantilla no se implementará correctamente.

    • La propiedad storageProfile.dataDisks, ya que está vacía

    • La propiedad osProfile.secrets, ya que está vacía

    • La propiedad osProfile.requireGuestProvisionSignal, ya que Azure la establece automáticamente

  4. En el recurso virtualNetwork, quite las siguientes propiedades:

    • Las propiedades delegations y virtualNetworkPeerings, ya que están vacías.
    • La línea de type: 'Microsoft.Network/virtualNetworks/subnets'
  5. En el recurso networkInterface, quite las siguientes propiedades:

    • La propiedad kind

    • De ipConfigurations: id, etag, type y privateIPAddress, ya que Azure la establece automáticamente y el método de asignación es dinámico

    • Desde ipConfigurations.properties:

      • provisioningState
    • De publicIPAddress, name, properties, type y sku

    • dnsSettings, ya que la propiedad dnsServers está vacía

Sugerencia

Cuando trabaje con sus propias plantillas, deberá determinar si hay alguna propiedad que debiera quitarse como hizo aquí.

En Visual Studio Code, la extensión de Bicep le ayuda a establecer las propiedades mínimas de un recurso. Al agregar un espacio después del signo igual en la definición de recurso, Visual Studio Code le pedirá que seleccione required-properties:

Screenshot of Visual Studio Code that shows the required-properties option.

Al seleccionar required-properties, Visual Studio Code rellena la definición de recurso con las propiedades que son obligatorias. Puede usar required-properties como referencia para determinar si todas las propiedades de su plantilla convertida deben estar presentes.

El repositorio de plantillas de inicio rápido de Azure también es útil para llevar a cabo esta tarea. Busque una plantilla de inicio rápido que haga aproximadamente lo mismo que está intentando hacer y observe las propiedades que establece en el recurso.

Creación de un archivo de parámetros

Los parámetros están definidos actualmente como valores predeterminados en su plantilla. Para que su plantilla funcione bien en todos los entornos, es recomendable crear un archivo de parámetros y quitar los valores predeterminados de los parámetros que deban cambiar en cada entorno.

  1. Cree un nuevo archivo denominado main.parameters.production.json.

  2. Pegue el siguiente JSON en el archivo main.parameters.production.json:

    {
      "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
      "contentVersion": "1.0.0.0",
      "parameters": {
        "virtualMachineSizeName": {
          "value": "Standard_D2s_v3"
        },
        "virtualMachineManagedDiskStorageAccountType": {
            "value": "Premium_LRS"
        },
        "virtualMachineAdminUsername": {
            "value": "toytruckadmin"
        },
        "virtualNetworkAddressPrefix": {
            "value": "YOUR-VIRTUAL-NETWORK-ADDRESS-PREFIX"
        },
        "virtualNetworkDefaultSubnetAddressPrefix": {
            "value": "YOUR-SUBNET-ADDRESS-PREFIX"
        }
      }
    }
    
  3. Actualice los valores de los parámetros virtualNetworkAddressPrefix y virtualNetworkDefaultSubnetAddressPrefix para que coincidan con los intervalos de direcciones IP especificados en el recurso de red virtual de su plantilla de referencia.

    Por ejemplo, aquí se muestra cómo se especifican los valores en una plantilla de referencia. Las direcciones IP podrían ser diferentes de las que se usan en este ejemplo.

    resource virtualNetworks_ToyTruck_vnet_name_resource 'Microsoft.Network/virtualNetworks@2022-05-01' = {
      name: virtualNetworks_ToyTruck_vnet_name
      location: 'westus3'
      properties: {
        addressSpace: {
          addressPrefixes: [
            '10.0.0.0/16'
          ]
        }
        subnets: [
          {
            name: 'default'
            id: virtualNetworks_ToyTruck_vnet_name_default.id
            properties: {
              addressPrefix: '10.0.0.0/24'
              delegations: []
              privateEndpointNetworkPolicies: 'Disabled'
              privateLinkServiceNetworkPolicies: 'Enabled'
            }
            type: 'Microsoft.Network/virtualNetworks/subnets'
          }
        ]
        virtualNetworkPeerings: []
        enableDdosProtection: false
      }
    }
    
  4. Actualice su archivo main.bicep para quitar los valores predeterminados de los parámetros especificados en el archivo de parámetros.

    • virtualMachineSizeName
    • virtualMachineManagedDiskStorageAccountType
    • virtualMachineAdminUsername

No cambie los valores predeterminados de los parámetros location y publicIPAddressSkuName, ya que es probable que dichos valores sean iguales en todos los entornos.

Comprobación de la plantilla

  1. Al final de la fase de refactorización, su archivo main.bicep debería tener un aspecto similar al del ejemplo siguiente:

    @description('The location where resources are deployed.')
    param location string = resourceGroup().location
    
    @description('The name of the size of the virtual machine to deploy.')
    param virtualMachineSizeName string
    
    @description('The name of the storage account SKU to use for the virtual machine\'s managed disk.')
    param virtualMachineManagedDiskStorageAccountType string
    
    @description('The administrator username for the virtual machine.')
    param virtualMachineAdminUsername string
    
    @description('The administrator password for the virtual machine.')
    @secure()
    param virtualMachineAdminPassword string
    
    @description('The name of the SKU of the public IP address to deploy.')
    param publicIPAddressSkuName string = 'Standard'
    
    @description('The virtual network address range.')
    param virtualNetworkAddressPrefix string
    
    @description('The default subnet address range within the virtual network')
    param virtualNetworkDefaultSubnetAddressPrefix string
    
    var virtualNetworkName = 'ToyTruck-vnet'
    var virtualMachineName = 'ToyTruckServer'
    var networkInterfaceName = 'YOUR-NETWORK-INTERFACE-NAME'
    var publicIPAddressName = 'ToyTruckServer-ip'
    var networkSecurityGroupName = 'ToyTruckServer-nsg'
    var virtualNetworkDefaultSubnetName = 'default'
    var virtualMachineImageReference = {
      publisher: 'canonical'
      offer: '0001-com-ubuntu-server-focal'
      sku: '20_04-lts-gen2'
      version: 'latest'
    }
    var virtualMachineOSDiskName = 'YOUR-OS-DISK-NAME'
    
    resource networkSecurityGroup 'Microsoft.Network/networkSecurityGroups@2022-05-01' = {
      name: networkSecurityGroupName
      location: location
    }
    
    resource publicIPAddress 'Microsoft.Network/publicIPAddresses@2022-05-01' = {
      name: publicIPAddressName
      location: location
      sku: {
        name: publicIPAddressSkuName
        tier: 'Regional'
      }
      properties: {
        publicIPAddressVersion: 'IPv4'
        publicIPAllocationMethod: 'Static'
        idleTimeoutInMinutes: 4
      }
    }
    
    resource virtualMachine 'Microsoft.Compute/virtualMachines@2022-08-01' = {
      name: virtualMachineName
      location: location
      properties: {
        hardwareProfile: {
          vmSize: virtualMachineSizeName
        }
        storageProfile: {
          imageReference: virtualMachineImageReference
          osDisk: {
            osType: 'Linux'
            name: virtualMachineOSDiskName
            createOption: 'FromImage'
            caching: 'ReadWrite'
            managedDisk: {
              storageAccountType: virtualMachineManagedDiskStorageAccountType
            }
            deleteOption: 'Delete'
            diskSizeGB: 30
          }
        }
        osProfile: {
          computerName: virtualMachineName
          adminUsername: virtualMachineAdminUsername
          adminPassword: virtualMachineAdminPassword
          linuxConfiguration: {
            disablePasswordAuthentication: false
            provisionVMAgent: true
            patchSettings: {
              patchMode: 'ImageDefault'
              assessmentMode: 'ImageDefault'
            }
            enableVMAgentPlatformUpdates: false
          }
          allowExtensionOperations: true
        }
        networkProfile: {
          networkInterfaces: [
            {
              id: networkInterface.id
              properties: {
                deleteOption: 'Detach'
              }
            }
          ]
        }
        diagnosticsProfile: {
          bootDiagnostics: {
            enabled: true
          }
        }
      }
    }
    
    resource virtualNetwork 'Microsoft.Network/virtualNetworks@2022-05-01' = {
      name: virtualNetworkName
      location: location
      properties: {
        addressSpace: {
          addressPrefixes: [
            virtualNetworkAddressPrefix
          ]
        }
        subnets: [
          {
            name: virtualNetworkDefaultSubnetName
            properties: {
              addressPrefix: virtualNetworkDefaultSubnetAddressPrefix
              privateEndpointNetworkPolicies: 'Disabled'
              privateLinkServiceNetworkPolicies: 'Enabled'
            }
          }
        ]
        enableDdosProtection: false
      }
    
      resource defaultSubnet 'subnets' existing = {
        name: virtualNetworkDefaultSubnetName
      }
    }
    
    resource networkInterface 'Microsoft.Network/networkInterfaces@2022-05-01' = {
      name: networkInterfaceName
      location: location
      properties: {
        ipConfigurations: [
          {
            name: 'ipconfig1'
            properties: {
              privateIPAllocationMethod: 'Dynamic'
              publicIPAddress: {
                id: publicIPAddress.id
              }
              subnet: {
                id: virtualNetwork::defaultSubnet.id
              }
              primary: true
              privateIPAddressVersion: 'IPv4'
            }
          }
        ]
        enableAcceleratedNetworking: true
        enableIPForwarding: false
        disableTcpStateTracking: false
        networkSecurityGroup: {
          id: networkSecurityGroup.id
        }
        nicType: 'Standard'
      }
    }
    

    Su archivo main.parameters.production.json debería tener un aspecto similar al del archivo siguiente, aunque puede que aparezcan intervalos de direcciones IP diferentes:

    {
      "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
      "contentVersion": "1.0.0.0",
      "parameters": {
        "virtualMachineSizeName": {
          "value": "Standard_D2s_v3"
        },
        "virtualMachineManagedDiskStorageAccountType": {
            "value": "Premium_LRS"
        },
        "virtualMachineAdminUsername": {
            "value": "toytruckadmin"
        },
        "virtualNetworkAddressPrefix": {
            "value": "10.0.0.0/16"
        },
        "virtualNetworkDefaultSubnetAddressPrefix": {
            "value": "10.0.0.0/24"
        }
      }
    }
    
  2. Seleccione Ver>Problemas para mostrar el panel de problemas.

    No se indican problemas.

Sugerencia

Cuando trabaja con sus propias plantillas, puede elegir opciones diferentes en cuanto a las propiedades que se van a parametrizar y otras personalizaciones. A lo largo de este módulo, se proporcionan instrucciones generales para ayudarle a empezar a trabajar, pero deberá tener en cuenta su propio entorno y cómo quiere reutilizar sus plantillas cuando decida la forma en que refactorizará sus propios archivos de Bicep.