De volgorde voor het implementeren van resources in ARM-sjablonen definiëren
Bij het implementeren van resources moet u er mogelijk voor zorgen dat sommige resources bestaan vóór andere resources. U hebt bijvoorbeeld een logische SQL-server nodig voordat u een database implementeert. U stelt deze relatie vast door één resource als afhankelijk van de andere resource te markeren. Gebruik het dependsOn
element om een expliciete afhankelijkheid te definiëren. Gebruik de verwijzings - of lijstfuncties om een impliciete afhankelijkheid te definiëren.
Azure Resource Manager evalueert de afhankelijkheden tussen resources en implementeert ze in hun afhankelijke volgorde. Als resources niet van elkaar afhankelijk zijn, worden deze door Resource Manager parallel geïmplementeerd. U hoeft alleen afhankelijkheden te definiëren voor resources die in dezelfde sjabloon zijn geïmplementeerd.
Tip
We raden Bicep aan omdat het dezelfde mogelijkheden biedt als ARM-sjablonen en de syntaxis gemakkelijker te gebruiken is. Zie resourceafhankelijkheden voor meer informatie.
dependsOn
Binnen uw Azure Resource Manager-sjabloon (ARM-sjabloon) kunt u met het dependsOn
element één resource definiëren als afhankelijk van een of meer resources. De waarde is een JSON-matrix (JavaScript Object Notation) met tekenreeksen, die elk een resourcenaam of id zijn. De matrix kan resources bevatten die voorwaardelijk zijn geïmplementeerd. Wanneer een voorwaardelijke resource niet wordt geïmplementeerd, verwijdert Azure Resource Manager deze automatisch uit de vereiste afhankelijkheden.
In het volgende voorbeeld ziet u een netwerkinterface die afhankelijk is van een virtueel netwerk, een netwerkbeveiligingsgroep en een openbaar IP-adres. Zie de quickstartsjabloon voor een virtuele Linux-machine voor de volledige sjabloon.
{
"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'))]"
],
...
}
Gebruik met languageVersion 2.0 de symbolische naam van de resource in dependsOn
matrices. Voorbeeld:
{
"$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"
],
...
}
}
}
Hoewel u misschien geneigd bent om relaties tussen uw resources toe te dependsOn
wijzen, is het belangrijk om te begrijpen waarom u dit doet. Als u bijvoorbeeld wilt documenteren hoe resources onderling zijn verbonden, dependsOn
is dit niet de juiste benadering. Na de implementatie behoudt de resource geen implementatieafhankelijkheden in de eigenschappen, dus er zijn geen opdrachten of bewerkingen waarmee u afhankelijkheden kunt zien. Het instellen van onnodige afhankelijkheden vertraagt de implementatietijd omdat Resource Manager deze resources niet parallel kan implementeren.
Onderliggende resources
Een impliciete implementatieafhankelijkheid wordt niet automatisch gemaakt tussen een onderliggende resource en de bovenliggende resource. Als u de onderliggende resource na de bovenliggende resource wilt implementeren, stelt u de dependsOn
eigenschap in.
In het volgende voorbeeld ziet u een logische SQL-server en -database. U ziet dat er een expliciete afhankelijkheid is gedefinieerd tussen de database en de server, ook al is de database een onderliggend element van de server.
"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'))]"
]
}
]
}
]
Zie de quickstart-sjabloon voor Azure SQL Database voor de volledige sjabloon.
naslag- en lijstfuncties
Met de referentiefunctie kan een expressie de waarde afleiden van andere JSON-naam- en waardeparen of runtime-resources. De functies list* retourneren waarden voor een resource uit een lijstbewerking.
Verwijzings- en lijstexpressies declareren impliciet dat de ene resource afhankelijk is van een andere. Gebruik waar mogelijk een impliciete verwijzing om te voorkomen dat u een onnodige afhankelijkheid toevoegt.
Als u een impliciete afhankelijkheid wilt afdwingen, raadpleegt u de resource op naam, niet de resource-id. Als u de resource-id doorgeeft aan de verwijzings- of lijstfuncties, wordt er geen impliciete verwijzing gemaakt.
De algemene indeling van de reference
functie is:
reference('resourceName').propertyPath
De algemene indeling van de listKeys
functie is:
listKeys('resourceName', 'yyyy-mm-dd')
In het volgende voorbeeld is een CDN-eindpunt expliciet afhankelijk van het CDN-profiel en impliciet afhankelijk van een web-app.
{
"type": "endpoints",
"apiVersion": "2021-06-01",
"name": "[variables('endpointName')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[variables('profileName')]"
],
"properties": {
"originHostHeader": "[reference(variables('webAppName')).hostNames[0]]",
...
}
...
}
Zie de referentiefunctie voor meer informatie.
Afhankelijk van resources in een lus
Als u resources wilt implementeren die afhankelijk zijn van resources in een kopieerlus, hebt u twee opties. U kunt een afhankelijkheid van afzonderlijke resources in de lus of op de hele lus instellen.
Notitie
Voor de meeste scenario's moet u de afhankelijkheid van afzonderlijke resources in de kopieerlus instellen. Alleen afhankelijk van de hele lus wanneer u alle resources in de lus nodig hebt om te bestaan voordat u de volgende resource maakt. Als u de afhankelijkheid van de hele lus instelt, wordt de grafiek met afhankelijkheden aanzienlijk uitgebreid, met name als deze geluste resources afhankelijk zijn van andere resources. De uitgebreide afhankelijkheden maken het lastig om de implementatie efficiënt te voltooien.
In het volgende voorbeeld ziet u hoe u meerdere virtuele machines implementeert. De sjabloon maakt hetzelfde aantal netwerkinterfaces. Elke virtuele machine is afhankelijk van één netwerkinterface, in plaats van de hele lus.
{
"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"
}
}
]
},
...
}
}
In het volgende voorbeeld ziet u hoe u drie opslagaccounts implementeert voordat u de virtuele machine implementeert. U ziet dat het copy
element is name
ingesteld op storagecopy
en dat het dependsOn
element voor de virtuele machine ook is ingesteld op 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"],
...
}
]
}
Symbolische namen kunnen worden gebruikt in dependsOn
matrices. Als een symbolische naam voor een kopieerlus is, worden alle resources in de lus toegevoegd als afhankelijkheden. Het voorgaande voorbeeld kan worden geschreven als de volgende JSON. In het voorbeeld is myVM afhankelijk van alle opslagaccounts in de myStorages-lus .
{
"$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"],
...
}
}
}
Kringafhankelijkheden
Resource Manager identificeert kringafhankelijkheden tijdens de sjabloonvalidatie. Als u een foutmelding krijgt voor een kringafhankelijkheid, evalueert u de sjabloon om te zien of er afhankelijkheden kunnen worden verwijderd. Als het verwijderen van afhankelijkheden niet werkt, kunt u kringafhankelijkheden voorkomen door bepaalde implementatiebewerkingen naar onderliggende resources te verplaatsen. Implementeer de onderliggende resources na de resources met de kringafhankelijkheid. Stel dat u twee virtuele machines implementeert, maar u moet eigenschappen instellen op elk machines die naar de andere verwijzen. U kunt ze in de volgende volgorde implementeren:
- vm1
- vm2
- De extensie op vm1 is afhankelijk van vm1 en vm2. Met de extensie worden waarden ingesteld op vm1 die worden opgehaald van vm2.
- De extensie op vm2 is afhankelijk van vm1 en vm2. Met de extensie worden waarden ingesteld op vm2 die worden opgehaald van vm1.
Zie Veelvoorkomende Azure-implementatiefouten met Azure Resource Manager oplossen voor informatie over het beoordelen van de implementatievolgorde en het oplossen van afhankelijkheidsfouten.
Volgende stappen
- Zie Zelfstudie: ARM-sjablonen maken met afhankelijke resources om een zelfstudie te doorlopen.
- Zie Complexe cloudimplementaties beheren met behulp van geavanceerde ARM-sjabloonfuncties voor een Learn-module die betrekking heeft op resourceafhankelijkheden.
- Zie aanbevolen procedures voor ARM-sjablonen voor aanbevelingen bij het instellen van afhankelijkheden.
- Zie Veelvoorkomende Azure-implementatiefouten met Azure Resource Manager oplossen voor meer informatie over het oplossen van afhankelijkheden tijdens de implementatie.
- Zie De structuur en syntaxis van ARM-sjablonen begrijpen voor meer informatie over het maken van Azure Resource Manager-sjablonen.
- Zie ARM-sjabloonfuncties voor een lijst met de beschikbare functies in een sjabloon.