容器版Azure Function因配置漂移丢失自定义应用设置问题排查
问题结论:确实是Terraform配置漂移导致的
Terraform的核心逻辑是期望状态声明式管理:它会强制远程资源与代码中定义的状态完全一致。你的场景中存在两个关键冲突点:
- App Settings被强制覆盖:
azurerm_function_app的app_settings属性是完全托管的——只要Terraform执行apply(比如定时部署、后续资源变更触发),就会删除所有不在代码里定义的应用设置,也就是你用Ansible添加的WEBSITES_ENABLE_APP_SERVICE_STORAGE、SubscriptionExpiredSchedule等都会被清空。 - CORS设置触发容器回收:Terraform代码中定义了空数组的CORS规则,若Ansible或其他方式修改了CORS配置,Terraform会强制将其改回初始状态,触发
CORSSettingsChanged容器回收,同时连带丢失自定义配置。
老旧Terraform版本(v1.0.4)的状态管理逻辑与新版本一致,该问题属于声明式工具的特性,和版本新旧无关。另外函数加载失败是配置丢失的连锁反应——定时触发器依赖的自定义配置不存在,导致无法正常加载。
解决方案
方案一:统一用Terraform管理所有配置(推荐)
将Ansible中负责的配置全部整合到Terraform代码中,彻底避免多工具管理的冲突:
- 整合应用设置:在
azurerm_function_app的app_settings中添加所有需要的键值对:
resource "azurerm_function_app" "myapp" { # 现有配置... app_settings = { APPINSIGHTS_INSTRUMENTATIONKEY = azurerm_application_insights.myapp.instrumentation_key FUNCTIONS_WORKER_RUNTIME = "dotnet" # 添加Ansible中定义的自定义配置 WEBSITES_ENABLE_APP_SERVICE_STORAGE = "false" SubscriptionExpiredSchedule = "* 30 * * * *" KEY = "VALUE..." } }
- 整合ACR托管身份配置:直接通过Terraform的
site_config属性配置,无需调用AZ CLI:
resource "azurerm_function_app" "myapp" { # 现有配置... site_config { linux_fx_version = "dotnet|6" always_on = true cors { allowed_origins = [] support_credentials = false } # 添加ACR身份验证配置 acr_use_managed_identity_creds = true acr_user_managed_identity_id = azurerm_user_assigned_identity.your_user_identity.id } }
- 整合容器部署配置:直接在Terraform中指定镜像信息,替代Ansible的
az function app config container set命令:
resource "azurerm_function_app" "myapp" { # 现有配置... site_config { # 替换原linux_fx_version为容器镜像地址 linux_fx_version = "DOCKER|${var.docker_registry_host}/${var.image_name}:${var.image_tag}" docker_registry_server_url = var.docker_registry_host } }
方案二:使用Terraform忽略变更规则(临时过渡方案)
如果暂时无法迁移配置,可通过lifecycle规则让Terraform不干预指定属性的变更:
resource "azurerm_function_app" "myapp" { # 现有配置... lifecycle { ignore_changes = [ app_settings, site_config[0].cors, site_config[0].acr_use_managed_identity_creds, site_config[0].acr_user_managed_identity_id, ] } }
⚠️ 注意:该方案会让Terraform失去对这些属性的管理能力,后续代码中修改这些配置不会同步到远程资源,容易引发配置混乱,仅适合短期过渡。
方案三:拆分资源与配置管理(不推荐)
若必须保留Ansible管理应用配置,需:
- 在Terraform代码中删除
app_settings、site_config.cors等由Ansible负责的属性,让Terraform不再托管这些部分。 - 严格控制Terraform的
apply触发逻辑,避免意外运行覆盖配置。
该方式风险极高,容易出现环境配置不一致,仅适合特殊场景。
内容的提问来源于stack exchange,提问作者Jack Lin
相关产品推荐
相关产品推荐

