Ćwiczenie — refaktoryzacja pliku Bicep

Ukończone

W poprzednim ćwiczeniu utworzono początkowy plik Bicep zawierający maszynę wirtualną ciężarówki toy i skojarzone zasoby. Jednak szablon Bicep nie stosuje najlepszych rozwiązań i jest trochę trudne do odczytania. W tej lekcji z refaktoryzujesz plik.

Podczas procesu refaktoryzacji wykonasz następujące czynności:

  • Zaktualizuj nazwy symboliczne zasobów i parametrów.
  • Usuń nadmiarowe parametry, zasoby i właściwości.
  • Dodaj zmienne i parametry, aby plik Bicep był wielokrotnego użytku.

Aktualizowanie nazw symbolicznych zasobów

  1. W programie Visual Studio Code otwórz plik main.bicep .

  2. Wybierz nazwę symboliczną zasobu sieciowej grupy zabezpieczeń, czyli networkSecurityGroups_ToyTruckServer_nsg_name_resource podobną nazwę.

    Zmień nazwę symboliczną. Możesz wybrać klawisz F2 lub kliknąć prawym przyciskiem myszy, a następnie wybrać polecenie Zmień nazwę symbolu.

    Wprowadź nazwę networkSecurityGroup i naciśnij klawisz Enter. Program Visual Studio Code aktualizuje nazwę i wszystkie odwołania w pliku.

  3. Powtórz ten proces dla każdego zasobu. Zmień nazwę zasobów, jak pokazano w poniższej tabeli.

    Uwaga

    Nazwy zasobów we wdrożeniu będą nieco inne niż nazwy w tabeli. Znajdź zasoby, które mają nazwy zbliżone do tych nazw.

    Typ zasobu Bieżąca nazwa symboliczna Nowa nazwa symboliczna
    Publiczny adres IP publicIPAddresses_ToyTruckServer_ip_name_resource publicIPAddress
    Maszyna wirtualna virtualMachines_ToyTruckServer_name_resource virtualMachine
    Sieć wirtualna virtualNetworks_ToyTruck_vnet_name_resource virtualNetwork
    Podsieć virtualNetworks_ToyTruck_vnet_name_default defaultSubnet
    Interfejs sieciowy networkInterfaces_toytruckserver890_name_resource networkInterface

Usuwanie nadmiarowego zasobu podsieci

Podsieć sieci wirtualnej jest obecnie definiowana dwukrotnie. Jest on definiowany raz w zasobie virtualNetwork i ponownie jako własny zasób podrzędny o nazwie defaultSubnet. Nie ma sensu definiować podsieci dwa razy.

  1. defaultSubnet Usuń zasób.

    Zwróć uwagę, że networkInterface zasób wyświetla teraz problem, ponieważ odwołuje się on do domyślnego identyfikatora zasobu podsieci:

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

  2. Zaktualizuj zasób, virtualNetwork aby uwzględnić existing odwołanie do podsieci. Jeśli dodasz existing odwołanie, możesz ponownie odwołać się do podsieci w kodzie Bicep bez ponownego zdefiniowania go:

    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. Zaktualizuj zasób, networkInterface aby odwoływać się do identyfikatora zasobu podsieci:

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

    Zauważysz błąd dotyczący tego, że wyrażenie jest zaangażowane w cykl. Naprawisz to w następnym kroku.

  4. Przejdź do virtualNetwork właściwości zasobu subnets i usuń go id: defaultSubnet.id , aby rozwiązać ten problem.

Zmienianie parametrów na zmienne

Parametry w szablonie nie muszą być parametrami. Teraz zmienisz nazwę parametrów na bardziej znaczące nazwy i przekonwertujesz je na zmienne.

  1. Wybierz nazwę symboliczną parametru virtualNetworks_ToyTruck_vnet_name . Zmień jego nazwę na virtualNetworkName.

  2. Zmień parametr na zmienną. Pamiętaj, aby usunąć typ, ponieważ definicje zmiennych nie zawierają typów:

    var virtualNetworkName = 'ToyTruck-vnet'
    
  3. Powtórz proces dla każdego parametru. Zmień nazwę parametrów, jak pokazano w poniższej tabeli.

    Zwróć uwagę, że wartość elementu networkInterfaceName zawiera trzycyfrową liczbę. Liczba jest inna w przypadku różnych wdrożeń. Upewnij się, że skopiujesz wartość zmiennej z szablonu odwołania.

    Bieżąca nazwa parametru Nowa nazwa zmiennej
    virtualMachines_ToyTruckServer_name virtualMachineName
    networkInterfaces_toytruckserver890_name networkInterfaceName
    publicIPAddresses_ToyTruckServer_ip_name publicIPAddressName
    networkSecurityGroups_ToyTruckServer_nsg_name networkSecurityGroupName
  4. Sprawdź, czy deklaracje zmiennych wyglądają jak w poniższym przykładzie:

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

Aktualizowanie lokalizacji zasobów

Wszystkie zasoby używają obecnie zakodowanej lokalizacji. Teraz dodasz parametr, aby szablon stał się bardziej wielokrotnego użytku.

  1. W górnej części pliku dodaj nowy parametr i dekorator opisu, aby wyjaśnić przeznaczenie parametru:

    @description('The location where resources are deployed.')
    param location string = resourceGroup().location
    
  2. Zaktualizuj każdy zasób, aby użyć parametru location zamiast zakodowanej westus3 lokalizacji.

Dodawanie parametrów i zmiennych

Szablon zawiera pewne trwale zakodowane wartości, w których parametry lub zmienne byłyby bardziej odpowiednie. Teraz dodasz parametry właściwości, które mogą ulec zmianie między wdrożeniami i zmiennymi dla wartości, które nie będą.

  1. W górnej części pliku main.bicep poniżej parametru location dodaj następujące parametry:

    @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
    

    Niektóre parametry mają wartości domyślne, a inne nie. Później utworzysz plik parametrów, aby ustawić większość tych wartości.

  2. Dodaj następujące nowe deklaracje zmiennych poniżej zmiennej networkSecurityGroupName :

    var virtualNetworkDefaultSubnetName = 'default'
    var virtualMachineImageReference = {
      publisher: 'canonical'
      offer: '0001-com-ubuntu-server-focal'
      sku: '20_04-lts-gen2'
      version: 'latest'
    }
    
  3. Dodaj następującą deklarację zmiennej. Zastąp wartość nazwą dysku systemu operacyjnego z własnego szablonu referencyjnego.

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

    Wartość elementu virtualMachineOSDiskName jest unikatowa. Wartość jest inna dla każdego wdrożenia. Upewnij się, że skopiujesz wartość zmiennej z szablonu odwołania.

    Ostrzeżenie

    Upewnij się, że skopiujesz poprawne wartości dla virtualMachineOSDiskName zmiennych i .networkInterfaceName W przeciwnym razie platforma Azure nie wykryje, że deklarujesz istniejące zasoby i może spróbować utworzyć nowe zasoby.

    Deklaracje zmiennych powinny teraz wyglądać następująco:

    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. Zaktualizuj zasób, publicIPAddress aby odwoływać się do parametru:

    Właściwości Parametr
    sku.name publicIPAddressSkuName
  5. Zaktualizuj zasób, virtualMachine aby odwoływać się do parametrów i zmiennych:

    Właściwości Parametr lub zmienna
    hardwareProfile.vmSize virtualMachineSizeName
    storageProfile.imageReference virtualMachineImageReference
    Użyj nazwy zmiennej, aby zastąpić wartości obiektu, w tym nawiasy klamrowe.
    storageProfile.osDisk.name virtualMachineOSDiskName
    storageProfile.osDisk.managedDisk.storageAccountType virtualMachineManagedDiskStorageAccountType
    osProfile.adminUsername virtualMachineAdminUsername
    osProfile.adminPassword
    Dodaj tę właściwość poniżej osProfile.adminUsername
    virtualMachineAdminPassword
  6. Zaktualizuj zasób, virtualNetwork aby odwoływać się do parametrów i zmiennych:

    Właściwości Parametr lub zmienna
    addressSpace.addressPrefixes virtualNetworkAddressPrefix
    subnets.name virtualNetworkDefaultSubnetName
    subnets.addressPrefix virtualNetworkDefaultSubnetAddressPrefix
  7. virtualNetwork Zaktualizuj zagnieżdżony zasób zasobu defaultSubnet:

    Właściwości Zmienna
    name virtualNetworkDefaultSubnetName

Usuwanie niepotrzebnych właściwości

Proces eksportowania dodaje nadmiarowe właściwości do wielu zasobów. Wykonaj następujące kroki, aby usunąć niepotrzebne właściwości.

  1. W zasobie networkSecurityGroup usuń properties , ponieważ właściwość jest pusta securityRules .

  2. W zasobie publicIPAddress usuń następujące właściwości:

    • ipAddress właściwość, ponieważ jest ona automatycznie ustawiana przez platformę Azure
    • ipTags właściwość, ponieważ jest pusta
  3. W zasobie virtualMachine usuń następujące właściwości:

    • storageProfile.osDisk.managedDisk.id właściwość, ponieważ platforma Azure automatycznie określa tę właściwość podczas wdrażania maszyny wirtualnej

      Ważne

      Jeśli ta właściwość nie zostanie usunięta, szablon nie zostanie wdrożony poprawnie.

    • storageProfile.dataDisks właściwość, ponieważ jest pusta

    • osProfile.secrets właściwość, ponieważ jest pusta

    • osProfile.requireGuestProvisionSignal właściwość, ponieważ platforma Azure ustawia tę właściwość automatycznie

  4. W zasobie virtualNetwork usuń następujące właściwości:

    • delegations i virtualNetworkPeerings właściwości, ponieważ są puste.
    • Linia dla type: 'Microsoft.Network/virtualNetworks/subnets'
  5. W zasobie networkInterface usuń następujące właściwości:

    • Właściwość kind

    • Z ipConfigurationselementu : id, etag, typeiprivateIPAddress ponieważ jest ona automatycznie ustawiana przez platformę Azure, a metoda alokacji jest dynamiczna

    • Z elementu ipConfigurations.properties:

      • provisioningState
    • Z publicIPAddress, , propertiesname, typeisku

    • dnsSettingsponieważ właściwość jest pusta dnsServers

Napiwek

Podczas pracy z własnymi szablonami należy określić, czy istnieją jakieś właściwości, które powinny zostać usunięte, jak pokazano tutaj.

W programie Visual Studio Code rozszerzenie Bicep pomaga ustawić minimalne właściwości zasobu. Po dodaniu spacji po znaku równości w definicji zasobu program Visual Studio Code wyświetli monit o wybranie wymaganych właściwości:

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

Po wybraniu opcji wymagane właściwości program Visual Studio Code wypełnia definicję zasobu właściwościami, które są obowiązkowe. Możesz odwołać się do właściwości wymaganych , aby określić, czy właściwości w przekonwertowanym szablonie muszą być obecne.

Repozytorium szablonów szybkiego startu platformy Azure jest również przydatne w tym zadaniu. Znajdź szablon szybkiego startu, który wykonuje w przybliżeniu czynności, które próbujesz wykonać, i przyjrzyj się właściwościom ustawianym w zasobie.

Tworzenie pliku parametrów

Parametry są obecnie zdefiniowane jako wartości domyślne w szablonie. Aby szablon działał dobrze w różnych środowiskach, dobrym pomysłem jest utworzenie pliku parametrów i usunięcie wartości domyślnych parametrów, które muszą zostać zmienione dla każdego środowiska.

  1. Utwórz nowy plik o nazwie main.parameters.production.json.

  2. Wklej następujący kod JSON do pliku 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. Zaktualizuj wartości parametrów virtualNetworkAddressPrefix i virtualNetworkDefaultSubnetAddressPrefix , aby odpowiadały zakresom adresów IP określonym w zasobie sieci wirtualnej szablonu odwołania.

    Na przykład poniżej przedstawiono sposób określenia wartości w szablonie odwołania. Adresy IP mogą różnić się od adresów IP używanych w tym przykładzie.

    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. Zaktualizuj plik main.bicep, aby usunąć wartości domyślne parametrów określonych w pliku parametrów.

    • virtualMachineSizeName
    • virtualMachineManagedDiskStorageAccountType
    • virtualMachineAdminUsername

Nie zmieniaj wartości domyślnych parametrów ipublicIPAddressSkuName, location ponieważ te wartości są prawdopodobnie takie same dla wszystkich środowisk.

Weryfikowanie szablonu

  1. Na końcu fazy refaktoryzacji plik main.bicep powinien wyglądać podobnie do poniższego przykładu:

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

    Plik main.parameters.production.json powinien wyglądać podobnie do poniższego pliku, chociaż mogą istnieć różne zakresy adresów IP:

    {
      "$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. Wybierz pozycję Wyświetl>problemy, aby wyświetlić okienko problemów.

    Nie wskazano żadnych problemów.

Napiwek

Podczas pracy z własnymi szablonami możesz dokonać różnych wyborów dotyczących właściwości, aby sparametryzować i inne dostosowania. W tym module udostępniamy ogólne wskazówki ułatwiające rozpoczęcie pracy, ale należy wziąć pod uwagę własne środowisko i sposób ponownego użycia szablonów podczas decydowania o tym, jak refaktoryzować własne pliki Bicep.