使用.tfvars时,如何传递HCP Vault值至GCP Secret Manager?
问题原因
.tfvars 是静态变量值文件,仅支持传入字面量,不能引用Terraform的数据源、资源、locals等动态表达式,所以你直接在dev.tfvars里写${data.vault_generic_secret.secrets.data[\"kafka_dev_password\"]}会被判定为无效语法,触发报错。
解决方案
以下是几种无需在tfvars中引用动态资源的可行方案:
方案1:拆分变量类型,在资源逻辑中动态取值
调整变量结构,区分静态连接串和Vault来源的连接串,在main.tf中根据类型自动取值:
- 先定义变量(
variables.tf):
variable "connections" { type = list(object({ name = string type = string # 标识类型:"static" 或 "vault" uri = optional(string) # 静态连接串使用 vault_key = optional(string) # Vault中存储的密钥名 })) }
- 修改
dev.tfvars:
connections = [ { name = "postgres", type = "static", uri = "postgresql://postgres_user:XXXXXXXXXXXX@1.1.1.1:5432/"}, { name = "kafka", type = "vault", vault_key = "kafka_dev_password"} ]
- 调整
main.tf中的密钥版本资源:
resource "google_secret_manager_secret_version" "connections-version" { count = length(var.connections) secret = google_secret_manager_secret.connections[count.index].id secret_data = var.connections[count.index].type == "static" ? var.connections[count.index].uri : data.vault_generic_secret.secrets.data[var.connections[count.index].vault_key] }
方案2:用环境变量传递Vault密钥
先从Vault获取密钥并导出为环境变量,再在tfvars中引用环境变量:
- 终端执行命令获取Vault密钥并导出:
export KAFKA_DEV_PASSWORD=$(vault read -field=kafka_dev_password secrets/terraform/cloudcomposer/kafka/)
- 修改
dev.tfvars:
connections = [ { name = "postgres", uri = "postgresql://postgres_user:XXXXXXXXXXXX@1.1.1.1:5432/"}, { name = "kafka", uri = "postgresql://kafka_user:${env("KAFKA_DEV_PASSWORD")}@kafka-host:9092/"} ]
方案3:拆分静态与动态连接串,在locals中合并
将静态连接串放在tfvars,动态连接串在locals中生成,最后合并后创建密钥:
- 定义静态连接串变量(
variables.tf):
variable "static_connections" { type = list(object({ name = string uri = string })) }
- 修改
dev.tfvars:
static_connections = [ { name = "postgres", uri = "postgresql://postgres_user:XXXXXXXXXXXX@1.1.1.1:5432/"}, ]
- 调整
main.tf:
locals { # 生成Vault来源的连接串 vault_connections = [ { name = "kafka" uri = "postgresql://kafka_user:${data.vault_generic_secret.secrets.data["kafka_dev_password"]}@kafka-host:9092/" } ] # 合并静态和动态连接串 all_connections = concat(var.static_connections, local.vault_connections) } resource "google_secret_manager_secret" "connections" { provider = google-beta count = length(local.all_connections) secret_id = "${var.secret_manager_prefix}-${local.all_connections[count.index].name}" replication { automatic = true } } resource "google_secret_manager_secret_version" "connections-version" { count = length(local.all_connections) secret = google_secret_manager_secret.connections[count.index].id secret_data = local.all_connections[count.index].uri }
内容的提问来源于stack exchange,提问作者MassHysteria
相关产品推荐
相关产品推荐

