Azure Functions ARM template redeployment deletes my published functions

拜拜、爱过 提交于 2020-05-29 03:24:38

问题


I have an Azure Functions (2.0) instance deployed by an ARM Template using Azure DevOps pipelines. I have another pipeline that deploys a functions application to the instance through zip deploy. This almost works perfectly, however, if I deploy the functions Infrastructure as Code, then deploy the app and then redeploy the Infrastructure as Code, my functions app is removed and all the functions disappear. I am using the incremental deployment so I cont see why it does this. Any thoughts on why it is behaving like this or how to troubleshoot?

I have copied my resource group deployment script and ARM template below.

New-AzureRmResourceGroupDeployment -Name ((Get-ChildItem $TemplateFile).BaseName + '-' + ((Get-Date).ToUniversalTime()).ToString('MMdd-HHmm')) `
                                   -ResourceGroupName $ResourceGroupName `
                                   -TemplateFile $TemplateFile `
                                   -TemplateParameterFile $TemplateParametersFile `
                                   -Mode Incremental `
                                   @OptionalParameters `
                                   -Force -Verbose `
                                   -AdminsGroup $AdminsGroup `
                                   -AdminsGroupObjectId $AdminsGroupObjectId `
                                   -ErrorVariable ErrorMessages

ARM template

  {
  "type": "Microsoft.Web/serverfarms",
  "sku": {
    "name": "Y1",
    "tier": "Dynamic",
    "size": "Y1",
    "family": "Y",
    "capacity": 0
  },
  "kind": "app",
  "apiVersion": "2016-09-01",
  "name": "[variables('FunctionPlanNameMyStuff')]",
  "location": "[resourceGroup().location]",

  "properties": {
    "name": "[variables('FunctionPlanNameMyStuff')]",
    "perSiteScaling": false,
    "reserved": false,
    "targetWorkerCount": 0,
    "targetWorkerSizeId": 0
  }
},
{
  "comments": "MyStuff Functions Site",
  "type": "Microsoft.Web/sites",
  "kind": "functionapp",
  "name": "[variables('FunctionSiteNameMyStuff')]",
  "apiVersion": "2016-08-01",
  "location": "[resourceGroup().location]",
  "identity": {
    "type": "SystemAssigned"
  },
  "scale": null,
  "properties": {
    "enabled": true,
    "hostNameSslStates": [
      {
        "name": "[concat(variables('FunctionSiteNameMyStuff'),'.azurewebsites.net')]",
        "sslState": "Disabled",
        "virtualIP": null,
        "thumbprint": null,
        "toUpdate": null,
        "hostType": "Standard"
      },
      {
        "name": "[concat(variables('FunctionSiteNameMyStuff'),'.scm.azurewebsites.net')]",
        "sslState": "Disabled",
        "virtualIP": null,
        "thumbprint": null,
        "toUpdate": null,
        "hostType": "Repository"
      }
    ],
    "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('FunctionPlanNameMyStuff'))]",
    "reserved": false,
    "siteConfig": null,
    "scmSiteAlsoStopped": false,
    "hostingEnvironmentProfile": null,
    "clientAffinityEnabled": false,
    "clientCertEnabled": false,
    "hostNamesDisabled": false,
    "containerSize": 1536,
    "dailyMemoryTimeQuota": 0,
    "cloningInfo": null
  },
  "resources": [
    {
      "apiVersion": "2015-08-01",
      "name": "appsettings",
      "type": "config",
      "dependsOn": [
        "[resourceId('Microsoft.Web/Sites', variables('FunctionSiteNameMyStuff'))]",
        "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionStorageAccountMyStuff'))]"
      ],
      "properties": {
        "AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('FunctionStorageAccountMyStuff'), ';AccountKey=', listKeys(variables('FunctionStorageResourceIdMyStuff'), '2017-10-01').keys[0].value)]",
        "AzureWebJobsDashboard": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('FunctionStorageAccountMyStuff'), ';AccountKey=', listKeys(variables('FunctionStorageResourceIdMyStuff'), '2017-10-01').keys[0].value)]",
        "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('FunctionStorageAccountMyStuff'), ';AccountKey=', listKeys(variables('FunctionStorageResourceIdMyStuff'),'2015-05-01-preview').key1)]",
        "WEBSITE_CONTENTSHARE": "[toLower(variables('FunctionSiteNameMyStuff'))]",
        "FUNCTIONS_EXTENSION_VERSION": "~2",
        "FUNCTIONS_WORKER_RUNTIME": "dotnet",
        "FUNCTION_APP_EDIT_MODE": "readwrite",
        "KeyVaultUrl": "[concat('https://', variables('KeyVaultName'), '.vault.azure.net/')]",
        "DeveloperMode": false
      }
    }
  ],
  "dependsOn": [
    "[resourceId('Microsoft.Web/serverfarms', variables('FunctionPlanNameMyStuff'))]",
    "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionStorageAccountMyStuff'))]"
  ]
},
{
  "comments": "Functions web site config",
  "type": "Microsoft.Web/sites/config",
  "name": "[concat(variables('FunctionSiteNameMyStuff'), '/', 'web')]",
  "apiVersion": "2016-08-01",
  "location": "[resourceGroup().location]",
  "tags": {
  },
  "scale": null,
  "properties": {
    "numberOfWorkers": 1,
    "defaultDocuments": [
      "Default.htm",
      "Default.html",
      "Default.asp",
      "index.htm",
      "index.html",
      "iisstart.htm",
      "default.aspx",
      "index.php",
      "hostingstart.html"
    ],
    "netFrameworkVersion": "v4.0",
    "phpVersion": "5.6",
    "pythonVersion": "",
    "nodeVersion": "",
    "linuxFxVersion": "",
    "requestTracingEnabled": false,
    "remoteDebuggingEnabled": false,
    "remoteDebuggingVersion": null,
    "httpLoggingEnabled": false,
    "logsDirectorySizeLimit": 35,
    "detailedErrorLoggingEnabled": false,
    "publishingUsername": "[concat('$', variables('FunctionSiteNameMyStuff'), 'pubuser')]",
    "publishingPassword": "[concat(variables('FnAppPublishingPasswordMyStuff'), uniqueString(resourceGroup().id))]",
    "appSettings": null,
    "metadata": null,
    "connectionStrings": null,
    "machineKey": null,
    "handlerMappings": null,
    "documentRoot": null,
    "scmType": "None",
    "use32BitWorkerProcess": true,
    "webSocketsEnabled": false,
    "alwaysOn": false,
    "javaVersion": null,
    "javaContainer": null,
    "javaContainerVersion": null,
    "appCommandLine": "",
    "managedPipelineMode": "Integrated",
    "virtualApplications": [
      {
        "virtualPath": "/",
        "physicalPath": "site\\wwwroot",
        "preloadEnabled": false,
        "virtualDirectories": null
      }
    ],
    "winAuthAdminState": 0,
    "winAuthTenantState": 0,
    "customAppPoolIdentityAdminState": false,
    "customAppPoolIdentityTenantState": false,
    "runtimeADUser": null,
    "runtimeADUserPassword": null,
    "loadBalancing": "LeastRequests",
    "routingRules": [],
    "experiments": {
      "rampUpRules": []
    },
    "limits": null,
    "autoHealEnabled": false,
    "autoHealRules": null,
    "tracingOptions": null,
    "vnetName": "",
    "siteAuthEnabled": false,
    "siteAuthSettings": {
      "enabled": null,
      "unauthenticatedClientAction": null,
      "tokenStoreEnabled": null,
      "allowedExternalRedirectUrls": null,
      "defaultProvider": null,
      "clientId": null,
      "clientSecret": null,
      "issuer": null,
      "allowedAudiences": null,
      "additionalLoginParams": null,
      "isAadAutoProvisioned": false,
      "googleClientId": null,
      "googleClientSecret": null,
      "googleOAuthScopes": null,
      "facebookAppId": null,
      "facebookAppSecret": null,
      "facebookOAuthScopes": null,
      "twitterConsumerKey": null,
      "twitterConsumerSecret": null,
      "microsoftAccountClientId": null,
      "microsoftAccountClientSecret": null,
      "microsoftAccountOAuthScopes": null
    },
    "cors": null,
    "push": null,
    "apiDefinition": {
      "url": "[concat('https://', variables('FunctionPlanNameMyStuff'), '.azurewebsites.net/swagger/docs/v1')]"
    },
    "autoSwapSlotName": null,
    "localMySqlEnabled": false,
    "managedServiceIdentityId": null,
    "ipSecurityRestrictions": null,
    "http20Enabled": false,
    "minTlsVersion": "1.0"
  },
  "dependsOn": [
    "[resourceId('Microsoft.Web/sites', variables('FunctionSiteNameMyStuff'))]"
  ]
},

回答1:


Add this app setting to your template:

{ "name": "WEBSITE_RUN_FROM_PACKAGE", "value": "1" }

Functions can only be run from zip file if this setting is present, and redeploying a template without it will remove existing value for this setting (if there was any).




回答2:


So @curiouscoder's answer does work but it requires more than a one liner really so I'm expanding on it here.

I hit this issue after adding some CORS origins to my ARM template, when I ran the template it removed the functions, to fix it you need to do the following (this assumes a Windows based function app which yours is and so is mine and that you're deploying from Azure DevOps):

  1. Add the WEBSITE_RUN_FROM_PACKAGE setting to your function's app service settings and set it to 1 (can also be set to a URL where the package is but that affects cold start up negatively for function apps)
  2. Now confusingly in your Azure DevOps release pipeline set your deployment method to "zip deploy" and not to "run from package"!
  3. Re-running your ARM template with changes will now not remove the site

The function app will now be running from the zip file rather from a deployment direct to the wwwroot folder, this means the wwwroot folder is made readonly. You'll get errors if you try to edit anything there:

The benefit of this approach is that you can't half deploy your app and having it read only means you can't accidentally mess with it once deployed.

The above does not work as smoothly as a slot change and will require the app to be restarted so it needs to be used in conjunction with a staging app or slots although as of writing the latter are still in preview for function apps.

The original github announcement is worth a read here as they're more detailed that the docs.




回答3:


Your ARM template is problematic because it sets the App Settings as a separate action from the app creation, which is not supported when using Azure Files.

See this sample for guidance.



来源:https://stackoverflow.com/questions/52623262/azure-functions-arm-template-redeployment-deletes-my-published-functions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!