Azure Functions ARM 模板重新部署会删除我发布的函数

Posted

技术标签:

【中文标题】Azure Functions ARM 模板重新部署会删除我发布的函数【英文标题】:Azure Functions ARM template redeployment deletes my published functions 【发布时间】:2019-03-08 11:04:04 【问题描述】:

我有一个使用 Azure DevOps 管道的 ARM 模板部署的 Azure Functions (2.0) 实例。我有另一个通过 zip deploy 将函数应用程序部署到实例的管道。这几乎可以完美运行,但是,如果我将功能基础架构部署为代码,然后部署应用程序,然后将基础架构重新部署为代码,我的功能应用程序将被删除并且所有功能都消失了。我正在使用增量部署,所以我不明白它为什么这样做。关于它为什么会出现这种行为或如何进行故障排除的任何想法?

我在下面复制了我的资源组部署脚本和 ARM 模板。

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 模板

  
  "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】:

您的 ARM 模板存在问题,因为它将应用设置设置为独立于应用创建的操作,使用 Azure 文件时不支持此操作。

请参阅this sample 以获得指导。

【讨论】:

ARM 模板工作正常。它们都是由依赖项管理的***资源,这在使用 copyindex 时会有所帮助。 我可能看起来可以正常工作,但可能会导致 Azure 文件配置不正确,并且可能会被添加然后删除。这会导致部署的内容看似消失。如果您正在部署消费应用程序,则需要按照该示例设置应用程序设置。 谢谢 - 我会深入研究一下。 我花了一晚上的时间对您指定的样本进行重新基线并进行测试。不幸的是,它没有任何区别,行为完全相同。我已经回到 Web Deploy 并且工作正常,它在 IaC 的部署之间持续存在。我认为 RunFromZip 仍处于测试阶段。【参考方案2】:

将此应用设置添加到您的模板:

 "name": "WEBSITE_RUN_FROM_PACKAGE", "value": "1" 

如果存在此设置,则只能从 zip 文件运行函数,并且重新部署没有它的模板将删除此设置的现有值(如果有的话)。

【讨论】:

谢谢,解决了arm deploy过程中app service www被删除的问题,即使app service被设置为resource。【参考方案3】:

所以@curiouscoder 的答案确实有效,但它确实需要不止一个班轮,所以我在这里对其进行扩展。

我在向我的 ARM 模板添加了一些 CORS 来源后遇到了这个问题,当我运行模板时它删除了函数,要修复它,你需要执行以下操作(假设你是一个基于 Windows 的函数应用程序,所以是我的,并且您正在从 Azure DevOps 进行部署):

    将 WEBSITE_RUN_FROM_PACKAGE 设置添加到函数的应用服务设置并将其设置为 1(也可以设置为包所在的 URL,但会对函数应用的冷启动产生负面影响) 现在令人困惑的是,在您的 Azure DevOps 发布管道中将您的部署方法设置为“压缩部署”而不是“从包运行”! 现在重新运行带有更改的 ARM 模板不会删除该站点

函数应用现在将从 zip 文件而不是从部署直接运行到 wwwroot 文件夹,这意味着 wwwroot 文件夹被设为只读。如果您尝试在那里编辑任何内容,您会收到错误:

这种方法的好处是您不能一半部署您的应用程序,并且将其设置为只读意味着您不会在部署后不小心弄乱它。

上述操作不如插槽更改顺利,并且需要重新启动应用程序,因此它需要与暂存应用程序或插槽一起使用,尽管在撰写本文时后者仍处于功能应用程序的预览中。

原始的 github 公告值得一读 here,因为它们比 docs 更详细。

【讨论】:

以上是关于Azure Functions ARM 模板重新部署会删除我发布的函数的主要内容,如果未能解决你的问题,请参考以下文章

Azure SQL Server 备份:需要使用 ARM 模板在 Azure SQL Server 备份中取消注册容器和重新转移数据库

是否可以通过 ARM 模板将分配的 Azure DSC 配置更新到 VM?

markdown ARM模板模式#arm #azure

json ARM模板与copyindex #arm #azure

使用 ARM 模板创建 Azure Databricks 令牌

在 ARM 模板中使用访问密钥检索在 Azure 容器上装载 Azure 文件共享