ARM 模板中的函数 MSDeploy 和事件网格订阅竞争条件

Function MSDeploy and Event Grid Subscription Race Condition in ARM Template

我正在使用 MSDeploy 扩展部署一个函数,然后使用此函数作为端点部署事件网格订阅。事件网格部署失败并显示消息 -

"details": [
      {
        "code": "Endpoint validation",
        "message": "The attempt to validate the provided azure endpoint resource:/subscriptions/XXXXX/resourceGroups/ResourceGroupName/providers/Microsoft.Web/sites/FunctionAppName/functions/EndpointName failed."
      }
    ]

我相信这是因为事件网格订阅试图在使用 MSDeploy 部署的函数端点启动之前创建并且 运行。 我怎样才能避免这种竞争状况? 注意:再次部署相同的模板可以很好地创建事件网格。

正在使用模板-

 //function app
        {
            "apiVersion": "2018-11-01",
            "type": "Microsoft.Web/sites",
            "name": "[parameters('functionAppName')]",
            "location": "[resourceGroup().location]",
            "kind": "functionapp",
            "dependsOn": [
                "[variables('azureFunction_serverFarmResourceId')]"
            ],
            "properties": {
                "serverFarmId": "[variables('azureFunction_serverFarmResourceId')]",
                "siteConfig": {
                    "appSettings": [
                        {
                        "name": "AzureWebJobsStorage",
                        "value": "[concat('DefaultEndpointsProtocol=https;AccountName=', parameters('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountResourceId'),variables('storageAccountApiVersion')).keys[0].value)]"
                        },
                        {
                        "name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
                        "value": "[concat('DefaultEndpointsProtocol=https;AccountName=', parameters('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountResourceId'),variables('storageAccountApiVersion')).keys[0].value)]"//"[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]"
                        },
                        {
                        "name": "WEBSITE_CONTENTSHARE",
                        "value": "[toLower(parameters('functionAppName'))]"
                        },
                        {
                        "name": "FUNCTIONS_EXTENSION_VERSION",
                        "value": "~3"
                        },
                        {
                        "name": "WEBSITE_NODE_DEFAULT_VERSION",
                        "value": "~10"
                        },
                        {
                        "name": "APPINSIGHTS_INSTRUMENTATIONKEY",
                        "value": "[reference(resourceId('microsoft.insights/components/', parameters('functionApp_applicationInsightsName')), '2015-05-01').InstrumentationKey]"
                        },
                        {
                        "name": "FUNCTIONS_WORKER_RUNTIME",
                        "value": "dotnet"
                        }
                    ]
                }
            },
            "resources": [
                {
                    "apiVersion": "2018-11-01",
                    "name": "MSDeploy",
                    "dependsOn": [
                        "[resourceId('Microsoft.Web/sites', parameters('functionAppName'))]"

                    ],
                    "properties": {
                        "packageUri": "[parameters('functionAppDeployPackageUri')]"
                    },
                    "type": "extensions"
                }
            ]
        },

        //event grid
        {
            "type": "Microsoft.Storage/storageAccounts/providers/eventSubscriptions",
            "name": "[concat(parameters('storageAccountName'), '/Microsoft.EventGrid/', parameters('blobcreate_eventsubscription_name'))]",
            "apiVersion": "2020-04-01-preview",
            "dependsOn": [
                "[concat('Microsoft.Web/sites/', parameters('functionAppName'), '/extensions/MSDeploy')]",
                "[resourceId('Microsoft.Web/sites', parameters('functionAppName'))]",
                "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]"
            ],
            "properties": {
                "destination": {
                    "endpointType": "AzureFunction",
                    "properties": {
                        "resourceId": "[concat(resourceId('Microsoft.Web/sites', parameters('functionAppName')), '/functions/', variables('egressDataProcessorFunctionName'))]"
                    }
                },
                "filter": {
                    "subjectBeginsWith": "[concat('/blobServices/default/containers/', parameters('storageAccounts_mainblob_name'))]",  
                    "subjectEndsWith": ".xml",
                    "includedEventTypes": [
                        "Microsoft.Storage.BlobCreated"
                    ],
                    "advancedFilters": []
                },
                "retryPolicy": {
                    "maxDeliveryAttempts": "[parameters('eventgrid_maxDeliveryAttemps')]",
                    "eventTimeToLiveInMinutes": "[parameters('eventgrid_eventTimeToLiveInMinutes')]"
                },
                "deadLetterDestination": {
                    "endpointType": "StorageBlob",
                    "properties": {
                        "resourceId": "[variables('storageAccountResourceId')]",
                        "blobContainerName": "[parameters('storageAccounts_deadletterblob_name')]"
                    }
                }
            }
        }

一种方法是将您的函数应用部署为 linked template,然后让您的根模板:

  1. 使用函数 url 作为输出部署函数应用程序模板。
  2. 部署依赖于函数应用部署并引用其输出的事件网格订阅。

另一种可能性是将 appsettings 吐到 a childresource 中,这取决于您的 MSDeploy 资源,然后事件网格取决于 appsettings