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

使用Terraform创建带Google KMS密钥的GCE实例遇权限错误

解决Google Compute实例使用KMS客户管理密钥的权限拒绝问题

问题核心

你遇到的错误如下:

Error: Error creating instance: googleapi: Error 400: Cloud KMS error when using key projects/formal-wonder-394711/locations/europe-west2/keyRings/my-key-ridha/cryptoKeys/my-crypto-key: Permission 'cloudkms.cryptoKeyVersions.useToEncrypt' denied on resource 'projects/formal-wonder-394711/locations/europe-west2/keyRings/my-key-ridha/cryptoKeys/my-crypto-key' (or it may not exist)., kmsPermissionDenied

中文翻译:

错误:创建实例失败:googleapi: 错误400:使用密钥 projects/formal-wonder-394711/locations/europe-west2/keyRings/my-key-ridha/cryptoKeys/my-crypto-key 时触发Cloud KMS错误:资源 'projects/formal-wonder-394711/locations/europe-west2/keyRings/my-key-ridha/cryptoKeys/my-crypto-key' 上的权限 'cloudkms.cryptoKeyVersions.useToEncrypt' 被拒绝(或资源不存在)。, kmsPermissionDenied

问题根源是:调用KMS加密磁盘的主体不是Terraform服务账号,而是Google Compute Engine的默认服务账号。创建带加密磁盘的VM时,是Compute Engine服务代表VM关联的服务账号发起KMS加密请求,而非Terraform执行账号。

修复方案

1. 修正KMS IAM绑定资源

将现有的IAM绑定替换为针对Compute Engine默认服务账号的权限配置,使用最小权限角色roles/cloudkms.cryptoKeyEncrypter:

resource "google_kms_crypto_key_iam_binding" "compute-kms-binding" {
  crypto_key_id = google_kms_crypto_key.my-crypto-key.id
  role          = "roles/cloudkms.cryptoKeyEncrypter"
  members = [
    # 替换为你的项目编号,格式:serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com
    "serviceAccount:123456789012-compute@developer.gserviceaccount.com"
  ]
  depends_on = [google_kms_crypto_key.my-crypto-key]
}

项目编号可通过命令获取:gcloud projects describe formal-wonder-394711 --format="value(projectNumber)"

2. 调整VM实例的依赖顺序

确保VM实例在KMS权限绑定完成后再创建,避免时序问题:

resource "google_compute_instance" "myvm" {
  name         = "my-test-vm"
  machine_type = "e2-small"
  zone         = "europe-west2-a"
  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-11"
    }
    kms_key_self_link = google_kms_crypto_key.my-crypto-key.id
  }
  network_interface {
    network    = google_compute_network.vpc2.id
    subnetwork = google_compute_subnetwork.network-subnet2.id
  }
  depends_on = [
    google_compute_network.vpc2,
    google_compute_subnetwork.network-subnet2,
    google_kms_crypto_key_iam_binding.compute-kms-binding # 添加此依赖
  ]
}

3. 可选:优化Terraform服务账号权限

如果Terraform需要管理KMS密钥,保留原绑定但使用更贴合的角色(避免过度授权):

resource "google_kms_crypto_key_iam_binding" "terraform-kms-binding" {
  crypto_key_id = google_kms_crypto_key.my-crypto-key.id
  role          = "roles/cloudkms.editor"
  members = [
    "serviceAccount:terraform-service@formal-wonder-394711.iam.gserviceaccount.com"
  ]
  depends_on = [google_kms_crypto_key.my-crypto-key]
}

关键注意事项

  • 权限主体区分:Terraform服务账号负责资源创建,磁盘加密操作由Compute Engine服务发起,使用的是项目默认Compute服务账号。
  • 最小权限原则:优先使用roles/cloudkms.cryptoKeyEncrypter这类细粒度角色,避免roles/cloudkms.admin等高权限角色带来的安全风险。

内容的提问来源于stack exchange,提问作者Rizwan Khan A

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 04:16:33