定義在 ARM 範本中部署資源的順序 \(部分機器翻譯\)

部署資源時,必須確認某些資源的存在順序優先於其他資源。 例如,需要先有邏輯 SQL 伺服器才能部署資料庫。 將某個資源標示為相依於其他資源,即可建立此關聯性。 使用 dependsOn 元素可定義明確的相依性。 使用 referencelist 函式可定義隱含的相依性。

Azure Resource Manager 會評估資源之間的相依性,然後依其相依順序進行部署。 如果資源並未彼此相依,Resource Manager 就會平行部署資源。 您只需要為部署在相同範本中的資源定義相依性。

提示

我們建議使用 Bicep,因為其提供的功能與 ARM 範本相同,而且語法更易於使用。 若要深入了解,請參閱資源相依性

dependsOn

在您的 Azure Resource Manager 範本 (ARM 範本) 中,可利用 dependsOn 元素,將一個資源定義為相依於一或多個資源。 其值會是 JavaScript 物件標記法 (JSON) 字串陣列,其中的每個字串皆為資源名稱或識別碼。 陣列可包括條件式部署的資源。 未部署條件式資源時,Azure Resource Manager 會自動將其從必要相依性中移除。

以下範例展示相依於虛擬網路、網路安全性群組以及公用 IP 位址的網路介面。 如需完整範本,請參閱 Linux VM 快速入門範本

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

使用 languageVersion 2.0 時,請在 dependsOn 陣列中使用資源符號名稱。 例如:

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

雖然您可能傾向使用 dependsOn 來對應資源之間的關聯性,但請務必了解您要這麼做的原因。 例如,若要記錄資源互連的方式,dependsOn 並不是適當的方法。 部署之後,資源不會在其屬性中保留部署相依性,因此不會有可讓您看到相依性的命令或作業。 設定不必要的相依性會拖慢部署時間,因為 Azure Resource Manager 無法平行部署這些資源。

子資源

子系資源與父代資源之間不會自動建立隱含的部署相依性。 若需要在父代資源之後再部署子系資源,請設定 dependsOn 屬性。

下列範例展示邏輯 SQL 伺服器和資料庫。 請注意,即使資料庫是伺服器的子系,資料庫及伺服器之間仍需定義明確相依性。

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

如需完整的範本,請參閱 Azure SQL Database 快速入門範本

reference 和 list 函式

reference 函式 可讓運算式從其他 JSON 名稱和值組或執行階段資源衍生其值。 list* 函式會從清單作業傳回資源的值。

參考與清單運算式會隱含宣告某個資源相依於另一個資源。 請盡可能使用隱含的參考,以避免新增不必要的相依性。

若要強制執行隱含相依性,請依名稱 (而非資源識別碼) 參考資源。 如果您將資源識別碼傳遞到 reference 或 list 函式,就不會建立隱含參考。

reference 函式的一般格式為:

reference('resourceName').propertyPath

listKeys 函式的一般格式為:

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

在下列範例中,CDN 端點明確相依於 CDN 設定檔,並隱含相依於 Web 應用程式。

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

若要深入了解,請參閱 reference 函數

依迴圈中的資源而定

若要部署的資源相依於複製迴圈中的資源,您有兩種選擇。 您可以對迴圈中個別的資源或是針對整個迴圈,設定相依性。

注意

大多數情況下,您應該對複製迴圈內的個別資源設定相依性。 只有當您需要迴圈中的所有資源都存在,才能建立下一個資源時,才對整個迴圈設定相依性。 對整個迴圈設定相依性,會使得相依性關係圖大幅展開,尤其是在迴圈資源相依於其他資源時。 展開的相依性會讓部署難以有效率地完成。

下列範例說明如何部署多個虛擬機器。 該範本會建立相同數目的網路介面。 每個虛擬機器都相依於一個網路介面,而非整個迴圈。

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

下列範例示範如何在部署虛擬機器前,先部署三個儲存體帳戶。 請注意,copy 元素已將 name 設為 storagecopy,且虛擬機器的 dependsOn 元素也已設為 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"],
      ...
    }
  ]
}

符號名稱可用於 dependsOn 陣列。 如果符號名稱是複製迴圈,迴圈中所有資源都會新增為相依性。 上述範例可以撰寫為下列 JSON。 在範例中,myVM 相依於 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"],
      ...
    }
  }
}

循環依存性

Resource Manager 會在範本驗證期間識別迴圈相依性。 若收到循環相依性的錯誤,請評估您的範本,查看是否可以移除任何相依性。 若移除相依性後仍未解決錯誤,可以將某些部署作業移往子系資源,以避免發生循環相依性。 在具有迴圈相依性的資源之後部署子資源。 例如,假設您要部署兩部虛擬機器,但是您必須分別在上面設定互相參考的屬性。 您可以採取下列順序部署︰

  1. vm1
  2. vm2
  3. vm1 的擴充相依於 vm1 和 vm2。 擴充在 vm1 上設定從 vm2 取得的值。
  4. vm2 的擴充相依於 vm1 和 vm2。 擴充在 vm2 上設定從 vm1 取得的值。

如需評估部署順序及解決相依性錯誤的相關資訊,請參閱使用 Azure Resource Manager 針對常見的 Azure 部署錯誤進行疑難排解

下一步