ARM Template - Deploying function using MSDeploy with zipped code in Azure Storage Blob

941 Views Asked by At

I'm trying to deploy an Azure function for which the zipped contents have been placed in a blob in another subscription and resource group. The function app is deployed, but there's no function under it, and MSDeploy fails with a timeout -

"provisioningOperation": "Create",
  "provisioningState": "Failed",
  "timestamp": "2021-07-23T15:10:45.9602877Z",
  "duration": "PT2H11.3363166S",
  "serviceRequestId": "17787274-8592-465b-a11e-10aada76286e",
  "statusCode": "RequestTimeout",
  "statusMessage": {
    "error": {
      "code": "ResourceDeploymentFailure",
      "message": "The resource provision operation did not complete within the allowed timeout period."
    }
  },
  "targetResource": {
    "id": "/subscriptions/<sub-id>/resourceGroups/rg-7ND96/providers/Microsoft.Web/sites/FnAppubjba74tmczo4/Extensions/MSDeploy",
    "resourceName": "FnAppubjba74tmczo4/MSDeploy",
    "resourceType": "Microsoft.Web/sites/Extensions"

I'm assuming this is happening because MSDeploy is unable to access the zip file in the blob. I haven't provided any explicit access, and I'm unable to figure out how to do that. Below is my ARM template for the function app -

{
      "type": "Microsoft.Web/sites",
      "apiVersion": "2020-06-01",
      "name": "[variables('functionAppName')]",
      "location": "[parameters('location')]",
      "kind": "functionapp",
      "properties": {
        "name": "[variables('functionAppName')]",
        "clientAffinityEnabled": false
      },
      "dependsOn": [
        "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]",
        "[resourceId('Microsoft.Insights/components', variables('appInsightsName'))]"
      ],
      "resources": [
        {
          "apiVersion": "2018-11-01",
          "name": "appsettings",
          "type": "config",
          "dependsOn": [
            "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]",
            "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]",
            "[resourceId('Microsoft.Insights/components', variables('appInsightsName'))]"
          ],
          "properties": {
            "AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';EndpointSuffix=', environment().suffixes.storage, ';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2019-06-01').keys[0].value)]",
            "FUNCTIONS_EXTENSION_VERSION": "~3",
            "FUNCTIONS_WORKER_RUNTIME": "dotnet",
            "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';EndpointSuffix=', environment().suffixes.storage, ';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2019-06-01').keys[0].value)]",
            "FileStorageAccountConnectionString": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';EndpointSuffix=', environment().suffixes.storage, ';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2019-06-01').keys[0].value)]",
            "FileShareName": "[variables('fileShareName')]",
            "APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(resourceId('microsoft.insights/components/', variables('appInsightsName')), '2015-05-01').InstrumentationKey]"
          }
        },
        {
          "name": "MSDeploy",
          "type": "Extensions",
          "apiVersion": "2018-11-01",
          "dependsOn": [
            "[resourceId('Microsoft.Web/Sites', variables('functionAppName'))]"
          ],
          "properties": {
            "packageUri": "https://storage-name.blob.core.windows.net/Function.zip",
            "appOffline": true
          }
        }
      ]
    }

Can I provide the function app access to the blob using managed identity dynamically in the ARM template before the MSDeploy resource runs? If not, can I generate a SAS token in the ARM template for access?

UPADTE - I went to the check the logs in the deployed function app in ..\home\LogFiles\SiteExtensions\MSDeploy - appManagerLog.xml -

<?xml version="1.0" encoding="utf-8"?>
<entries>
    <entry time="2021-07-23T15:13:08.5448175+00:00" type="Message">
        <message>Downloading package path 'Function.zip' from blob 'https://storage-name.blob.core.windows.net'</message>
    </entry>
    <entry time="2021-07-23T15:13:09.0604383+00:00" type="Message">
        <message>No parameters were populated.</message>
    </entry>
    <entry time="2021-07-23T15:13:09.0604383+00:00" type="Message">
        <message>AppOffline enabled</message>
    </entry>
    <entry time="2021-07-23T15:13:09.0604383+00:00" type="Message">
        <message>Calling SyncTo() on package.</message>
    </entry>
    <entry time="2021-07-23T15:13:09.3104411+00:00" type="Message">
        <message>Adding file (.\FunctionApp.csproj).</message>
    </entry>
    <entry time="2021-07-23T15:13:09.3104411+00:00" type="Message">
        <message>Adding file (.\FunctionApp.csproj).</message>
    </entry>
    <entry time="2021-07-23T15:13:09.3729946+00:00" type="Message">
        <message>Deleting file (.\host.json).</message>
    </entry>
    <entry time="2021-07-23T15:13:09.3729946+00:00" type="Message">
        <message>Deleting file (.\host.json).</message>
    </entry>
    <entry time="2021-07-23T15:13:09.4199523+00:00" type="Message">
        <message>Adding file (.\local.settings.json).</message>
    </entry>
    <entry time="2021-07-23T15:13:09.4199523+00:00" type="Message">
        <message>Adding file (.\local.settings.json).</message>
    </entry>
    <entry time="2021-07-23T15:13:09.4823395+00:00" type="Message">
        <message>Adding directory (.\Models).</message>
    </entry>
    <entry time="2021-07-23T15:13:09.4823395+00:00" type="Message">
        <message>Adding directory (.\Models).</message>
    </entry>
    <entry time="2021-07-23T15:13:09.529223+00:00" type="Message">
        <message>Adding file (.\Models\RequestModel.cs).</message>
    </entry>
    <entry time="2021-07-23T15:13:09.529223+00:00" type="Message">
        <message>Adding file (.\Models\RequestModel.cs).</message>
    </entry>
    <entry time="2021-07-23T15:13:09.5917233+00:00" type="Message">
        <message>Adding file (.\Models\State.cs).</message>
    </entry>
    <entry time="2021-07-23T15:13:09.5917233+00:00" type="Message">
        <message>Adding file (.\Models\State.cs).</message>
    </entry>
    <entry time="2021-07-23T15:13:09.654252+00:00" type="Message">
        <message>Adding file (.\Models\StateInfo.cs).</message>
    </entry>
    <entry time="2021-07-23T15:13:09.654252+00:00" type="Message">
        <message>Adding file (.\Models\StateInfo.cs).</message>
    </entry>
    <entry time="2021-07-23T15:13:09.716655+00:00" type="Message">
        <message>Adding file (.\ResponseFunction.cs).</message>
    </entry>
    <entry time="2021-07-23T15:13:09.716655+00:00" type="Message">
        <message>Adding file (.\ResponseFunction.cs).</message>
    </entry>
    <entry time="2021-07-23T15:13:09.8729031+00:00" type="Message">
        <message>Total Changes: 8 (7 added, 1 deleted, 0 updated, 0 parameters changed, 7989 bytes copied)</message>
    </entry>
    <entry time="2021-07-23T15:13:09.8729031+00:00" type="Message">
        <message>[Information] [user: F8C3B4564BD880EEFBE19EBA84667977B183FC6B] [324886c5-3416-4866-b8b4-5c3a2ed83394] WebDeploy operation complete. Performing post-deployment operations.</message>
    </entry>
    <entry time="2021-07-23T15:13:10.6130904+00:00" type="Message">
        <message>[Verbose] [user: F8C3B4564BD880EEFBE19EBA84667977B183FC6B] Begin HttpPost https://adobefnappubjba74tmczo4.azurewebsites.net/admin/host/synctriggers, x-ms-request-id: 324886c5-3416-4866-b8b4-5c3a2ed83394</message>
    </entry>
    <entry time="2021-07-23T15:16:47.9939772+00:00" type="Message">
        <message>Downloading package path 'Function.zip' from blob 'https://storage-name.blob.core.windows.net'</message>
    </entry>
    <entry time="2021-07-23T15:16:48.0721032+00:00" type="Message">
        <message>No parameters were populated.</message>
    </entry>
    <entry time="2021-07-23T15:16:48.0721032+00:00" type="Message">
        <message>AppOffline enabled</message>
    </entry>
    <entry time="2021-07-23T15:16:48.0721032+00:00" type="Message">
        <message>Calling SyncTo() on package.</message>
    </entry>
    <entry time="2021-07-23T15:16:48.1502509+00:00" type="Message">
        <message>Deleting file (.\host.json).</message>
    </entry>
    <entry time="2021-07-23T15:16:48.1502509+00:00" type="Message">
        <message>Deleting file (.\host.json).</message>
    </entry>
    <entry time="2021-07-23T15:16:48.2596268+00:00" type="Message">
        <message>Total Changes: 1 (0 added, 1 deleted, 0 updated, 0 parameters changed, 0 bytes copied)</message>
    </entry>
    <entry time="2021-07-23T15:16:48.2596268+00:00" type="Message">
        <message>[Information] [user: F8C3B4564BD880EEFBE19EBA84667977B183FC6B] [ae7d2678-ec79-476b-8e72-e3a4e4cc0d70] WebDeploy operation complete. Performing post-deployment operations.</message>
    </entry>
    <entry time="2021-07-23T15:16:48.3221254+00:00" type="Message">
        <message>[Verbose] [user: F8C3B4564BD880EEFBE19EBA84667977B183FC6B] Begin HttpPost https://adobefnappubjba74tmczo4.azurewebsites.net/admin/host/synctriggers, x-ms-request-id: ae7d2678-ec79-476b-8e72-e3a4e4cc0d70</message>
    </entry>
    <entry time="2021-07-23T15:21:42.6541756Z" type="Message">
        <message>Downloading package path 'Function.zip' from blob 'https://storage-name.blob.core.windows.net'</message>
    </entry>
    <entry time="2021-07-23T15:21:42.7318456Z" type="Message">
        <message>No parameters were populated.</message>
    </entry>
    <entry time="2021-07-23T15:21:42.7318456Z" type="Message">
        <message>AppOffline enabled</message>
    </entry>
    <entry time="2021-07-23T15:21:42.7318456Z" type="Message">
        <message>Calling SyncTo() on package.</message>
    </entry>
    <entry time="2021-07-23T15:21:42.8099044Z" type="Message">
        <message>Deleting file (.\host.json).</message>
    </entry>
    <entry time="2021-07-23T15:21:42.8099044Z" type="Message">
        <message>Deleting file (.\host.json).</message>
    </entry>
    <entry time="2021-07-23T15:21:42.8880416Z" type="Message">
        <message>Total Changes: 1 (0 added, 1 deleted, 0 updated, 0 parameters changed, 0 bytes copied)</message>
    </entry>
    <entry time="2021-07-23T15:21:42.8880416Z" type="Message">
        <message>[Information] [user: F8C3B4564BD880EEFBE19EBA84667977B183FC6B] [6b7c0ba0-8504-4525-9f99-a5e7d787693f] WebDeploy operation complete. Performing post-deployment operations.</message>
    </entry>
    <entry time="2021-07-23T15:21:42.9505549Z" type="Message">
        <message>[Verbose] [user: F8C3B4564BD880EEFBE19EBA84667977B183FC6B] Begin HttpPost https://adobefnappubjba74tmczo4.azurewebsites.net/admin/host/synctriggers, x-ms-request-id: 6b7c0ba0-8504-4525-9f99-a5e7d787693f</message>
    </entry>
</entries>

From the logs it appears that MSDeploy does have access to the blob since all the folders are being read. However, my deployment fails and when I go to the Azure portal to the deployed function app, there are no functions under it. Am I missing something here?

1

There are 1 best solutions below

0
Jean-Nicolas G. On

Your package URI should contain a Shared Access Signature (SAS)

"packageUri": "https://storage-name.blob.core.windows.net/Function.zip?sv=yourSAS",

For that, in Azure Storage Explorer, create a Shared Access Signature (SAS) token for the storage container, and then append the token to the WDP URLs. Make a note of the package URLs for later use in ARM templates.

In your case the wdp is a zip file, same same but different.

A SAS URI looks like this:

https://contoso.blob.core.windows.net/container01?sv=2020-04-08&st=2021-03-02T00%3A30%3A33Z&se=2020-03-03T00%3A30%3A33Z&sr=c&sp=rl&sig=z9VFdWffrV6FXU51T8b8HVfipZPOpYOFLXuQw6wfkFY%3F

In the Select Resource panel of the Connect to Azure Storage dialog, select the resource you want to connect to. Select Shared access signature (SAS) and select Next. Enter a display name for your connection and the SAS URI for the resource. Select Next. Review your connection information in the Summary panel. If the connection information is correct, select Connect.

From microsoft doc