Dela via


Definiera distributionsordningen för resurser i ARM-mallar

När du distribuerar resurser kan du behöva se till att vissa resurser finns före andra resurser. Du behöver till exempel en logisk SQL-server innan du distribuerar en databas. Du upprättar den här relationen genom att markera en resurs som beroende av den andra resursen. Använd elementet dependsOn för att definiera ett explicit beroende. Använd referens- eller listfunktionerna för att definiera ett implicit beroende.

Azure Resource Manager utvärderar beroendena mellan resurser och distribuerar dem i beroende ordning. När resurserna inte är beroende av varandra distribuerar Resource Manager dem parallellt. Du behöver bara definiera beroenden för resurser som distribueras i samma mall.

Dricks

Vi rekommenderar Bicep eftersom det erbjuder samma funktioner som ARM-mallar och syntaxen är enklare att använda. Mer information finns i resursberoenden.

dependsOn

I din Azure Resource Manager-mall (ARM-mall) kan du med elementet dependsOn definiera en resurs som beroende av en eller flera resurser. Dess värde är en JSON-matris (JavaScript Object Notation), som var och en är ett resursnamn eller ID. Matrisen kan innehålla resurser som är villkorligt distribuerade. När en villkorsstyrd resurs inte distribueras tar Azure Resource Manager automatiskt bort den från de beroenden som krävs.

I följande exempel visas ett nätverksgränssnitt som är beroende av ett virtuellt nätverk, en nätverkssäkerhetsgrupp och en offentlig IP-adress. Den fullständiga mallen finns i snabbstartsmallen för en virtuell Linux-dator.

{
  "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'))]"
  ],
  ...
}

Med languageVersion 2.0 använder du resursens symboliska namn i dependsOn matriser. Till exempel:

{
  "$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"
      ],
      ...
    }
  }
}

Även om du kanske är benägen att använda dependsOn för att mappa relationer mellan dina resurser är det viktigt att förstå varför du gör det. Om du till exempel vill dokumentera hur resurser är sammankopplade dependsOn är det inte rätt metod. Efter distributionen behåller resursen inte distributionsberoenden i dess egenskaper, så det finns inga kommandon eller åtgärder som gör att du kan se beroenden. Om du anger onödiga beroenden går distributionstiden långsammare eftersom Resource Manager inte kan distribuera resurserna parallellt.

Underordnade resurser

Ett implicit distributionsberoende skapas inte automatiskt mellan en underordnad resurs och den överordnade resursen. Om du behöver distribuera den underordnade resursen efter den överordnade resursen anger du egenskapen dependsOn .

I följande exempel visas en logisk SQL-server och databas. Observera att ett explicit beroende definieras mellan databasen och servern, även om databasen är underordnad servern.

"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'))]"
        ]
      }
    ]
  }
]

Den fullständiga mallen finns i snabbstartsmallen för Azure SQL Database.

referens- och listfunktioner

Med referensfunktionen kan ett uttryck härleda dess värde från andra JSON-namn och värdepar eller körningsresurser. List *-funktionerna returnerar värden för en resurs från en liståtgärd.

Referens- och listuttryck deklarerar implicit att en resurs är beroende av en annan. Använd när det är möjligt en implicit referens för att undvika att lägga till ett onödigt beroende.

Om du vill framtvinga ett implicit beroende läser du resursen efter namn, inte resurs-ID. Om du skickar resurs-ID:t till referens- eller listfunktionerna skapas ingen implicit referens.

Funktionens reference allmänna format är:

reference('resourceName').propertyPath

Funktionens listKeys allmänna format är:

listKeys('resourceName', 'yyyy-mm-dd')

I följande exempel är en CDN-slutpunkt uttryckligen beroende av CDN-profilen och är implicit beroende av en webbapp.

{
    "type": "endpoints",
    "apiVersion": "2021-06-01",
    "name": "[variables('endpointName')]",
    "location": "[resourceGroup().location]",
    "dependsOn": [
      "[variables('profileName')]"
    ],
    "properties": {
      "originHostHeader": "[reference(variables('webAppName')).hostNames[0]]",
      ...
    }
    ...
}

Mer information finns i referensfunktionen.

Beroende på resurser i en loop

Om du vill distribuera resurser som är beroende av resurser i en kopieringsloop har du två alternativ. Du kan antingen ange ett beroende av enskilda resurser i loopen eller på hela loopen.

Kommentar

I de flesta scenarier bör du ange beroendet av enskilda resurser i kopieringsloopen. Beror bara på hela loopen när du behöver alla resurser i loopen innan du skapar nästa resurs. Om du anger beroendet för hela loopen expanderar diagrammet beroenden avsevärt, särskilt om dessa loopade resurser är beroende av andra resurser. De utökade beroendena gör det svårt för distributionen att slutföras effektivt.

I följande exempel visas hur du distribuerar flera virtuella datorer. Mallen skapar samma antal nätverksgränssnitt. Varje virtuell dator är beroende av ett nätverksgränssnitt i stället för hela loopen.

{
  "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"
          }
        }
      ]
    },
    ...
  }
}

I följande exempel visas hur du distribuerar tre lagringskonton innan du distribuerar den virtuella datorn. Observera att elementet copy har name angetts till storagecopy och att elementet dependsOn för den virtuella datorn också är inställt på 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"],
      ...
    }
  ]
}

Symboliska namn kan användas i dependsOn matriser. Om ett symboliskt namn är för en kopieringsloop läggs alla resurser i loopen till som beroenden. Föregående exempel kan skrivas som följande JSON. I exemplet är myVM beroende av alla lagringskonton i myStorages-loopen.

{
  "$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"],
      ...
    }
  }
}

Cirkulära beroenden

Resource Manager identifierar cirkulära beroenden under mallvalidering. Om du får ett fel för ett cirkulärt beroende utvärderar du mallen för att se om några beroenden kan tas bort. Om det inte fungerar att ta bort beroenden kan du undvika cirkulära beroenden genom att flytta vissa distributionsåtgärder till underordnade resurser. Distribuera de underordnade resurserna efter de resurser som har det cirkulära beroendet. Anta till exempel att du distribuerar två virtuella datorer, men du måste ange egenskaper för var och en som refererar till den andra. Du kan distribuera dem i följande ordning:

  1. vm1
  2. vm2
  3. Tillägget på vm1 beror på vm1 och vm2. Tillägget anger värden på vm1 som det hämtar från vm2.
  4. Tillägget på vm2 beror på vm1 och vm2. Tillägget anger värden på vm2 som det hämtar från vm1.

Information om hur du utvärderar distributionsordningen och löser beroendefel finns i Felsöka vanliga Azure-distributionsfel med Azure Resource Manager.

Nästa steg