创建 Azure Function App 时找不到 ARM 模板存储帐户

ARM template storage account not found while creating Azure Function App

我有一个 ARM 模板,用于创建存储帐户、应用程序服务计划、Application Insights 和函数应用程序。在Function App 的dependsOn 部分,我将其配置为依赖其他三个资源。但是当我部署模板时,它失败并出现以下错误:

状态消息:未找到资源组 'dummy-rg' 下的资源 'Microsoft.Storage/storageAccounts/dummystorage'。

我看到首先创建了存储帐户、ASP 和 App Insights,然后是 Function App。因此,似乎依赖性得到了尊重。这几乎就像在创建函数应用程序时存储帐户配置尚未完全完成。正如您在下面的模板中看到的,Function App 资源使用 listKeys 获取存储帐户密钥作为配置的一部分。

有人知道如何防止这种情况发生吗?我已经阅读了文档中有关依赖项的所有内容,我相信这应该可行。

需要注意的是,存储帐户是根据条件部署的。我无法想象它与我的问题有关,但我只是想提一下。

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "functionAppName": {
            "type": "string"
        },
        "appServicePlanName": {
            "type": "string"
        },
        "appInsightsName": {
            "type": "string"
        },
        "deployStorage": {
            "type": "bool",
            "defaultValue": true
        },
        "storageAccountName": {
            "type": "string"
        },
        "utcDateTime": {
            "type": "string",
            "defaultValue": "[utcNow()]"
        }
    },
    "variables": {
        "storageAccountDeploymentName": "[concat('storageDeploy-', parameters('utcDateTime'))]",
    },
    "resources": [
        {
            "name": "[parameters('functionAppName')]",
            "apiVersion": "2018-11-01",
            "type": "Microsoft.Web/sites",
            "kind": "functionapp",
            "location": "[parameters('location')]",
            "tags": "[parameters('tags')]",
            "dependsOn": [
                "[parameters('appInsightsName')]",
                "[parameters('appServicePlanName')]",
                "[resourceId('Microsoft.Resources/deployments', variables('storageAccountDeploymentName'))]"
            ],
            "properties": {
                "name": "[parameters('functionAppName')]",
                "siteConfig": {
                    "appSettings": [
                        {
                            "name": "FUNCTIONS_EXTENSION_VERSION",
                            "value": "~3"
                        },
                        {
                            "name": "FUNCTIONS_WORKER_RUNTIME",
                            "value": "powershell"
                        },
                        {
                            "name": "APPINSIGHTS_INSTRUMENTATIONKEY",
                            "value": "[reference(concat('Microsoft.Insights/components/', parameters('appInsightsName')), '2015-05-01').InstrumentationKey]"
                        },
                        {
                            "name": "APPLICATIONINSIGHTS_CONNECTION_STRING",
                            "value": "[reference(concat('Microsoft.Insights/components/', parameters('appInsightsName')), '2015-05-01').ConnectionString]"
                        },
                        {
                            "name": "AzureWebJobsStorage",
                            "value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageAccountName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2019-06-01').keys[0].value,';EndpointSuffix=','core.windows.net')]"
                        },
                        {
                            "name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
                            "value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageAccountName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2019-06-01').keys[0].value,';EndpointSuffix=','core.windows.net')]"
                        },
                        {
                            "name": "WEBSITE_CONTENTSHARE",
                            "value": "[concat(toLower(parameters('functionAppName')), '813b')]"
                        }
                    ],
                    "use32BitWorkerProcess": false,
                    "powerShellVersion": "[variables('powerShellVersion')]"
                },
                "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]",
                "clientAffinityEnabled": true
            }
        },
        {
            "name": "[parameters('appServicePlanName')]",
            "apiVersion": "2018-11-01",
            "type": "Microsoft.Web/serverfarms",
            "location": "[parameters('location')]",
            "tags": "[parameters('tags')]"
            // snip
        },
        {
            "name": "[parameters('appInsightsName')]",
            "apiVersion": "2020-02-02-preview",
            "type": "microsoft.insights/components",
            "location": "[parameters('location')]",
            "tags": "[parameters('tags')]",
            // snip
        },
        {
            "name": "[variables('storageAccountDeploymentName')]",
            "type": "Microsoft.Resources/deployments",
            "apiVersion": "2019-10-01",
            "condition": "[parameters('deployStorage')]",
            "properties": {
                "expressionEvaluationOptions": {
                    "scope": "outer"
                },
                "mode": "Incremental",
                "template": {
                    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
                    "contentVersion": "1.0.0.0",
                    "resources": [
                        {
                            "name": "[parameters('storageAccountName')]",
                            "type": "Microsoft.Storage/storageAccounts",
                            "apiVersion": "2019-06-01",
                            "tags": "[parameters('tags')]",
                            "location": "[parameters('location')]",
                            // snip
                        }
                    ]
                }
            }
        }
    ]
}

我注意到您的存储 dependsOn 看起来像这样:

"dependsOn": [
            "[parameters('appInsightsName')]",
            "[parameters('appServicePlanName')]",
            "[resourceId('Microsoft.Resources/deployments', variables('storageAccountDeploymentName'))]"

而我对存储帐户和 Blob 容器的 despendsOn 看起来像这样......这可能是它不起作用的原因吗?我从未使用过 Microsoft.Resources/deployments(仅供参考,我的 ARM 模板部署正在运行)

"dependsOn": [
            "[resourceId('Microsoft.Storage/storageAccounts/blobServices/containers', variables('StorageAccountName'), 'default', variables('BlobContainerName2'))]",
            "[resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName'))]"

或者:

您可以放弃条件并每次都部署存储帐户。如果它存在则没有变化,如果它不存在则创建它。

唯一需要注意的是,如果您更改了存储帐户 post-部署,或者如果存储帐户具有基于时间戳或 GUID 等动态设置的名称。

我知道这是一个解决方法,但它应该可以解决您的问题,除非有上述警告。

我认为你 运行 喜欢这个:https://bmoore-msft.blog/2020/07/26/resource-not-found-dependson-is-not-working/

TLDR; listKeys 在部署引擎的单独作业中调用,如果该资源(即您的存储)不在同一部署中,则会提前调用。

  1. 您不需要嵌套您的 storageAccount 部署,不会有坏处但也无济于事。如果您的 storageAccount 部署是无条件的,那么它会有所帮助,因为 ARM 会在 运行 listKeys 之前等待。
  2. 如果您需要条件,唯一的解决方法是嵌套函数应用程序部署并设置对条件 storageAccount 的依赖(依赖不必是有条件的 ARM 会处理)。您需要将该嵌套部署的评估范围设置为“内部”。

有帮助吗?