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 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 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

In 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 worden 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 quickstart-sjabloon voor een Virtuele Linux-machine voor de volledige sjabloon.

{
    "type": "Microsoft.Network/networkInterfaces",
    "apiVersion": "2020-06-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'))]"
    ],
    ...
}

Hoewel u misschien geneigd bent om relaties tussen uw resources toe te wijzen, is het belangrijk om te dependsOn begrijpen waarom u dit doet. Als u bijvoorbeeld wilt documenteren hoe resources met elkaar zijn verbonden, dependsOn is dit niet de juiste aanpak. 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": "2020-02-02-preview",
    "name": "[parameters('serverName')]",
    "location": "[parameters('location')]",
    "properties": {
      "administratorLogin": "[parameters('administratorLogin')]",
      "administratorLoginPassword": "[parameters('administratorLoginPassword')]"
    },
    "resources": [
      {
        "type": "databases",
        "apiVersion": "2020-08-01-preview",
        "name": "[parameters('sqlDBName')]",
        "location": "[parameters('location')]",
        "sku": {
          "name": "Standard",
          "tier": "Standard"
          },
        "dependsOn": [
          "[resourceId('Microsoft.Sql/servers', concat(parameters('serverName')))]"
        ]
      }
    ]
  }
]

Zie de snelstartsjabloon voor Azure SQL Database voor de volledige sjabloon.

naslag- en lijstfuncties

Met de verwijzingsfunctie 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 er onnodige afhankelijkheid wordt toegevoegd.

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 referentie- 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.

{
    "name": "[variables('endpointName')]",
    "apiVersion": "2016-04-02",
    "type": "endpoints",
    "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. Is 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 lussen van resources 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": "2020-05-01",
  "name": "[concat(variables('nicPrefix'),'-',copyIndex())]",
  "location": "[parameters('location')]",
  "copy": {
    "name": "nicCopy",
    "count": "[parameters('vmCount')]"
  },
  ...
},
{
  "type": "Microsoft.Compute/virtualMachines",
  "apiVersion": "2020-06-01",
  "name": "[concat(variables('vmPrefix'),copyIndex())]",
  "location": "[parameters('location')]",
  "dependsOn": [
    "[resourceId('Microsoft.Network/networkInterfaces',concat(variables('nicPrefix'),'-',copyIndex()))]"
  ],
  "copy": {
    "name": "vmCopy",
    "count": "[parameters('vmCount')]"
  },
  "properties": {
    "networkProfile": {
      "networkInterfaces": [
        {
          "id": "[resourceId('Microsoft.Network/networkInterfaces',concat(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": {},
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2019-04-01",
      "name": "[concat(copyIndex(),'storage', uniqueString(resourceGroup().id))]",
      "location": "[resourceGroup().location]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "Storage",
      "copy": {
        "name": "storagecopy",
        "count": 3
      },
      "properties": {}
    },
    {
      "type": "Microsoft.Compute/virtualMachines",
      "apiVersion": "2015-06-15",
      "name": "[concat('VM', uniqueString(resourceGroup().id))]",
      "dependsOn": ["storagecopy"],
      ...
    }
  ],
  "outputs": {}
}

Kringafhankelijkheden

Resource Manager identificeert kringafhankelijkheden tijdens de sjabloonvalidatie. Als u een foutmelding krijgt voor een kringafhankelijkheid, evalueert u de sjabloon om te zien of eventuele afhankelijkheden kunnen worden verwijderd. Als het verwijderen van afhankelijkheden niet werkt, kunt u kringafhankelijkheden vermijden door enkele implementatiebewerkingen naar onderliggende resources te verplaatsen. Implementeer de onderliggende resources na de resources met de kringafhankelijkheid. Stel dat u twee virtuele machines implementeert, maar dat u eigenschappen moet instellen op elk apparaat dat naar de andere verwijst. U kunt ze in de volgende volgorde implementeren:

  1. vm1
  2. vm2
  3. De extensie op vm1 is afhankelijk van vm1 en vm2. De extensie stelt waarden in op vm1 die deze ophaalt van vm2.
  4. De extensie op vm2 is afhankelijk van vm1 en vm2. De extensie stelt waarden in op vm2 die deze ophaalt 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