You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Secret Manager数据源的Terraform Cloud SQL资源频繁触发原地更新

问题:Terraform 重复触发 Cloud SQL 授权网络原地更新

我通过 Terraform 从 Google Secret Manager 获取 IP 地址,将其配置为 Cloud SQL 的授权网络,代码如下:

数据源配置(拉取密钥)

data "google_secret_manager_secret_version" "myIp" {
  secret   = "myIp"
  version = 1
}

Cloud SQL 实例配置

resource "google_sql_database_instance" "myCloudSql" {
  database_version = "POSTGRES_14"

  authorized_networks {
    name  = "my IP"
    value = module.myModule.myIp
  }

  # ...更多授权网络配置
}

即使基础设施没有任何实际变更,每次执行 terraform plan 或 terraform apply 时,Terraform 都会尝试对 Cloud SQL 的授权网络执行原地更新,执行输出示例:

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # module.myCloudSql.google_sql_database_instance.myCloudSql will be updated in-place
  ~ resource "google_sql_database_instance" "myCloudSql" {

        # (14 unchanged attributes hidden)

      ~ settings {
            # (11 unchanged attributes hidden)

          ~ ip_configuration {
                # (3 unchanged attributes hidden)

              - authorized_networks {
                  # At least one attribute in this block is (or was) sensitive,
                  # so its contents will not be displayed.
                }

原因分析

  1. 敏感数据掩码导致匹配失败:从 Secret Manager 获取的 IP 会被 Terraform 标记为敏感数据,状态文件中该值会被掩码处理。Terraform 对比本地配置与远程状态时,无法直接验证敏感值的一致性,误判为值已变更。
  2. IP 格式不统一:Google Cloud SQL 服务端返回授权网络配置时,会自动对 IP 做标准化处理(比如为单个 IP 补全 /32 后缀),而本地配置的原始 IP 未做同样处理,导致 Terraform 认为两者不匹配。

解决方案

1. 显式标记敏感值

在模块输出或直接引用敏感值时,使用 sensitive() 函数包裹,确保 Terraform 正确识别敏感数据的一致性:

# 模块输出示例
output "myIp" {
  value = sensitive(data.google_secret_manager_secret_version.myIp.secret_data)
}

或直接在 Cloud SQL 配置中使用:

authorized_networks {
  name  = "my IP"
  value = sensitive(data.google_secret_manager_secret_version.myIp.secret_data)
}

2. 标准化 IP 格式

使用 Terraform 函数统一 IP 格式,匹配服务端的标准化结果:

authorized_networks {
  name  = "my IP"
  value = format("%s/32", data.google_secret_manager_secret_version.myIp.secret_data)
}

3. 忽略授权网络的变更检测(兜底方案)

如果上述方法无效,可通过 lifecycle 块让 Terraform 跳过授权网络的变更对比,但需注意这会掩盖真实的配置变更:

resource "google_sql_database_instance" "myCloudSql" {
  database_version = "POSTGRES_14"

  authorized_networks {
    name  = "my IP"
    value = module.myModule.myIp
  }

  # ...更多授权网络配置

  lifecycle {
    ignore_changes = [settings[0].ip_configuration[0].authorized_networks]
  }
}

内容的提问来源于stack exchange,提问作者CommonSenseCode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 03:16:05