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 vóór andere resources bestaan. U hebt bijvoorbeeld een logische SQL-server nodig voordat u een database implementeert. U brengt deze relatie tot stand door één resource te markeren als afhankelijk van de andere resource. 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 deze in de 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 eenvoudiger te gebruiken is. Zie resourceafhankelijkheden voor meer informatie.
dependsOn
Binnen uw ARM-sjabloon (Azure Resource Manager) kunt u met het dependsOn
element één resource definiëren als afhankelijk van een of meer resources. De waarde ervan 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, netwerkbeveiligingsgroep en openbaar IP-adres. Zie de quickstart-sjabloon voor een Linux-VM 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. Bijvoorbeeld:
{
"$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 dependsOn
relaties tussen uw resources toe te wijzen, is het belangrijk om te begrijpen waarom u dit doet. Het is bijvoorbeeld niet de juiste methode om vast te leggen hoe resources onderling zijn verbonden dependsOn
. 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 kunt implementeren.
Onderliggende resources
Er wordt niet automatisch een impliciete implementatieafhankelijkheid 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 Quickstart-sjabloon voor Azure SQL Database voor de volledige sjabloon.
verwijzings- en lijstfuncties
Met de verwijzingsfunctie kan een expressie de waarde afleiden van andere JSON-naam- en waardeparen of runtime-resources. De lijst*-functies retourneren waarden voor een resource uit een lijstbewerking.
Verwijzings- en lijstexpressies declareren impliciet dat één resource afhankelijk is van een andere resource. Gebruik indien mogelijk een impliciete verwijzing om onnodige afhankelijkheid te voorkomen.
Als u een impliciete afhankelijkheid wilt afdwingen, raadpleegt u de resource op naam, niet op 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 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 instellen van afzonderlijke resources in de lus of van de hele lus.
Notitie
Voor de meeste scenario's moet u de afhankelijkheid van afzonderlijke resources binnen de kopieerlus instellen. Alleen afhankelijk van de hele lus wanneer u alle resources in de lus wilt laten 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 resources met een lus afhankelijk zijn van andere resources. De uitgebreide afhankelijkheden maken het moeilijk om de implementatie efficiënt te voltooien.
In het volgende voorbeeld ziet u hoe u meerdere virtuele machines implementeert. Met de sjabloon wordt hetzelfde aantal netwerkinterfaces gemaakt. 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 sjabloonvalidatie. Als u een foutbericht ontvangt 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 sommige implementatiebewerkingen naar onderliggende resources te verplaatsen. Implementeer de onderliggende resources na de resources die de kringafhankelijkheid hebben. Stel dat u twee virtuele machines implementeert, maar dat u eigenschappen moet instellen voor elke virtuele machine die naar de andere verwijst. U kunt ze in de volgende volgorde implementeren:
- vm1
- vm2
- De extensie op vm1 is afhankelijk van vm1 en vm2. De extensie stelt waarden in op vm1 die worden opgehaald uit vm2.
- De extensie op vm2 is afhankelijk van vm1 en vm2. De extensie stelt waarden in op vm2 die worden opgehaald van vm1.
Zie Veelvoorkomende azure-implementatiefouten oplossen met Azure Resource Manager voor informatie over het beoordelen van de implementatievolgorde en het oplossen van afhankelijkheidsfouten.
Volgende stappen
- Zie Zelfstudie: ARM-sjablonen maken met afhankelijke resources voor een zelfstudie.
- Zie Complexe cloudimplementaties beheren met behulp van geavanceerde ARM-sjabloonfuncties voor een Learn-module die resourceafhankelijkheden behandelt.
- Zie Aanbevolen procedures voor ARM-sjablonen voor aanbevelingen bij het instellen van afhankelijkheden.
- Zie Veelvoorkomende Azure-implementatiefouten oplossen met Azure Resource Manager voor meer informatie over het oplossen van problemen met afhankelijkheden tijdens de implementatie.
- Zie Inzicht in de structuur en syntaxis van ARM-sjablonen voor meer informatie over het maken van Azure Resource Manager-sjablonen.
- Zie ARM-sjabloonfuncties voor een lijst met de beschikbare functies in een sjabloon.