如何用Terraform的azapi_update_resource更新Azure Container App单个环境变量
如何用Terraform更新Azure Container App单个环境变量
问题描述
使用Terraform的azapi_update_resource资源更新Azure Container App的环境变量时,执行操作后原有环境变量会被全部删除,仅保留新添加的目标变量。需要实现单个环境变量的更新,或者确认该资源是否无法满足此需求。
示例代码:
terraform { required_providers { azapi = { source = "Azure/azapi" } } } provider "azapi" { } provider "azurerm" { features {} } resource "azurerm_resource_group" "example" { name = "resource_group" location = "East US" } resource "azurerm_log_analytics_workspace" "example" { name = "acctest-01" location = azurerm_resource_group.example.location resource_group_name = azurerm_resource_group.example.name sku = "PerGB2018" retention_in_days = 30 } resource "azurerm_container_app_environment" "example" { name = "Example-Environment" location = azurerm_resource_group.example.location resource_group_name = azurerm_resource_group.example.name log_analytics_workspace_id = azurerm_log_analytics_workspace.example.id } resource "azurerm_container_app" "example" { name = "example-app" container_app_environment_id = azurerm_container_app_environment.example.id resource_group_name = azurerm_resource_group.example.name revision_mode = "Single" template { container { name = "examplecontainerapp" image = "mcr.microsoft.com/azuredocs/containerapps-helloworld:latest" cpu = 0.25 memory = "0.5Gi" env { name = "keyname" value = "keyvalue" } } } } resource "azapi_update_resource" "example" { type = "Microsoft.App/containerApps@2022-10-01" resource_id = azurerm_container_app.example.id body = jsonencode({ properties = { template = { containers = [ { env = [ { name = "testname" value = "testvalue" } ] } ] } } }) }
原因分析
默认情况下,azapi_update_resource使用PUT方法,会将你定义的body内容完全替换到目标资源的对应字段中。示例代码里直接覆盖了template.containers[0].env数组,导致原有环境变量被全部删除。
解决方案
方案1:使用azapi_update_resource的PATCH模式
通过指定method = "PATCH"并使用JSON Patch语法,实现对单个环境变量的添加或更新,而不影响原有变量。
追加新环境变量
修改后的azapi_update_resource配置如下:
resource "azapi_update_resource" "example" { type = "Microsoft.App/containerApps@2022-10-01" resource_id = azurerm_container_app.example.id method = "PATCH" # 指定为PATCH方法 body = jsonencode([ { "op" = "add" "path" = "/properties/template/containers/0/env/-" # "-"表示追加到数组末尾 "value" = { name = "testname" value = "testvalue" } } ]) }
更新已有环境变量
如果要更新已存在的环境变量,可先读取当前资源的配置,合并原有变量与新变量(同名则覆盖):
data "azapi_resource" "container_app" { type = "Microsoft.App/containerApps@2022-10-01" resource_id = azurerm_container_app.example.id } resource "azapi_update_resource" "example" { type = "Microsoft.App/containerApps@2022-10-01" resource_id = azurerm_container_app.example.id method = "PATCH" body = jsonencode({ properties = { template = { containers = [ { env = concat( # 过滤掉要更新的变量 [for e in jsondecode(data.azapi_resource.container_app.output).properties.template.containers[0].env : e if e.name != "testname"], # 添加更新后的变量 [{name = "testname", value = "new-testvalue"}] ) } ] } } }) }
方案2:直接修改azurerm_container_app资源(推荐)
既然已经通过azurerm_container_app管理容器应用,直接在该资源的template.container.env块中添加或修改变量是最符合Terraform声明式管理的方式,无需额外使用azapi_update_resource:
resource "azurerm_container_app" "example" { name = "example-app" container_app_environment_id = azurerm_container_app_environment.example.id resource_group_name = azurerm_resource_group.example.name revision_mode = "Single" template { container { name = "examplecontainerapp" image = "mcr.microsoft.com/azuredocs/containerapps-helloworld:latest" cpu = 0.25 memory = "0.5Gi" env { name = "keyname" value = "keyvalue" } # 添加或修改目标环境变量 env { name = "testname" value = "testvalue" } } } }
这种方式会由Terraform自动管理环境变量集合,不会删除未修改的原有变量,配置更简洁易维护。
内容的提问来源于stack exchange,提问作者Ravi Khambhati
相关产品推荐
相关产品推荐

