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

如何用Terraform在AWS上创建并兼容手动更新的Secrets

解决方案

要实现「初始化带默认值、后续合并手动新增内容且不覆盖」的需求,可以通过 Terraform 的资源生命周期配置、数据源读取与内容合并逻辑结合来实现,核心思路是:先确保 Secret 实体存在并初始化默认值,后续部署时读取现有 Secret 内容,合并手动新增内容与 Terraform 管理的默认值,仅在内容有变化时更新 Secret 版本。

具体实现代码

# 定义Terraform管理的默认Secret键值对
locals {
  default_secret = {
    db_username = "admin"
    db_password = "initial-default-pass"
    api_key     = "dev-api-key-123"
  }
}

# 创建Secrets Manager Secret实体,初始化默认值
resource "aws_secretsmanager_secret" "app_secret" {
  name         = "my-microservice-secret"
  # 首次部署时设置默认值
  secret_string = jsonencode(local.default_secret)

  # 忽略secret_string的后续变化,避免Terraform覆盖手动修改的内容
  lifecycle {
    ignore_changes = [secret_string]
  }
}

# 读取现有Secret的当前版本内容
data "aws_secretsmanager_secret_version" "existing" {
  secret_id = aws_secretsmanager_secret.app_secret.id
}

# 合并现有内容与默认值:
# - 若保留手动修改的Terraform默认键值,用 merge(local.default_secret, local.existing_secret)
# - 若强制同步Terraform默认键值(覆盖手动修改),用 merge(local.existing_secret, local.default_secret)
locals {
  existing_secret = jsondecode(data.aws_secretsmanager_secret_version.existing.secret_string)
  merged_secret   = merge(local.default_secret, local.existing_secret)
}

# 更新Secret版本(仅当合并后内容与现有不同时执行)
resource "aws_secretsmanager_secret_version" "current" {
  secret_id     = aws_secretsmanager_secret.app_secret.id
  secret_string = jsonencode(local.merged_secret)

  lifecycle {
    # 确保新版本创建后再移除旧版本,避免服务中断
    create_before_destroy = true
    # 仅当内容变化时更新版本,减少不必要的版本创建
    precondition {
      condition     = jsonencode(local.merged_secret) != data.aws_secretsmanager_secret_version.existing.secret_string
      error_message = "Secret content unchanged, skipping version update."
    }
  }
}

逻辑说明

  1. 首次部署:

    • 创建 aws_secretsmanager_secret 实体,同时设置默认的 secret_string 值。
    • 数据源读取到刚初始化的默认值,合并后内容与现有一致,因此不会触发 aws_secretsmanager_secret_version 的更新。
  2. 手动修改Secret后:

    • 后续Terraform部署时,数据源会读取包含手动新增/修改内容的Secret。
    • 合并逻辑会保留手动添加的所有键值对:
      • 若使用 merge(local.default_secret, local.existing_secret):手动修改的Terraform默认键值会被保留,不会被Terraform覆盖;新增的默认键会被添加到Secret中。
      • 若使用 merge(local.existing_secret, local.default_secret):Terraform管理的默认键值会强制同步(覆盖手动修改),但手动新增的其他键值仍会保留。
    • 只有当合并后的内容与现有内容不同时,才会创建新的Secret版本,避免无意义的版本迭代。
  3. Terraform默认值更新:

    • 若修改了 local.default_secret 中的值,合并后会更新对应键的值,手动添加的键值不受影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 20:42:09