Exercício – Refatorar o arquivo Bicep
No exercício anterior, você criou um arquivo Bicep inicial contendo 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 ser lido. Nesta unidade, você vai refatorar o arquivo.
Durante o processo de refatoração, você vai:
- Atualizar os nomes simbólicos de recursos e parâmetros.
- Remover parâmetros, recursos e propriedades redundantes.
- Adicionar variáveis e parâmetros para tornar o arquivo Bicep reutilizável.
Atualizar os nomes simbólicos de recursos
No Visual Studio Code, abra o arquivo main.bicep.
Selecionar o nome simbólico do recurso de grupo de segurança de rede, que é
networkSecurityGroups_ToyTruckServer_nsg_name_resource
ou um nome semelhante.Altere o nome simbólico. Você pode pressionar F2 ou clicar com o botão direito do mouse e selecionar Renomear Símbolo.
Insira o nome
networkSecurityGroup
e pressione ENTER. O Visual Studio Code atualiza o nome e todas as referências no arquivo.Repita esse processo para cada recurso. Renomeie os recursos como mostrado na tabela a seguir.
Observação
Os nomes dos recursos na implantação serão um pouco diferentes dos descritos na tabela. Encontre os recursos que têm nomes parecidos com 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
Adaptador de rede networkInterfaces_toytruckserver890_name_resource
networkInterface
Remover o recurso de sub-rede redundante
A sub-rede da rede virtual está definida duas vezes no momento. Ela está definida uma vez no recurso virtualNetwork
e novamente como o próprio recurso filho chamado defaultSubnet
. Não faz sentido defini-la duas vezes.
Exclua o recurso
defaultSubnet
.Observe que o recurso
networkInterface
agora exibe um problema, porque ele se refere à ID do recurso da sub-rede padrão:Atualize o recurso
virtualNetwork
para incluir uma referênciaexisting
à sub-rede. Se você adicionar a referênciaexisting
, poderá referenciar a sub-rede novamente dentro do código Bicep sem defini-la de novo: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' } }
Atualize o recurso
networkInterface
para se referir à 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ê observará um erro sobre se a expressão está envolvida em um ciclo. Você corrigirá isso na próxima etapa.
Vá para a propriedade
subnets
do recursovirtualNetwork
e removaid: defaultSubnet.id
para resolver o erro.
Alterar os parâmetros para variáveis
Os parâmetros no modelo não precisam ser parâmetros. Você agora renomeará os parâmetros para nomes mais significativos e os converterá em variáveis.
Selecione o nome simbólico do parâmetro
virtualNetworks_ToyTruck_vnet_name
. Renomeie-o comovirtualNetworkName
.Altere o parâmetro para uma variável. Lembre-se de remover o tipo, pois as definições de variável não incluem tipos:
var virtualNetworkName = 'ToyTruck-vnet'
Repita o processo para cada parâmetro. Renomeie os parâmetros como mostrado na tabela a seguir.
Observe que o valor de
networkInterfaceName
inclui um número de três dígitos. O número é diferente para implantações diferentes. Copie o valor da variável do 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
Verifique se as declarações de variável são semelhantes ao seguinte exemplo:
var virtualNetworkName = 'ToyTruck-vnet' var virtualMachineName = 'ToyTruckServer' var networkInterfaceName = 'YOUR-NETWORK-INTERFACE-NAME' var publicIPAddressName = 'ToyTruckServer-ip' var networkSecurityGroupName = 'ToyTruckServer-nsg'
Atualizar as localizações de recursos
No momento, todos os recursos usam uma localização embutida em código. Você adicionará um parâmetro para que o modelo se torne mais reutilizável.
No início do arquivo, adicione um novo parâmetro e um decorador de descrição para que a finalidade dele fique clara:
@description('The location where resources are deployed.') param location string = resourceGroup().location
Atualize cada recurso para usar o parâmetro
location
em vez da localizaçãowestus3
embutida em código.
Adicionar parâmetros e variáveis
Seu modelo tem alguns valores embutido em código em que parâmetros ou variáveis seriam mais apropriados. Aqui, você adicionará parâmetros para propriedades que podem ser alteradas entre implantações e variáveis para valores que não serão alterados.
No início do arquivo main.bicep, abaixo do parâmetro
location
, 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. Posteriormente, você criará um arquivo de parâmetro para definir a maioria desses valores.
Sob a variável
networkSecurityGroupName
, adicione as seguintes novas declarações de variável:var virtualNetworkDefaultSubnetName = 'default' var virtualMachineImageReference = { publisher: 'canonical' offer: '0001-com-ubuntu-server-focal' sku: '20_04-lts-gen2' version: 'latest' }
Adicione a declaração de variável a seguir. Substitua o valor pelo nome do disco de SO do seu modelo de referência.
var virtualMachineOSDiskName = 'YOUR-OS-DISK-NAME'
O valor de
virtualMachineOSDiskName
é exclusivo. O valor é diferente para cada implantação. Copie o valor da variável do modelo de referência.Aviso
Copie corretamente os valores das variáveis
virtualMachineOSDiskName
enetworkInterfaceName
. Caso contrário, o Azure não entenderá que você está declarando recursos que já existem e poderá tentar criar outros recursos.Agora, as declarações de variável serão semelhantes a 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'
Atualize o recurso
publicIPAddress
para fazer referência a um parâmetro:Propriedade Parâmetro sku.name
publicIPAddressSkuName
Atualize o recurso
virtualMachine
para se referir aos parâmetros e às variáveis:Propriedade Variável ou parâmetro hardwareProfile.vmSize
virtualMachineSizeName
storageProfile.imageReference
virtualMachineImageReference
Use o nome da variável para substituir os valores do objeto, incluindo as chaves.storageProfile.osDisk.name
virtualMachineOSDiskName
storageProfile.osDisk.managedDisk.storageAccountType
virtualMachineManagedDiskStorageAccountType
osProfile.adminUsername
virtualMachineAdminUsername
osProfile.adminPassword
Adicione esta propriedade abaixo deosProfile.adminUsername
virtualMachineAdminPassword
Atualize o recurso
virtualNetwork
para se referir aos parâmetros e às variáveis:Propriedade Variável ou parâmetro addressSpace.addressPrefixes
virtualNetworkAddressPrefix
subnets.name
virtualNetworkDefaultSubnetName
subnets.addressPrefix
virtualNetworkDefaultSubnetAddressPrefix
Atualize o recurso aninhado
defaultSubnet
do recursovirtualNetwork
:Propriedade Variável name
virtualNetworkDefaultSubnetName
Remover as propriedades desnecessárias
O processo de exportação adiciona propriedades redundantes a muitos recursos. Use estas etapas para remover as propriedades desnecessárias.
No recurso
networkSecurityGroup
, removaproperties
porque a propriedadesecurityRules
está vazia.No recurso
publicIPAddress
, remova as seguintes propriedades:- A propriedade
ipAddress
, pois ela é definida automaticamente pelo Azure - A propriedade
ipTags
, pois ela está vazia
- A propriedade
No recurso
virtualMachine
, remova as seguintes propriedades:A propriedade
storageProfile.osDisk.managedDisk.id
, pois ela é determinada automaticamente pelo Azure quando a máquina virtual é implantadaImportante
Se você não remover essa propriedade, seu modelo não será implantado corretamente.
A propriedade
storageProfile.dataDisks
, pois ela está vaziaA propriedade
osProfile.secrets
, pois ela está vaziaA propriedade
osProfile.requireGuestProvisionSignal
, pois ela é definida automaticamente pelo Azure
No recurso
virtualNetwork
, remova as seguintes propriedades:- As propriedades
delegations
evirtualNetworkPeerings
, porque elas estão vazias. - A linha para
type: 'Microsoft.Network/virtualNetworks/subnets'
- As propriedades
No recurso
networkInterface
, remova as seguintes propriedades:A propriedade
kind
De
ipConfigurations
:id
,etag
,type
eprivateIPAddress
, pois ela é definida automaticamente pelo Azure e o método de alocação é DinâmicoDe
ipConfigurations.properties
:provisioningState
De
publicIPAddress
,name
,properties
,type
esku
dnsSettings
porque a propriedadednsServers
está vazia
Dica
Ao trabalhar com modelos próprios, você precisará determinar se há propriedades que devem ser removidas como você fez aqui.
No Visual Studio Code, a extensão Bicep ajuda você a definir as propriedades mínimas de 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 required-properties:
Quando você seleciona required-properties, o Visual Studio Code preenche a definição de recurso com as propriedades obrigatórias. Você pode consultar required-properties para determinar se todas as propriedades no modelo convertido precisam estar presentes.
O repositório de modelos de início rápido do Azure é útil para essa tarefa. Encontre um modelo de início rápido que faça algo semelhante ao que você está tentando fazer e veja as propriedades que ele define no recurso.
Criar um arquivo de parâmetro
Seus parâmetros estão atualmente definidos como valores padrão no modelo. Para fazer com que o modelo funcione bem em vários ambientes, é uma boa ideia criar um arquivo de parâmetro e remover os valores padrão de parâmetros que precisam ser alterados para cada ambiente.
Crie um arquivo chamado main.parameters.production.json.
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" } } }
Atualize os valores dos parâmetros
virtualNetworkAddressPrefix
evirtualNetworkDefaultSubnetAddressPrefix
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 } }
Atualize o arquivo main.bicep para remover os valores padrão dos parâmetros especificados no arquivo de parâmetros.
virtualMachineSizeName
virtualMachineManagedDiskStorageAccountType
virtualMachineAdminUsername
Mantenha os valores padrão para os parâmetros location
e publicIPAddressSkuName
, pois eles provavelmente são os mesmos para todos os ambientes.
Verificar o modelo
No final da fase de refatoração, o arquivo main.bicep será semelhante ao seguinte exemplo:
@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' } }
O arquivo main.parameters.production.json deve ser semelhante ao seguinte arquivo, embora possa haver intervalos de endereços IP diferentes 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" } } }
Selecione Exibir>Problemas para exibir o painel de problemas.
Nenhum problema foi indicado.
Dica
Ao trabalhar com modelos próprios, você pode fazer escolhas diferentes sobre as propriedades a serem parametrizadas e outras personalizações. Ao longo deste módulo, forneceremos diretrizes gerais para ajudar você a começar o processo, mas você precisará considerar o seu ambiente e como deseja reutilizar os modelos ao decidir como refatorar seus arquivos Bicep.