Exercício - Refatorar o arquivo Bicep

Concluído

No exercício anterior, você criou um arquivo Bicep inicial que contém a máquina virtual do caminhão de brinquedo e os recursos associados. No entanto, o modelo Bicep não segue as melhores práticas e é um pouco difícil de ler. Nesta unidade, você refatorará o arquivo.

Durante o processo de refatoração, você:

  • Atualize os nomes simbólicos para seus recursos e parâmetros.
  • Remova parâmetros, recursos e propriedades redundantes.
  • Adicione variáveis e parâmetros para tornar seu arquivo Bicep reutilizável.

Atualizar os nomes simbólicos do recurso

  1. No Visual Studio Code, abra o arquivo main.bicep .

  2. Selecione o nome simbólico para o recurso de grupo de segurança de rede, que é networkSecurityGroups_ToyTruckServer_nsg_name_resource ou um nome semelhante.

    Renomeie o nome simbólico. Você pode selecionar F2 ou clicar com o botão direito do mouse e, em seguida, selecionar Renomear símbolo.

    Digite o nome networkSecurityGroup e pressione Enter. O Visual Studio Code atualiza o nome e todas as referências no arquivo.

  3. Repita esse processo para cada recurso. Renomeie os recursos conforme mostrado na tabela a seguir.

    Nota

    Os nomes dos recursos em sua implantação serão um pouco diferentes dos nomes na tabela. Encontre os recursos que têm nomes próximos a esses nomes.

    Tipo de recurso Nome simbólico atual Novo nome simbólico
    Endereço IP público publicIPAddresses_ToyTruckServer_ip_name_resource publicIPAddress
    Máquina virtual virtualMachines_ToyTruckServer_name_resource virtualMachine
    Rede virtual virtualNetworks_ToyTruck_vnet_name_resource virtualNetwork
    Sub-rede virtualNetworks_ToyTruck_vnet_name_default defaultSubnet
    Interface de Rede networkInterfaces_toytruckserver890_name_resource networkInterface

Remover o recurso de sub-rede redundante

Atualmente, a sub-rede da rede virtual é definida duas vezes. Ele é definido uma vez no virtualNetwork recurso e novamente como seu próprio recurso filho chamado defaultSubnet. Não faz sentido definir a sub-rede duas vezes.

  1. Exclua o defaultSubnet recurso.

    Observe que o networkInterface recurso agora exibe um problema, porque se refere ao ID de recurso da sub-rede padrão:

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

  2. Atualize o virtualNetwork recurso para incluir uma existing referência à sub-rede. Se você adicionar a existing referência, poderá fazer referência à sub-rede novamente no código do Bíceps sem defini-la novamente:

    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. Atualize o networkInterface recurso para fazer referência ao ID do recurso da sub-rede:

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

    Você notará um erro sobre que a expressão está envolvida em um ciclo. Você corrigirá isso na próxima etapa.

  4. Vá para a virtualNetwork propriedade do subnets recurso e remova id: defaultSubnet.id para resolver o erro.

Alterar os parâmetros para variáveis

Os parâmetros no modelo não precisam ser parâmetros. Agora você renomeará os parâmetros para nomes mais significativos e os converterá em variáveis.

  1. Selecione o nome simbólico para o virtualNetworks_ToyTruck_vnet_name parâmetro. Renomeie-o para virtualNetworkName.

  2. Altere o parâmetro para uma variável. Lembre-se de remover o tipo porque as definições de variáveis não incluem tipos:

    var virtualNetworkName = 'ToyTruck-vnet'
    
  3. Repita o processo para cada parâmetro. Renomeie os parâmetros conforme mostrado na tabela a seguir.

    Observe que o networkInterfaceName valor do inclui um número de três dígitos. O número é diferente para implantações diferentes. Certifique-se de copiar o valor da variável do seu modelo de referência.

    Nome do parâmetro atual Novo nome da variável
    virtualMachines_ToyTruckServer_name virtualMachineName
    networkInterfaces_toytruckserver890_name networkInterfaceName
    publicIPAddresses_ToyTruckServer_ip_name publicIPAddressName
    networkSecurityGroups_ToyTruckServer_nsg_name networkSecurityGroupName
  4. Verifique se as declarações de variáveis se parecem com o exemplo a seguir:

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

Atualizar os locais dos recursos

Todos os recursos atualmente usam um local codificado. Agora você adicionará um parâmetro para que o modelo se torne mais reutilizável.

  1. Na parte superior do arquivo, adicione um novo parâmetro e um decorador de descrição para esclarecer a finalidade do parâmetro:

    @description('The location where resources are deployed.')
    param location string = resourceGroup().location
    
  2. Atualize cada recurso para usar o location parâmetro em vez do local codificado westus3 .

Adicionar parâmetros e variáveis

Seu modelo tem alguns valores codificados onde parâmetros ou variáveis seriam mais apropriados. Agora você adicionará parâmetros para propriedades que podem mudar entre implantações e variáveis para valores que não mudarão.

  1. Na parte superior do arquivo main.bicep , abaixo do location parâmetro, adicione os seguintes 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
    

    Alguns dos parâmetros têm valores padrão e outros não. Mais tarde, você criará um arquivo de parâmetros para definir a maioria desses valores.

  2. Adicione as seguintes novas declarações de variável abaixo da networkSecurityGroupName variável:

    var virtualNetworkDefaultSubnetName = 'default'
    var virtualMachineImageReference = {
      publisher: 'canonical'
      offer: '0001-com-ubuntu-server-focal'
      sku: '20_04-lts-gen2'
      version: 'latest'
    }
    
  3. Adicione a seguinte declaração de variável. Substitua o valor pelo nome do disco do SO a partir do seu próprio modelo de referência.

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

    O valor do virtualMachineOSDiskName é único. O valor é diferente para cada implantação. Certifique-se de copiar o valor da variável do seu modelo de referência.

    Aviso

    Certifique-se de copiar os valores corretos para as virtualMachineOSDiskName variáveis e networkInterfaceName . Caso contrário, o Azure não detetará que você está declarando recursos existentes e poderá tentar criar novos recursos.

    Suas declarações de variáveis agora devem se parecer com este exemplo:

    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. Atualize o publicIPAddress recurso para fazer referência a um parâmetro:

    Property Parâmetro
    sku.name publicIPAddressSkuName
  5. Atualize o virtualMachine recurso para consultar os parâmetros e variáveis:

    Property Parâmetro ou variável
    hardwareProfile.vmSize virtualMachineSizeName
    storageProfile.imageReference virtualMachineImageReference
    Use o nome da variável para substituir os valores do objeto, incluindo as chaves encaracoladas.
    storageProfile.osDisk.name virtualMachineOSDiskName
    storageProfile.osDisk.managedDisk.storageAccountType virtualMachineManagedDiskStorageAccountType
    osProfile.adminUsername virtualMachineAdminUsername
    osProfile.adminPassword
    Adicione esta propriedade abaixo osProfile.adminUsername
    virtualMachineAdminPassword
  6. Atualize o virtualNetwork recurso para consultar os parâmetros e variáveis:

    Property Parâmetro ou variável
    addressSpace.addressPrefixes virtualNetworkAddressPrefix
    subnets.name virtualNetworkDefaultSubnetName
    subnets.addressPrefix virtualNetworkDefaultSubnetAddressPrefix
  7. Atualizar o virtualNetwork recurso aninhado do recurso defaultSubnet:

    Property Variável
    name virtualNetworkDefaultSubnetName

Remover propriedades desnecessárias

O processo de exportação adiciona propriedades redundantes a muitos recursos. Use estas etapas para remover as propriedades desnecessárias.

  1. networkSecurityGroup No recurso, remova properties porque a securityRules propriedade está vazia.

  2. No recurso, remova as publicIPAddress seguintes propriedades:

    • ipAddress porque é definida automaticamente pelo Azure
    • ipTags propriedade porque está vazia
  3. No recurso, remova as virtualMachine seguintes propriedades:

    • storageProfile.osDisk.managedDisk.id porque o Azure determina automaticamente essa propriedade quando a máquina virtual é implantada

      Importante

      Se você não remover essa propriedade, seu modelo não será implantado corretamente.

    • storageProfile.dataDisks propriedade porque está vazia

    • osProfile.secrets propriedade porque está vazia

    • osProfile.requireGuestProvisionSignal porque o Azure define essa propriedade automaticamente

  4. No recurso, remova as virtualNetwork seguintes propriedades:

    • delegations e virtualNetworkPeerings propriedades porque estão vazias.
    • A linha para type: 'Microsoft.Network/virtualNetworks/subnets'
  5. No recurso, remova as networkInterface seguintes propriedades:

    • A kind propriedade

    • De ipConfigurations: id, , typeetag, e porque é definido automaticamente pelo Azure eprivateIPAddress o método de alocação é Dinâmico

    • De ipConfigurations.properties:

      • provisioningState
    • De publicIPAddress, , , typenameproperties, esku

    • dnsSettings porque a dnsServers propriedade está vazia

Gorjeta

Ao trabalhar com seus próprios modelos, você precisa determinar se há propriedades que devem ser removidas como fez aqui.

No Visual Studio Code, a extensão Bicep ajuda você a definir as propriedades mínimas para um recurso. Quando você adiciona um espaço após o sinal de igual na definição de recurso, o Visual Studio Code solicita que você selecione as propriedades necessárias:

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

Quando você seleciona propriedades necessárias, o Visual Studio Code preenche a definição de recurso com as propriedades que são obrigatórias. Você pode consultar as propriedades necessárias para determinar se todas as propriedades em seu modelo convertido precisam estar presentes.

O repositório de Modelos de Início Rápido do Azure também é útil para essa tarefa. Encontre um modelo de início rápido que faça aproximadamente o que você está tentando fazer e examine as propriedades que ele define no recurso.

Criar um arquivo de parâmetro

Atualmente, seus parâmetros são definidos como valores padrão em seu modelo. Para que seu modelo funcione bem em todos os ambientes, é uma boa ideia criar um arquivo de parâmetros e remover valores padrão para parâmetros que precisam ser alterados para cada ambiente.

  1. Crie um novo arquivo chamado main.parameters.production.json.

  2. Cole o seguinte JSON no arquivo 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. Atualize os valores dos virtualNetworkAddressPrefix parâmetros e virtualNetworkDefaultSubnetAddressPrefix para que correspondam aos intervalos de endereços IP especificados no recurso de rede virtual do modelo de referência.

    Por exemplo, veja como os valores são especificados em um modelo de referência. Seus endereços IP podem ser diferentes dos endereços IP usados neste exemplo.

    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. Atualize o arquivo main.bicep para remover os valores padrão para os parâmetros especificados no arquivo de parâmetros.

    • virtualMachineSizeName
    • virtualMachineManagedDiskStorageAccountType
    • virtualMachineAdminUsername

Não altere os valores padrão para os parâmetros e publicIPAddressSkuName porque esses valores são provavelmente os mesmos para todos os location seus ambientes.

Verificar o modelo

  1. No final da fase de refator, seu arquivo main.bicep deve ser semelhante ao exemplo a seguir:

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

    Seu arquivo main.parameters.production.json deve ser semelhante ao seguinte arquivo, embora você possa ter diferentes intervalos de endereços IP listados:

    {
      "$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. Selecione Exibir>problemas para exibir o painel de problemas.

    Nenhum problema é indicado.

Gorjeta

Ao trabalhar com seus próprios modelos, você pode fazer escolhas diferentes sobre as propriedades a serem parametrizadas e outras personalizações. Ao longo deste módulo, fornecemos orientação geral para ajudá-lo a começar, mas você precisará considerar seu próprio ambiente e como deseja reutilizar seus modelos quando decidir como refatorar seus próprios arquivos Bicep.