ARM增量部署模式下Azure函数应用配置修改的部署行为问询
问题描述
我通过以下YAML任务创建了包含应用设置和函数的Azure Function App:
- task: AzureResourceManagerTemplateDeployment@3 displayName: 'deploy resources' inputs: azureResourceManagerConnection: azureResourceManagerConnection subscriptionId: subscriptionId resourceGroupName: rg location: location csmFile: template.bicep csmParametersFile: parameters.json deploymentMode: 'Incremental'
现在我修改了应用设置,若以Incremental部署模式运行上述任务,是会重建带有修改后设置的Function App(包含函数),还是仅更新应用设置,函数应用及现有函数保持不变?
我的template.bicep及相关模块内容如下:
var appSettings = [ { name: 'WEBSITE_ADD_SITENAME_BINDINGS_IN_APPHOST_CONFIG' value: 1 } { name: 'WEBSITE_ENABLE_SYNC_UPDATE_SITE' value: 1 } { name: 'SCM_TOUCH_WEBCONFIG_AFTER_DEPLOYMENT' value: 0 } { name: 'APPINSIGHTS_INSTRUMENTATIONKEY' value: reference(resourceId(appInsightsResourceGroup, 'microsoft.insights/components/', appInsightsName), '2015-05-01').InstrumentationKey } { name: 'AzureWebJobsStorage' value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccountName};AccountKey=${listKeys(resourceId(storageAccountResourceGroup, 'Microsoft.Storage/storageAccounts', storageAccountName), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value}' } { name: 'WEBSITE_CONTENTAZUREFILECONNECTIONSTRING' value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccountName};AccountKey=${listKeys(resourceId(storageAccountResourceGroup, 'Microsoft.Storage/storageAccounts', storageAccountName), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value}' } { name: 'FUNCTIONS_WORKER_RUNTIME' value: 'dotnet' } { name: 'FUNCTIONS_EXTENSION_VERSION' value: '~4' } { name: 'WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT' value: maximumElasticWorkerCount } { name: 'appConfigurationEndpoint' value: appConfigurationEndpoint } { name: 'membershipStorageAccountName' value: '@Microsoft.KeyVault(SecretUri=${reference(membershipStorageAccountName, '2019-09-01').secretUriWithVersion})' } { name: 'membershipContainerName' value: '@Microsoft.KeyVault(SecretUri=${reference(membershipContainerName, '2019-09-01').secretUriWithVersion})' } ] var stagingSettings = [ { name: 'WEBSITE_CONTENTSHARE' value: toLower('functionApp-staging') } { name: 'AzureFunctionsJobHost__extensions__durableTask__hubName' value: '${solutionAbbreviation}compute${environmentAbbreviationStaging}' } { name: 'AzureWebJobs.StarterFunction.Disabled' value: 1 } ] var productionSettings = [ { name: 'WEBSITE_CONTENTSHARE' value: toLower('functionApp') } { name: 'AzureFunctionsJobHost__extensions__durableTask__hubName' value: '${solutionAbbreviation}compute${environmentAbbreviation}' } { name: 'AzureWebJobs.StarterFunction.Disabled' value: 0 } ] module functionAppTemplate 'functionApp.bicep' = { name: 'functionAppTemplater' params: { name: '${functionAppName}' kind: functionAppKind location: location servicePlanName: servicePlanName dataKeyVaultName: dataKeyVaultName dataKeyVaultResourceGroup: dataKeyVaultResourceGroup secretSettings: union(appSettings, productionSettings) } dependsOn: [ servicePlanTemplate ] } module functionAppSlotTemplate 'functionAppSlot.bicep' = { name: 'functionAppSlotTemplate' params: { name: '${functionAppName}/staging' kind: functionAppKind location: location servicePlanName: servicePlanName dataKeyVaultName: dataKeyVaultName dataKeyVaultResourceGroup: dataKeyVaultResourceGroup secretSettings: union(appSettings, stagingSettings) } dependsOn: [ functionAppTemplate ] }
functionApp.bicep:
resource functionApp 'Microsoft.Web/sites@2018-02-01' = { name: name location: location kind: kind properties: { serverFarmId: resourceId('Microsoft.Web/serverfarms', servicePlanName) clientAffinityEnabled: false httpsOnly: true siteConfig: { use32BitWorkerProcess : false appSettings: secretSettings } } identity: { type: 'SystemAssigned' } }
functionAppSlot.bicep:
resource functionAppSlot 'Microsoft.Web/sites/slots@2018-11-01' = { name: name kind: kind location: location properties: { clientAffinityEnabled: true enabled: true httpsOnly: true serverFarmId: resourceId('Microsoft.Web/serverfarms', servicePlanName) siteConfig: { use32BitWorkerProcess : false appSettings: secretSettings } } identity: { type: 'SystemAssigned' } }
回答
以Incremental模式运行部署任务时,只会更新应用设置,不会重建Function App,现有函数也会保持不变,原因如下:
增量部署模式的核心逻辑
Incremental模式会对比Azure中已存在的资源与模板定义的资源,仅对存在差异的属性进行更新,不会删除或重建未变更的资源。你的模板中,Function App的核心属性(名称、服务计划关联、位置、身份配置等)均未修改,仅siteConfig.appSettings有变更,因此只会更新这部分设置。函数代码的存储独立性
你的Function App通过WEBSITE_CONTENTSHARE和WEBSITE_CONTENTAZUREFILECONNECTIONSTRING配置使用文件共享存储函数代码,本次部署仅修改应用设置,未触及代码存储相关的配置或资源,因此已部署的函数代码不会被覆盖或删除,会完整保留。Bicep模板的设置更新规则
模板中的Microsoft.Web/sites资源定义仅更新appSettings数组,Azure资源管理器会将模板中的设置与现有设置合并(注意:若模板中移除了某个设置,Incremental模式下该设置会被保留;若要删除设置,需要显式在模板中声明移除)。
内容的提问来源于stack exchange,提问作者user989988

