如何在嵌套的 ARM 模板中设置对子资源的依赖?

How can I set dependencies on child resources in nested ARM template?

我正在尝试使用嵌套模板在订阅级别部署资源组和其中的多个资源。

Microsoft 文档中有一个 example of deploying resource group and storage account 我正在努力遵循。我正在尝试在存储帐户资源和容器资源之间创建另一个内部依赖级别。也就是说,只有在存储帐户部署完成后才能部署容器。这是我的模板的简化版本:

{
  "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "rgName": {
      "type": "string"
    },
    "rgLocation": {
      "type": "string"
    },
    "storagePrefix": {
      "type": "string",
      "maxLength": 11
    },
    "containerName": {
      "type": "string"
    }
  },
  "variables": {
    "storageName": "[concat(parameters('storagePrefix'), uniqueString(subscription().id, parameters('rgName')))]"
  },
  "resources": [
    {
      "type": "Microsoft.Resources/resourceGroups",
      "apiVersion": "2021-04-01",
      "name": "[parameters('rgName')]",
      "location": "[parameters('rgLocation')]",
      "properties": {}
    },
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2021-04-01",
      "name": "storageDeployment",
      "resourceGroup": "[parameters('rgName')]",
      "dependsOn": [
        "[resourceId('Microsoft.Resources/resourceGroups/', parameters('rgName'))]"
      ],
      "properties": {
        "mode": "Incremental",
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "parameters": {},
          "variables": {},
          "resources": [
            {
              "type": "Microsoft.Storage/storageAccounts",
              "apiVersion": "2021-04-01",
              "name": "[variables('storageName')]",
              "location": "[parameters('rgLocation')]",
              "sku": {
                "name": "Standard_LRS"
              },
              "kind": "StorageV2"
            },
            {
              "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
              "apiVersion": "2021-06-01",
              "name": "[format('{0}/default/{1}', variables('storageName'), parameters('containerName'))]",
              "dependsOn": [
                "[resourceId('Microsoft.Storage/storageAccounts', variables('storageName'))]"
              ]
            }
          ],
          "outputs": {}
        }
      }
    }
  ],
  "outputs": {}
}

当我尝试使用 PowerShell 脚本 New-AzSubscriptionDeployment 部署此模板时,出现以下错误:

|  InvalidTemplate - Long running operation failed with status 'Failed'. Additional Info:'Deployment template validation failed: 'The resource 'Microsoft.Storage/storageAccounts/myStorageAccount' is not defined in the template. Please see https://aka.ms/arm-template for usage details.'.'

我知道它与容器资源的 dependsOn 部分有关。但是我该如何解决这个问题呢?


编辑:所选答案解决了依赖性问题,但是在需要使用 concatlistKeys 表达式调用值的情况下,问题仍然存在。这是一个示例,其中设置 AzureWebJobsStorage 的值会在嵌套模板中引发错误:

{
    "type": "Microsoft.Web/sites",
    [ ... ]
    "dependsOn": [
        "[variables('hostingPlanName')]",
        "[variables('functionAppStorageAccountName')]"
    ],
    "properties": {
        "serverFarmId": "[variables('hostingPlanName')]",
        "siteConfig": {
            "appSettings": [
                {
                    "name": "AzureWebJobsStorage",
                    "value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('functionAppstorageAccountName'), ';EndpointSuffix=', environment().suffixes.storage, ';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('functionAppstorageAccountName')), '2021-04-01').keys[0].value)]"
                }
                [ ... ]
            ]
        }

AzureWebJobsStorage 的值导致部署失败并出现以下错误:

`Status Message: The Resource 'Microsoft.Storage/storageAccounts/stfuncaedotestfeb16g' under resource group '<null>' was not found. For more details
     | please go to https://aka.ms/ARMResourceNotFoundFix (Code:ResourceNotFound)  CorrelationId: 55942377-6d0f-40ec-9733-33b9c3ea13de

我尝试通过使用资源组名称(然后是订阅 ID)来更加详细,但这并没有解决问题。

您应该可以使用:

"dependsOn": [
  "[variables('storageName')]"
]

请注意,仅当模板中没有其他同名资源时才有效——否则您必须手动构建完整的 resourceId,例如:

[format('{0}/resourceGroups/{1}/providers/Microsoft.Storage/storageAccounts/{2}', subscription().id, parameters('rgName'), variables('storageName'))]

后一种形式总是有效的,只是有点冗长。

更详细一点的是,resourceId 函数在订阅范围内无法正常工作。