Esercizio - Effettuare il refactoring del file Bicep

Completato

Nell'esercizio precedente è stato creato un file Bicep iniziale che contiene la macchina virtuale del camion giocattolo e le risorse associate. Tuttavia, il modello Bicep non segue le procedure consigliate ed è un po' difficile da leggere. In questa unità si effettuerà il refactoring del file.

Durante il processo di refactoring, si effettueranno le seguenti operazioni:

  • Aggiornare i nomi simbolici per le risorse e i parametri.
  • Rimuovere parametri, risorse e proprietà ridondanti.
  • Aggiungere variabili e parametri per rendere riutilizzabile il file Bicep.

Aggiornare i nomi simbolici delle risorse

  1. In Visual Studio Code aprire il file main.bicep.

  2. Selezionare il nome simbolico per la risorsa del gruppo di sicurezza di rete, denominato networkSecurityGroups_ToyTruckServer_nsg_name_resource o con un nome simile.

    Rinominare il nome simbolico. È possibile selezionare F2 oppure fare clic con il pulsante destro del mouse e selezionare Rinomina simbolo.

    Immettere il nome networkSecurityGroup e premere INVIO. Visual Studio Code aggiorna il nome e tutti i riferimenti nel file.

  3. Ripetere questo processo per ogni risorsa. Rinominare le risorse come mostrato nella tabella seguente.

    Nota

    I nomi delle risorse nella distribuzione saranno leggermente diversi da quelli nella tabella. Trovare le risorse con nomi simili a tali nomi.

    Tipo di risorsa Nome simbolico corrente Nuovo nome simbolico
    Indirizzo IP pubblico publicIPAddresses_ToyTruckServer_ip_name_resource publicIPAddress
    Macchina virtuale virtualMachines_ToyTruckServer_name_resource virtualMachine
    Rete virtuale virtualNetworks_ToyTruck_vnet_name_resource virtualNetwork
    Subnet virtualNetworks_ToyTruck_vnet_name_default defaultSubnet
    Interfaccia di rete networkInterfaces_toytruckserver890_name_resource networkInterface

Rimuovere la risorsa subnet ridondante

La subnet della rete virtuale è attualmente definita due volte. Viene definita una volta nella risorsa virtualNetwork e di nuovo come sua stessa risorsa figlia denominata defaultSubnet. Non ha senso definirla due volte.

  1. Eliminare la risorsa defaultSubnet.

    Si noti che la risorsa networkInterface evidenzia ora un problema, poiché fa riferimento all'ID risorsa della subnet predefinita:

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

  2. Aggiornare la risorsa virtualNetwork in modo da includere un riferimento existing alla subnet. Se si aggiunge il riferimento existing, è possibile fare di nuovo riferimento alla subnet nel codice Bicep senza definirla di nuovo:

    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. Aggiornare la risorsa networkInterface in modo che faccia riferimento all'ID risorsa della subnet:

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

    Si noterà un errore relativo al fatto che l'espressione è coinvolta in un ciclo. Nella sezione successiva verrà spiegato come correggere il problema.

  4. Passare alla proprietà subnets della risorsa virtualNetwork e rimuovere id: defaultSubnet.id per risolvere l'errore.

Modificare i parametri in variabili

I parametri nel modello non devono essere parametri. I parametri verranno ora rinominati in nomi più significativi e convertirli in variabili.

  1. Selezionare il nome simbolico per il parametro virtualNetworks_ToyTruck_vnet_name. Rinominarlo in virtualNetworkName.

  2. Modificare il parametro in una variabile. Ricordarsi di rimuovere il tipo, poiché le definizioni di variabile non includono tipi:

    var virtualNetworkName = 'ToyTruck-vnet'
    
  3. Ripetere il processo per ogni parametro. Rinominare i parametri come mostrato nella tabella seguente.

    Si noti che il valore di networkInterfaceName include un numero a tre cifre. Il numero è diverso a seconda della distribuzione. Assicurarsi di copiare il valore della variabile dal modello di riferimento.

    Nome parametro corrente Nome nuova variabile
    virtualMachines_ToyTruckServer_name virtualMachineName
    networkInterfaces_toytruckserver890_name networkInterfaceName
    publicIPAddresses_ToyTruckServer_ip_name publicIPAddressName
    networkSecurityGroups_ToyTruckServer_nsg_name networkSecurityGroupName
  4. Verificare che le dichiarazioni di variabili siano simili all'esempio seguente:

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

Aggiornare le posizioni delle risorse

Tutte le risorse usano attualmente una posizione hardcoded. Si aggiungerà ora un parametro in modo che il modello diventi più riutilizzabile.

  1. Nella parte superiore del file aggiungere un nuovo parametro e un elemento Decorator di descrizione per chiarirne lo scopo:

    @description('The location where resources are deployed.')
    param location string = resourceGroup().location
    
  2. Aggiornare ogni risorsa in modo che usi il parametro location anziché la posizione westus3 hardcoded.

Aggiungere parametri e variabili

Il modello include alcuni valori hardcoded per i quali parametri e variabili sarebbero più appropriati. Si aggiungeranno ora parametri per le proprietà che potrebbero cambiare tra le distribuzioni e variabili per i valori che non cambieranno.

  1. Nella parte superiore del file main.bicep, sotto il parametro location aggiungere i parametri seguenti:

    @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
    

    Alcuni parametri hanno valori predefiniti e altri no. Verrà creato in seguito un file di parametri per impostare la maggior parte di questi valori.

  2. Aggiungere le nuove dichiarazioni di variabili seguenti sotto la variabile networkSecurityGroupName:

    var virtualNetworkDefaultSubnetName = 'default'
    var virtualMachineImageReference = {
      publisher: 'canonical'
      offer: '0001-com-ubuntu-server-focal'
      sku: '20_04-lts-gen2'
      version: 'latest'
    }
    
  3. Aggiungere la dichiarazione di variabile seguente. Sostituire il valore con il nome del disco del sistema operativo dal proprio modello di riferimento.

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

    Il valore di virtualMachineOSDiskName è univoco. Il valore è diverso per ogni distribuzione. Assicurarsi di copiare il valore della variabile dal modello di riferimento.

    Avviso

    Assicurarsi di copiare correttamente i valori per le variabili virtualMachineOSDiskName e networkInterfaceName. In caso contrario, Azure non rileverà che si dichiarano risorse esistenti e potrebbe provare a creare nuove risorse.

    Le dichiarazioni di variabili dovrebbero essere ora simili all'esempio seguente:

    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. Aggiornare la risorsa publicIPAddress per fare riferimento a un parametro:

    Proprietà Parametro
    sku.name publicIPAddressSkuName
  5. Aggiornare la risorsa virtualMachine in modo che faccia riferimento ai parametri e alle variabili:

    Proprietà Parametro o variabile
    hardwareProfile.vmSize virtualMachineSizeName
    storageProfile.imageReference virtualMachineImageReference
    Usare il nome della variabile per sostituire i valori dell'oggetto, incluse le parentesi graffe.
    storageProfile.osDisk.name virtualMachineOSDiskName
    storageProfile.osDisk.managedDisk.storageAccountType virtualMachineManagedDiskStorageAccountType
    osProfile.adminUsername virtualMachineAdminUsername
    osProfile.adminPassword
    Aggiungere questa proprietà di seguito osProfile.adminUsername
    virtualMachineAdminPassword
  6. Aggiornare la risorsa virtualNetwork in modo che faccia riferimento ai parametri e alle variabili:

    Proprietà Parametro o variabile
    addressSpace.addressPrefixes virtualNetworkAddressPrefix
    subnets.name virtualNetworkDefaultSubnetName
    subnets.addressPrefix virtualNetworkDefaultSubnetAddressPrefix
  7. Aggiornare la virtualNetwork risorsa nidificata della risorsa defaultSubnet:

    Proprietà Variabile
    name virtualNetworkDefaultSubnetName

Rimuovere le proprietà non necessarie

Il processo di esportazione aggiunge proprietà ridondanti a molte risorse. Usare questi passaggi per rimuovere le proprietà non necessarie.

  1. Nella risorsa networkSecurityGroup rimuovere properties perché la proprietà securityRules è vuota.

  2. Nella risorsa publicIPAddress, rimuovere le proprietà seguenti:

    • Rimuovere la proprietà ipAddress perché viene impostata automaticamente da Azure
    • ipTags perché è vuoto
  3. Nella risorsa virtualMachine, rimuovere le proprietà seguenti:

    • Rimuovere la proprietà storageProfile.osDisk.managedDisk.id perché Azure la determina automaticamente quando viene distribuita la macchina virtuale

      Importante

      Se questa proprietà non viene rimossa, il modello non verrà distribuito correttamente.

    • storageProfile.dataDisks perché è vuoto

    • osProfile.secrets perché è vuoto

    • Rimuovere la proprietà osProfile.requireGuestProvisionSignal perché viene impostata automaticamente da Azure

  4. Nella risorsa virtualNetwork, rimuovere le proprietà seguenti:

    • Rimuovere le proprietà delegations e virtualNetworkPeerings perché sono vuote.
    • Riga per type: 'Microsoft.Network/virtualNetworks/subnets'
  5. Nella risorsa networkInterface, rimuovere le proprietà seguenti:

    • La proprietà kind

    • Da ipConfigurations: id, etag, typeeprivateIPAddress perché viene impostata automaticamente da Azure e il metodo di allocazione è Dynamic

    • Da ipConfigurations.properties:

      • provisioningState
    • Da publicIPAddress, name, properties, type e sku

    • dnsSettings perché la proprietà dnsServers è vuota

Suggerimento

Quando si lavora con i propri modelli, è necessario determinare se sono presenti proprietà che devono essere rimosse come è stato fatto qui.

In Visual Studio Code, l'estensione Bicep consente di impostare le proprietà minime per una risorsa. Quando si aggiunge uno spazio dopo il segno di uguale nella definizione della risorsa, Visual Studio Code richiede di selezionare proprietà obbligatorie:

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

Quando si seleziona required-properties, Visual Studio Code precompila la definizione della risorsa con le proprietà obbligatorie. È possibile fare riferimento a required-properties per determinare se tutte le proprietà del modello convertito devono essere presenti.

Anche il repository Modelli di avvio rapido di Azure è utile per questa attività. Trovare un modello di avvio rapido che corrisponda approssimativamente all'operazione che si sta tentando di eseguire ed esaminare le proprietà impostate per la risorsa.

Creare un file di parametri

I parametri sono attualmente definiti come valori predefiniti nel modello. Per fare in modo che il modello funzioni correttamente in tutti gli ambienti, è consigliabile creare un file di parametri e rimuovere i valori predefiniti per i parametri che devono cambiare per ogni ambiente.

  1. Creare un nuovo file denominato main.parameters.production.json.

  2. Incollare il codice JSON seguente nel file 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. Aggiornare i valori per i parametri virtualNetworkAddressPrefix e virtualNetworkDefaultSubnetAddressPrefix in modo che corrispondano agli intervalli di indirizzi IP specificati nella risorsa di rete virtuale del modello di riferimento.

    Ad esempio, ecco come vengono specificati in un modello di riferimento. Gli indirizzi IP potrebbero essere diversi da quelli usati in questo esempio.

    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. Aggiornare il file main.bicep per rimuovere i valori predefiniti per i parametri specificati nel file dei parametri.

    • virtualMachineSizeName
    • virtualMachineManagedDiskStorageAccountType
    • virtualMachineAdminUsername

Non modificare i valori predefiniti per i parametri location e publicIPAddressSkuName perché questi valori sono probabilmente uguali per tutti gli ambienti.

Verificare il modello

  1. Al termine della fase di refactoring, il file main.bicep dovrebbe essere simile al seguente:

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

    Il file main.parameters.production.json dovrebbe essere simile al seguente, anche se è possibile che siano elencati intervalli di indirizzi IP diversi:

    {
      "$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. Selezionare Visualizza>Problemi per visualizzare il riquadro dei problemi.

    Non sono indicati problemi.

Suggerimento

Quando si lavora con i propri modelli, è possibile che vengano fatte scelte diverse per le proprietà da parametrizzare e altre personalizzazioni. In questo modulo vengono fornite indicazioni generali per iniziare, ma è necessario tenere conto del proprio ambiente e valutare come riutilizzare i modelli quando si decide come effettuare il refactoring dei file Bicep.