Definir a ordem de implementação dos recursos nos modelos do ARM
Ao implementar recursos, poderá ter de se certificar de que existem alguns recursos antes de outros recursos. Por exemplo, precisa de um SERVIDOR SQL lógico antes de implementar uma base de dados. Esta relação é estabelecida ao marcar um recurso como dependente do outro recurso. Utilize o dependsOn
elemento para definir uma dependência explícita. Utilize as funções de referência ou lista para definir uma dependência implícita.
O Azure Resource Manager avalia as dependências entre recursos e implementa-as na respetiva ordem dependente. Quando os recursos não são dependentes entre si, o Resource Manager implementa-os em paralelo. Só precisa de definir dependências para recursos implementados no mesmo modelo.
Dica
Recomendamos o Bicep porque oferece as mesmas capacidades que os modelos do ARM e a sintaxe é mais fácil de utilizar. Para saber mais, veja Dependências de recursos.
dependsOn
No modelo de Resource Manager do Azure (modelo arm), o dependsOn
elemento permite-lhe definir um recurso como dependente de um ou mais recursos. O valor é uma matriz JSON (JavaScript Object Notation) de cadeias, cada uma das quais é um nome de recurso ou ID. A matriz pode incluir recursos que são implementados condicionalmente. Quando um recurso condicional não é implementado, o Azure Resource Manager remove-o automaticamente das dependências necessárias.
O exemplo seguinte mostra uma interface de rede que depende de uma rede virtual, grupo de segurança de rede e endereço IP público. Para obter o modelo completo, veja o modelo de início rápido de uma VM do Linux.
{
"type": "Microsoft.Network/networkInterfaces",
"apiVersion": "2022-07-01",
"name": "[variables('networkInterfaceName')]",
"location": "[parameters('location')]",
"dependsOn": [
"[resourceId('Microsoft.Network/networkSecurityGroups/', parameters('networkSecurityGroupName'))]",
"[resourceId('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]",
"[resourceId('Microsoft.Network/publicIpAddresses/', variables('publicIpAddressName'))]"
],
...
}
Com languageVersion 2.0, utilize o nome simbólico do recurso em dependsOn
matrizes. Por exemplo:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"languageVersion": "2.0",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]"
}
},
"resources": {
"myStorage": {
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2023-01-01",
"name": "[format('storage{0}', uniqueString(resourceGroup().id))]",
"location": "[parameters('location')]",
"sku": {
"name": "Standard_LRS"
},
"kind": "StorageV2"
},
"myVm": {
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2023-03-01",
"name": "[format('vm{0}', uniqueString(resourceGroup().id))]",
"location": "[parameters('location')]",
"dependsOn": [
"myStorage"
],
...
}
}
}
Embora possa estar inclinado a utilizar dependsOn
para mapear relações entre os seus recursos, é importante compreender por que motivo o está a fazer. Por exemplo, para documentar a forma como os recursos estão interligados, dependsOn
não é a abordagem certa. Após a implementação, o recurso não retém dependências de implementação nas respetivas propriedades, pelo que não existem comandos ou operações que lhe permitam ver dependências. Definir dependências desnecessárias atrasa o tempo de implementação porque Resource Manager não conseguem implementar esses recursos em paralelo.
Recursos subordinados
Uma dependência de implementação implícita não é criada automaticamente entre um recurso subordinado e o recurso principal. Se precisar de implementar o recurso subordinado após o recurso principal, defina a dependsOn
propriedade.
O exemplo seguinte mostra um SERVIDOR SQL lógico e uma base de dados. Repare que é definida uma dependência explícita entre a base de dados e o servidor, mesmo que a base de dados seja um subordinado do servidor.
"resources": [
{
"type": "Microsoft.Sql/servers",
"apiVersion": "2022-05-01-preview",
"name": "[parameters('serverName')]",
"location": "[parameters('location')]",
"properties": {
"administratorLogin": "[parameters('administratorLogin')]",
"administratorLoginPassword": "[parameters('administratorLoginPassword')]"
},
"resources": [
{
"type": "databases",
"apiVersion": "2022-05-01-preview",
"name": "[parameters('sqlDBName')]",
"location": "[parameters('location')]",
"sku": {
"name": "Standard",
"tier": "Standard"
},
"dependsOn": [
"[resourceId('Microsoft.Sql/servers', parameters('serverName'))]"
]
}
]
}
]
Para obter o modelo completo, veja o modelo de início rápido para SQL do Azure Base de Dados.
funções de referência e lista
A função de referência permite que uma expressão deriva o respetivo valor a partir de outros pares de nomes JSON e de valores ou recursos de runtime. As funções list* devolvem valores para um recurso de uma operação de lista.
As expressões de referência e lista declaram implicitamente que um recurso depende de outro. Sempre que possível, utilize uma referência implícita para evitar adicionar uma dependência desnecessária.
Para impor uma dependência implícita, veja o recurso por nome e não o ID do recurso. Se transmitir o ID do recurso para as funções de referência ou lista, não será criada uma referência implícita.
O formato geral da reference
função é:
reference('resourceName').propertyPath
O formato geral da listKeys
função é:
listKeys('resourceName', 'yyyy-mm-dd')
No exemplo seguinte, um ponto final da CDN depende explicitamente do perfil da CDN e depende implicitamente de uma aplicação Web.
{
"type": "endpoints",
"apiVersion": "2021-06-01",
"name": "[variables('endpointName')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[variables('profileName')]"
],
"properties": {
"originHostHeader": "[reference(variables('webAppName')).hostNames[0]]",
...
}
...
}
Para saber mais, veja função de referência.
Depender de recursos num ciclo
Para implementar recursos que dependem de recursos num ciclo de cópia, tem duas opções. Pode definir uma dependência em recursos individuais no ciclo ou em todo o ciclo.
Nota
Para a maioria dos cenários, deve definir a dependência de recursos individuais no ciclo de cópia. Só depende de todo o ciclo quando precisar que todos os recursos no ciclo existam antes de criar o recurso seguinte. Definir a dependência em todo o ciclo faz com que o gráfico de dependências se expanda significativamente, especialmente se esses recursos em ciclo dependerem de outros recursos. As dependências expandidas dificultam a conclusão eficiente da implementação.
O exemplo seguinte mostra como implementar várias máquinas virtuais. O modelo cria o mesmo número de interfaces de rede. Cada máquina virtual depende de uma interface de rede, em vez de todo o ciclo.
{
"type": "Microsoft.Network/networkInterfaces",
"apiVersion": "2022-07-01",
"name": "[format('{0}-{1}', variables('nicPrefix'), copyIndex())]",
"location": "[parameters('location')]",
"copy": {
"name": "nicCopy",
"count": "[parameters('vmCount')]"
},
...
},
{
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2022-11-01",
"name": "[format('{0}{1}', variables('vmPrefix'), copyIndex())]",
"location": "[parameters('location')]",
"dependsOn": [
"[resourceId('Microsoft.Network/networkInterfaces',format('{0}-{1}', variables('nicPrefix'),copyIndex()))]"
],
"copy": {
"name": "vmCopy",
"count": "[parameters('vmCount')]"
},
"properties": {
"networkProfile": {
"networkInterfaces": [
{
"id": "[resourceId('Microsoft.Network/networkInterfaces',format('(0)-(1)', variables('nicPrefix'), copyIndex()))]",
"properties": {
"primary": "true"
}
}
]
},
...
}
}
O exemplo seguinte mostra como implementar três contas de armazenamento antes de implementar a máquina virtual. Tenha em atenção que o copy
elemento está name
definido como storagecopy
e o dependsOn
elemento da máquina virtual também está definido como storagecopy
.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]"
}
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2022-09-01",
"name": "[format('{0}storage{1}, copyIndex(), uniqueString(resourceGroup().id))]",
"location": "[parameters('location')]",
"sku": {
"name": "Standard_LRS"
},
"kind": "Storage",
"copy": {
"name": "storagecopy",
"count": 3
},
"properties": {}
},
{
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2022-11-01",
"name": "[format('VM{0}', uniqueString(resourceGroup().id))]",
"dependsOn": ["storagecopy"],
...
}
]
}
Os nomes simbólicos podem ser utilizados em dependsOn
matrizes. Se um nome simbólico for para um ciclo de cópia, todos os recursos no ciclo são adicionados como dependências. O exemplo anterior pode ser escrito como o seguinte JSON. No exemplo, myVM depende de todas as contas de armazenamento no ciclo myStorages .
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"languageVersion": "2.0",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]"
}
},
"resources": {
"myStorages": {
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2022-09-01",
"name": "[format('{0}storage{1}, copyIndex(), uniqueString(resourceGroup().id))]",
"location": "[parameters('location')]",
"sku": {
"name": "Standard_LRS"
},
"kind": "Storage",
"copy": {
"name": "storagecopy",
"count": 3
},
"properties": {}
},
"myVM": {
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2022-11-01",
"name": "[format('VM{0}', uniqueString(resourceGroup().id))]",
"dependsOn": ["myStorages"],
...
}
}
}
Dependências circulares
Resource Manager identifica dependências circulares durante a validação do modelo. Se receber um erro de uma dependência circular, avalie o modelo para ver se podem ser removidas dependências. Se a remoção de dependências não funcionar, pode evitar dependências circulares ao mover algumas operações de implementação para recursos subordinados. Implemente os recursos subordinados após os recursos que têm a dependência circular. Por exemplo, suponha que está a implementar duas máquinas virtuais, mas tem de definir propriedades em cada uma que se refira à outra. Pode implementá-los pela seguinte ordem:
- vm1
- vm2
- A extensão na vm1 depende da vm1 e da vm2. A extensão define os valores na vm1 que obtém da vm2.
- A extensão na vm2 depende da vm1 e da vm2. A extensão define os valores na vm2 que obtém da vm1.
Para obter informações sobre como avaliar a ordem de implementação e resolver erros de dependência, veja Resolver erros comuns de implementação do Azure com o Azure Resource Manager.
Passos seguintes
- Para ver um tutorial, veja Tutorial: Criar modelos do ARM com recursos dependentes.
- Para obter um módulo do Learn que abrange dependências de recursos, veja Gerir implementações de cloud complexas com funcionalidades avançadas de modelo do ARM.
- Para obter recomendações ao definir dependências, veja Melhores práticas do modelo do ARM.
- Para saber mais sobre a resolução de problemas de dependências durante a implementação, veja Resolver erros comuns de implementação do Azure com o Azure Resource Manager.
- Para saber mais sobre como criar modelos do Azure Resource Manager, veja Compreender a estrutura e a sintaxe dos modelos do ARM.
- Para obter uma lista das funções disponíveis num modelo, veja Funções de modelo do ARM.