Terraform集成Google Secret Manager遇错:密钥传递与Cloud Run配置咨询
参考#1
| secret_data = | 错误信息 |
|---|---|
| data.terraform_remote_state.config1.outputs.cr_sa_key_out.value | Error: Unsupported attribute ... Can't access attributes on a primitive-typed value (string). |
| jsonencode() | 空值"" |
| base64encode() | 空值"" |
| data.terraform_remote_state.config1.outputs.cr_sa_key_out | Error: Error creating SecretVersion: googleapi: got HTTP response code 404 with body: <p><b>404.</b> 这是一个错误。<p>请求的URL <code>/v1/cr∂-secret-file:addVersion?alt=json</code> 未在此服务器上找到。 |
| base64encode(same) | 空值"" |
| jsonencode(same) | 空值"" |
| jsonencode(data.terraform_remote_state.config1.outputs.cr_sa_key_out_attr) | 空值"" |
| data.terraform_remote_state.config1.outputs.cr_sa_key_out_attr | Inappropriate value for attribute "secret_data": string required. |
额外错误:base64encode(same) → Invalid value for "str" parameter: string required.
参考#2
状态文件输出片段:
"outputs": { ////...//// "cr_sa_key_out": { "value": "xxxxxlongkeyxxxxx", "type": "string", "sensitive": true } }
服务账号密钥资源片段:
"resources": [ ////...//// "mode": "managed", "type": "google_service_account_key", "name": "cr_key", "provider": "provider[\"registry.terraform.io/hashicorp/google\"]", "instances": [ { "schema_version": 0, "attributes": { "id": "projects/<proj>/serviceAccounts/<sa_name>@<proj>.iam.gserviceaccount.com/keys/<<key_id>>", "keepers": null, "key_algorithm": "KEY_ALG_RSA_2048", "name": "projects/<proj>/serviceAccounts/<sa_name>@<proj>.iam.gserviceaccount.com/keys/<key_id>", "private_key": "xxxxPRIVATE_KEYxxxxxx", "private_key_type": "TYPE_GOOGLE_CREDENTIALS_FILE", "public_key": "xxxxxPUBLIC KEYxxxxx", "public_key_data": null, "public_key_type": "TYPE_X509_PEM_FILE", "service_account_id": "projects/<proj>/serviceAccounts/<sa_name>@<proj>.iam.gserviceaccount.com", "valid_after": "<date>", "valid_before": "<date>" }, "sensitive_attributes": [], "private": "xxxxxx==", "dependencies": [ "google_project_iam_member.sa-accounts-iam", "google_service_account.sa", "random_id.suffix" ] } ] },
参考#3(Main.tf 1)
terraform { required_version = ">= 1.0" backend "gcs" { bucket = "z_tf" } required_providers { google-beta = ">=3.8" google = { version = "~> 4.0.0" } } } # 提供者配置 provider "google" { project = var.project region = var.region } provider "google-beta" { project = var.project region = var.region } ////....//// resource "google_service_account_key" "cr_key" { service_account_id = "projects/${var.project}/serviceAccounts/${var.cr_sa}-${random_id.suffix.hex}@${var.project}.iam.gserviceaccount.com" depends_on = [google_project_iam_member.sa-accounts-iam] key_algorithm = "KEY_ALG_RSA_2048" private_key_type = "TYPE_GOOGLE_CREDENTIALS_FILE" } output "cr_sa_key_out" { value = google_service_account_key.cr_key.private_key sensitive = true } output "cr_sa_key_out_attr" { value = google_service_account_key.cr_key sensitive = true } output "cr_sa_out" { value = google_service_account.sa[var.cr_sa].name sensitive = false }
参考#4(Main.tf 2)(第二个目录)
##<<相同的terraform{}和provider{}配置>>## # 数据/输出配置 data "terraform_remote_state" "config1" { backend = "gcs" config = { bucket = "z_tf" } } resource "google_secret_manager_secret" "cr_secret" { secret_id = "${var.cr_sa}-key-cr-secret-file" replication { automatic = true } } # 用于排查延迟问题的配置 resource "null_resource" "stall_30_seconds" { provisioner "local-exec" { command = <<-EOF sleep 30 EOF } } resource "google_secret_manager_secret_version" "cr_sec_vers" { secret = google_secret_manager_secret.cr_secret.secret_id secret_data = data.terraform_remote_state.config1.outputs.cr_sa_key_out.value depends_on = [null_resource.stall_30_seconds] } ///// ## Cloud Run配置 resource "google_cloud_run_service" "cr_service" { provider = google-beta name = var.cloud_run_service_name location = var.region template { spec { service_account_name = data.terraform_remote_state.config1.outputs.cr_sa_out # google_service_account.sa[var.cr_sa].name containers { image = "ghcr.io/dbt-labs/dbt-bigquery" env { name = google_secret_manager_secret_version.cr_sec_vers.id value_from { secret_key_ref { name = google_secret_manager_secret_version.cr_sec_vers.name key = "latest" #google_secret_manager_secret_version.cr_sec_vers.name } } } } } } traffic { percent = 100 latest_revision = true } }
问题解答
1. 正确传入secret_data到google_secret_manager_secret_version
核心错误有两个,修正后即可解决问题:
- secret_data取值错误:
cr_sa_key_out本身是字符串类型的输出值,不需要加.value,直接使用data.terraform_remote_state.config1.outputs.cr_sa_key_out即可。之前的错误是因为给字符串类型强制添加了.value属性。 - secret字段取值错误:
google_secret_manager_secret_version的secret参数需要传入Secret的完整资源ID(即google_secret_manager_secret.cr_secret.id),而非仅secret_id(名称)。404错误就是因为用名称请求API找不到资源。
修正后的配置:
resource "google_secret_manager_secret_version" "cr_sec_vers" { secret = google_secret_manager_secret.cr_secret.id secret_data = data.terraform_remote_state.config1.outputs.cr_sa_key_out # 无需额外延迟,Terraform会自动处理资源依赖 }
另外,private_key本身就是符合要求的字符串格式(JSON/PEM),不需要用jsonencode或base64encode处理。
2. Cloud Run配置的优化点
当前配置存在3处不合理,修正如下:
- 环境变量名称:
env.name不能设为Secret Version的ID,应改为有意义的名称,比如GOOGLE_APPLICATION_CREDENTIALS_CONTENT。 - secret_key_ref参数:
name应引用Secret的secret_id而非Version的name;key用latest是合理的。 - 服务账号格式:确认
cr_sa_out输出的google_service_account.sa[var.cr_sa].name是服务账号邮箱或完整资源名,若不是则改用email字段。
修正后的Cloud Run配置:
resource "google_cloud_run_service" "cr_service" { provider = google-beta name = var.cloud_run_service_name location = var.region template { spec { service_account_name = data.terraform_remote_state.config1.outputs.cr_sa_out containers { image = "ghcr.io/dbt-labs/dbt-bigquery" env { name = "GOOGLE_APPLICATION_CREDENTIALS_CONTENT" value_from { secret_key_ref { name = google_secret_manager_secret.cr_secret.secret_id key = "latest" } } } } } } traffic { percent = 100 latest_revision = true } }
额外建议:若无需拆分两次apply,可将所有资源放在同一配置中,Terraform会自动处理依赖,避免手动拆分的问题。
内容的提问来源于stack exchange,提问作者juicero
相关产品推荐
相关产品推荐

