Boas práticas do modelo do ARM
Este artigo mostra como usar as práticas recomendadas ao criar seu modelo do Azure Resource Manager (modelo ARM). Essas recomendações ajudam a evitar problemas comuns ao usar um modelo ARM para implantar uma solução.
Limites do modelo
Limite o tamanho do modelo a 4 MB e cada definição de recurso a 1 MB. Os limites se aplicam ao estado final do modelo depois que ele foi expandido com definições iterativas de recursos e valores para variáveis e parâmetros. O ficheiro de parâmetros também está limitado a 4 MB. Poderá ser apresentado um erro com um ficheiro de modelo ou de parâmetros inferior a 4 MB se o tamanho total do pedido for demasiado grande. Para obter mais informações sobre como simplificar o modelo para evitar pedidos grandes, veja Resolver erros de tamanho de trabalhos excedido.
Também está limitado a:
- 256 parâmetros
- 512 variáveis
- 800 recursos (incluindo contagem de cópias)
- 64 valores de saída
- 10 locais exclusivos por escopo de assinatura/locatário/grupo de gerenciamento
- 24 576 carateres numa expressão de modelo
Poderá exceder alguns limites do modelo se utilizar um modelo aninhado. Para obter mais informações, veja Utilizar modelos associados e aninhados ao implementar recursos do Azure. Para reduzir o número de parâmetros, variáveis ou saídas, pode combinar vários valores num objeto. Para obter mais informações, veja Objetos como parâmetros.
Grupo de recursos
Quando você implanta recursos em um grupo de recursos, o grupo de recursos armazena metadados sobre os recursos. Os metadados são armazenados na localização do grupo de recursos.
Se a região do grupo de recursos estiver temporariamente indisponível, não poderá atualizar os recursos no grupo de recursos porque os metadados não estão disponíveis. Os recursos noutras regiões continuarão a funcionar como esperado, mas não poderá atualizá-los. Para minimizar o risco, localize o grupo de recursos e os recursos na mesma região.
Parâmetros
As informações nesta seção podem ser úteis quando você trabalha com parâmetros.
Recomendações gerais para parâmetros
Minimize o uso de parâmetros. Em vez disso, use variáveis ou valores literais para propriedades que não precisam ser especificadas durante a implantação.
Use camel case para nomes de parâmetros.
Utilize parâmetros para as definições que variam de acordo com o ambiente, como o SKU, o tamanho ou a capacidade.
Use parâmetros para nomes de recursos que você deseja especificar para facilitar a identificação.
Forneça uma descrição de cada parâmetro nos metadados.
"parameters": { "storageAccountType": { "type": "string", "metadata": { "description": "The type of the new storage account created to store the VM disks." } } }
Defina valores predefinidos para parâmetros que não são sensíveis. Ao especificar um valor padrão, é mais fácil implantar o modelo, e os usuários do seu modelo veem um exemplo de um valor apropriado. Qualquer valor padrão para um parâmetro deve ser válido para todos os usuários na configuração de implantação padrão.
"parameters": { "storageAccountType": { "type": "string", "defaultValue": "Standard_GRS", "metadata": { "description": "The type of the new storage account created to store the VM disks." } } }
Para especificar um parâmetro opcional, não use uma cadeia de caracteres vazia como um valor padrão. Em vez disso, use um valor literal ou uma expressão de linguagem para construir um valor.
"storageAccountName": { "type": "string", "defaultValue": "[concat('storage', uniqueString(resourceGroup().id))]", "metadata": { "description": "Name of the storage account" } }
Utilize
allowedValues
com moderação. Use-o apenas quando precisar se certificar de que alguns valores não estão incluídos nas opções permitidas. Se você usarallowedValues
de forma muito ampla, poderá bloquear implantações válidas por não manter sua lista atualizada.Quando um nome de parâmetro em seu modelo corresponde a um parâmetro no comando de implantação do PowerShell, o Gerenciador de Recursos resolve esse conflito de nomenclatura adicionando o postfix FromTemplate ao parâmetro de modelo. Por exemplo, se você incluir um parâmetro chamado ResourceGroupName em seu modelo, ele entrará em conflito com o parâmetro ResourceGroupName no cmdlet New-AzResourceGroupDeployment . Durante a implantação, você será solicitado a fornecer um valor para ResourceGroupNameFromTemplate.
Recomendações de segurança para parâmetros
Use sempre parâmetros para nomes de usuário e senhas (ou segredos).
Utilize
securestring
para todas as palavras-passe e segredos. Se você passar dados confidenciais em um objeto JSON, use osecureObject
tipo. Os parâmetros de modelo com cadeia de caracteres segura ou tipos de objeto seguros não podem ser lidos após a implantação do recurso."parameters": { "secretValue": { "type": "securestring", "metadata": { "description": "The value of the secret to store in the vault." } } }
Não forneça valores padrão para nomes de usuário, senhas ou qualquer valor que exija um
secureString
tipo.Não forneça valores padrão para propriedades que aumentam a área da superfície de ataque do aplicativo.
Recomendações de localização para parâmetros
Use um parâmetro para especificar o local dos recursos e defina o valor padrão como
resourceGroup().location
. O fornecimento de um parâmetro location permite que os usuários do modelo especifiquem um local onde tenham permissão para implantar recursos."parameters": { "location": { "type": "string", "defaultValue": "[resourceGroup().location]", "metadata": { "description": "The location in which the resources should be deployed." } } }
Não especifique
allowedValues
o parâmetro location. Os locais especificados podem não estar disponíveis em todas as nuvens.Use o valor do parâmetro location para recursos que provavelmente estarão no mesmo local. Essa abordagem minimiza o número de vezes que os usuários são solicitados a fornecer informações de localização.
Para recursos que não estão disponíveis em todos os locais, use um parâmetro separado ou especifique um valor de local literal.
Variáveis
As seguintes informações podem ser úteis quando você trabalha com variáveis:
Use camel case para nomes de variáveis.
Use variáveis para valores que você precisa usar mais de uma vez em um modelo. Se um valor for usado apenas uma vez, um valor codificado tornará seu modelo mais fácil de ler.
Use variáveis para valores que você constrói a partir de uma organização complexa de funções de modelo. Seu modelo é mais fácil de ler quando a expressão complexa só aparece em variáveis.
Não é possível usar a função de referência na
variables
seção do modelo. Areference
função deriva seu valor do estado de tempo de execução do recurso. No entanto, as variáveis são resolvidas durante a análise inicial do modelo. Construa valores que precisam dareference
função diretamente naresources
seção ououtputs
no modelo.Inclua variáveis para nomes de recursos que devem ser exclusivos.
Use um loop de cópia em variáveis para criar um padrão repetido de objetos JSON.
Remova as variáveis não utilizadas.
Versão da API
Defina a propriedade apiVersion
como uma versão da API codificada para o tipo de recurso. Ao criar um novo modelo, recomendamos que você use a versão mais recente da API para um tipo de recurso. Para determinar os valores disponíveis, consulte Referência do modelo.
Quando seu modelo funcionar conforme o esperado, recomendamos que você continue usando a mesma versão da API. Ao usar a mesma versão da API, você não precisa se preocupar em quebrar as alterações que podem ser introduzidas em versões posteriores.
Não use um parâmetro para a versão da API. As propriedades e os valores do recurso podem variar de acordo com a versão da API. O IntelliSense em um editor de código não pode determinar o esquema correto quando a versão da API é definida como um parâmetro. Se você passar uma versão da API que não corresponda às propriedades do modelo, a implantação falhará.
Não use variáveis para a versão da API.
Dependências de recursos
Ao decidir quais dependências definir, use as seguintes diretrizes:
Utilize a função
reference
e passe o nome do recurso para definir uma dependência implícita entre os recursos que têm de partilhar uma propriedade. Não adicione um elemento explícitodependsOn
quando já tiver definido uma dependência implícita. Esta abordagem reduz o risco de ter dependências desnecessárias. Para obter um exemplo de configuração de uma dependência implícita, consulte funções de referência e lista.Defina um recurso subordinado como dependente do seu recurso principal.
Os recursos com o elemento de condição definido como
false
são removidos automaticamente da ordem de dependência. Defina as dependências como se o recurso estivesse sempre implantado.Deixe a cascata de dependências sem as definir explicitamente. Por exemplo, sua máquina virtual depende de uma interface de rede virtual e a interface de rede virtual depende de uma rede virtual e endereços IP públicos. Portanto, a máquina virtual é implantada após todos os três recursos, mas não defina explicitamente a máquina virtual como dependente de todos os três recursos. Essa abordagem esclarece a ordem de dependência e facilita a alteração do modelo posteriormente.
Se um valor puder ser determinado antes da implantação, tente implantar o recurso sem dependência. Por exemplo, se um valor de configuração precisar do nome de outro recurso, talvez você não precise de uma dependência. Essa orientação nem sempre funciona porque alguns recursos verificam a existência do outro recurso. Se você receber um erro, adicione uma dependência.
Recursos
As seguintes informações podem ser úteis quando você trabalha com recursos:
Para ajudar outros contribuidores a compreender o propósito do recurso, especifique
comments
para cada recurso no modelo."resources": [ { "name": "[variables('storageAccountName')]", "type": "Microsoft.Storage/storageAccounts", "apiVersion": "2019-06-01", "location": "[resourceGroup().location]", "comments": "This storage account is used to store the VM disks.", ... } ]
Se o seu modelo ARM estiver armazenado em um
.jsonc
arquivo, os comentários usando a//
sintaxe serão suportados, conforme mostrado aqui."resources": [ { // This storage account is used to store the VM disks. "name": "[variables('storageAccountName')]", "type": "Microsoft.Storage/storageAccounts", "apiVersion": "2019-06-01", "location": "[resourceGroup().location]", ... } ]
Para obter mais detalhes sobre comentários e metadados, consulte Compreender a estrutura e a sintaxe dos modelos ARM.
Se você usar um ponto de extremidade público em seu modelo (como um ponto de extremidade público de armazenamento de Blob do Azure), não codifice o namespace. Use a
reference
função para recuperar dinamicamente o namespace. Você pode usar essa abordagem para implantar o modelo em diferentes ambientes de namespace público sem alterar manualmente o ponto de extremidade no modelo. Defina a versão da API para a mesma versão que você está usando para a conta de armazenamento em seu modelo."diagnosticsProfile": { "bootDiagnostics": { "enabled": "true", "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2019-06-01').primaryEndpoints.blob]" } }
Se a conta de armazenamento for implantada no mesmo modelo que você está criando e o nome da conta de armazenamento não for compartilhado com outro recurso no modelo, não será necessário especificar o namespace do provedor ou quando
apiVersion
fizer referência ao recurso. O exemplo a seguir mostra a sintaxe simplificada."diagnosticsProfile": { "bootDiagnostics": { "enabled": "true", "storageUri": "[reference(variables('storageAccountName')).primaryEndpoints.blob]" } }
Você também pode fazer referência a uma conta de armazenamento existente que esteja em um grupo de recursos diferente.
"diagnosticsProfile": { "bootDiagnostics": { "enabled": "true", "storageUri": "[reference(resourceId(parameters('existingResourceGroup'), 'Microsoft.Storage/storageAccounts', parameters('existingStorageAccountName')), '2019-06-01').primaryEndpoints.blob]" } }
Atribua endereços IP públicos a uma máquina virtual apenas quando uma aplicação o requer. Para se conectar a uma máquina virtual para fins administrativos, use regras NAT de entrada, um gateway de rede virtual ou uma caixa de jumpbox.
Para obter mais informações sobre como se conectar a máquinas virtuais, consulte:
A
domainNameLabel
propriedade para endereços IP públicos deve ser exclusiva. OdomainNameLabel
valor deve ter entre 3 e 63 caracteres e seguir as regras especificadas por esta expressão regular:^[a-z][a-z0-9-]{1,61}[a-z0-9]$
. Como auniqueString
função gera uma cadeia de caracteres com 13 caracteres, odnsPrefixString
parâmetro é limitado a 50 caracteres."parameters": { "dnsPrefixString": { "type": "string", "maxLength": 50, "metadata": { "description": "The DNS label for the public IP address. It must be lowercase. It should match the following regular expression, or it will raise an error: ^[a-z][a-z0-9-]{1,61}[a-z0-9]$" } } }, "variables": { "dnsPrefix": "[concat(parameters('dnsPrefixString'),uniquestring(resourceGroup().id))]" }
Quando você adiciona uma senha a uma extensão de script personalizada, use a
commandToExecute
propriedade naprotectedSettings
propriedade."properties": { "publisher": "Microsoft.Azure.Extensions", "type": "CustomScript", "typeHandlerVersion": "2.0", "autoUpgradeMinorVersion": true, "settings": { "fileUris": [ "[concat(variables('template').assets, '/lamp-app/install_lamp.sh')]" ] }, "protectedSettings": { "commandToExecute": "[concat('sh install_lamp.sh ', parameters('mySqlPassword'))]" } }
Nota
Para garantir que os segredos sejam criptografados quando forem passados como parâmetros para VMs e extensões, use a
protectedSettings
propriedade das extensões relevantes.Especifique valores explícitos para propriedades que tenham valores padrão que podem mudar ao longo do tempo. Por exemplo, se você estiver implantando um cluster AKS, poderá especificar ou omitir a
kubernetesVersion
propriedade. Se você não especificá-lo, o cluster será padronizado para a versão secundária N-1 e o patch mais recente. Quando você implanta o cluster usando um modelo ARM, esse comportamento padrão pode não ser o esperado. A reimplantação do modelo pode resultar na atualização inesperada do cluster para uma nova versão do Kubernetes. Em vez disso, considere especificar um número de versão explícito e, em seguida, alterá-lo manualmente quando estiver pronto para atualizar o cluster.
Comentários
Além da comments
propriedade, há suporte para comentários usando a //
sintaxe. Para obter mais detalhes sobre comentários e metadados, consulte Compreender a estrutura e a sintaxe dos modelos ARM. Você pode optar por salvar arquivos JSON que contêm //
comentários usando a extensão de .jsonc
arquivo, para indicar que o arquivo JSON contém comentários. O serviço ARM também aceitará comentários em qualquer arquivo JSON, incluindo arquivos de parâmetros.
Ferramentas ARM de código do Visual Studio
Trabalhar com modelos ARM é mais fácil com as Ferramentas do Azure Resource Manager (ARM) para Visual Studio Code. Esta extensão fornece suporte a idiomas, trechos de recursos e preenchimento automático de recursos para ajudá-lo a criar e validar modelos do Azure Resource Manager. Para saber mais e instalar a extensão, consulte Ferramentas do Azure Resource Manager (ARM).
Usar kit de ferramentas de teste
O kit de ferramentas de teste de modelo ARM é um script que verifica se seu modelo usa práticas recomendadas. Quando seu modelo não está em conformidade com as práticas recomendadas, ele retorna uma lista de avisos com alterações sugeridas. O kit de ferramentas de teste pode ajudá-lo a aprender como implementar práticas recomendadas em seu modelo.
Depois de concluir o modelo, execute o kit de ferramentas de teste para ver se há maneiras de melhorar sua implementação. Para obter mais informações, consulte Usar kit de ferramentas de teste de modelo ARM.
Próximos passos
- Para obter informações sobre a estrutura do arquivo de modelo, consulte Compreender a estrutura e a sintaxe dos modelos ARM.
- Para obter recomendações sobre como criar modelos que funcionam em todos os ambientes de nuvem do Azure, consulte Desenvolver modelos ARM para consistência na nuvem.