重部署Bicep时如何保留模板未定义的应用设置?
问题原因
你遇到的配置丢失问题不是Bicep的bug,是ARM部署的默认行为导致的:
- 你当前把
appSettings直接写在Microsoft.Web/sites资源的siteConfig属性块里,部署时这个数组属性会被全量替换,没有出现在数组里的配置项会被直接清空。 - 就算你把部署模式改成增量部署也没用,ARM对数组类型的资源属性默认是全量覆盖逻辑,不会自动做合并。
可行解决方案
方案1:全配置纳管(推荐,符合IaC最佳实践)
不要让基础设施部署、应用发布两个流程同时修改App Service的应用设置,所有配置统一收敛到Bicep模板中管理:
- 原模板里固定的配置(比如
ContainerName、FancyUrl)直接写在模板里 - 应用发布流程新增的API密钥、API地址这类配置,定义为Bicep参数,敏感值存在Azure Key Vault中,Bicep通过Key Vault引用直接拉取,不需要在DevOps流水线里单独调用接口改App Service配置
- 这种方式完全避免配置漂移,线上配置和代码库定义完全一致,排查问题不会出现「配置不知道被谁改了」的情况
方案2:部署时自动合并现有配置(适合暂时没法全量纳管的场景)
如果短期内没法把所有应用配置都迁到Bicep里,可以把appSettings从父资源的siteConfig块里移除,改用单独的config子资源部署,部署前先拉取线上现有配置,和模板定义的固定配置合并后再写入,这样非模板定义的配置就不会被删除。
修改后的main.bicep示例代码如下:
resource appService 'Microsoft.Web/sites@2020-06-01' = { name: webSiteName location: location properties: { serverFarmId: appServicePlan.id siteConfig: { linuxFxVersion: linuxFxVersion // 注意:这里删掉原来的appSettings数组,不要写在父资源里 } } } // 引用当前App Service线上已存在的应用设置 resource existingAppSettings 'Microsoft.Web/sites/config@2020-06-01' existing = { parent: appService name: 'appsettings' } // 定义基础设施层需要固定管控的配置项 var infraManagedSettings = { ContainerName: 'FancyContainer' FancyUrl: 'fancy.api.com' } // 合并配置:线上已有配置优先保留,和固定配置重名的项以模板定义的值为准 resource appSettings 'Microsoft.Web/sites/config@2020-06-01' = { parent: appService name: 'appsettings' properties: union(existingAppSettings.properties, infraManagedSettings) }
该方案注意事项
union函数的参数顺序不能反:后面传入的对象会覆盖前面对象的同key值,所以把模板管控的配置放在第二个参数位置,保证基础设施层的固定配置不会被线上的旧值覆盖- 首次部署也能正常运行:App Service创建时会自动生成一批默认应用设置,
existing关键字的引用不会因为资源不存在报错 - 模板里明确定义的配置项,如果被应用发布流程修改过,下次Bicep部署时会被还原为模板定义的值,这是预期行为
内容的提问来源于stack exchange,提问作者asdpsd
相关产品推荐
相关产品推荐

