使用自定义服务帐户在 GCP 中创建 VM 时,KMS 权限出现 400 错误
Posted
技术标签:
【中文标题】使用自定义服务帐户在 GCP 中创建 VM 时,KMS 权限出现 400 错误【英文标题】:400 Error on KMS Permissions when creating a VM in GCP using a custom service account 【发布时间】:2021-09-25 05:29:13 【问题描述】:我正在使用 Terraform 创建一个 VM 实例和连接到所述实例的网络、计算磁盘、该磁盘的快照以及用于加密数据的 KMS 密钥环和密钥。
我使用自己创建的服务帐户向 GCP 进行身份验证,使用以下代码块:
credentials = file("gcp-account.json")
该帐户具有以下权限:
云 KMS 管理员 Cloud KMS CryptoKey 加密器/解密器 计算管理员 计算网络管理员 编辑器然后,在google_compute_snapshot
和google_compute_disk
块中,我提供kms_key_self_link
和服务帐户,以使用新创建的KMS 密钥和我的自定义服务帐户为请求加密数据:
kms_key_self_link = var.kms_key_selflink
kms_key_service_account = var.service_account
我在google_compute_instance
块中做同样的事情,并在boot_disk
和attached_disk
中提供kms_key_self_link
,并指定VM 应该使用自定义服务帐户来处理请求:
service_account
email = var.service_account
scopes = []
然后,在运行terraform apply
时出现以下错误:
错误:创建实例时出错:googleapi:错误 400:Cloud KMS 错误 使用钥匙时 projects/project name/locations/location/keyRings/key ring name/cryptoKeys/key name:权限“cloudkms.cryptoKeyVersions.useToEncrypt”被拒绝 资源 'projects/project name/locations/location/keyRings/key ring name/cryptoKeys/key name:'(或者它可能不存在)。,kmsPermissionDenied
当我授予该权限时会得到解决
角色/cloudkms.cryptoKeyEncrypterDecrypter
Compute Engine Service Agent 的权限,然后脚本就可以正常运行了。
data "google_iam_policy" "kms_key_encrypt_decrypt"
binding
role = "roles/cloudkms.cryptoKeyEncrypterDecrypter"
members = ["serviceAccount:servicePROJECT_NUMBER@computesystem.iam.gserviceaccount.com"]
resource "google_kms_crypto_key_iam_policy" "crypto_key"
crypto_key_id = google_kms_crypto_key.key.id
policy_data = data.google_iam_policy.kms_key_encrypt_decrypt.policy_data
但是,我希望我的所有资源仅使用我的自定义服务帐户来处理请求,而不以任何方式涉及默认的 Compute Engine 服务代理。
我查过了,Compute Engine Service Agent 分配了哪些角色,只有一个:
计算引擎服务代理
并将完全相同的角色分配给我的自定义服务帐户。
这没有帮助。后来我注意到,问题只发生在VM的boot_disk
中:
boot_disk
kms_key_self_link = var.kms_key_selflink
initialize_params
image = var.vm_image
type = var.gce_disk_type
当我注释掉boot_disk
块中的kms_key_self_link
时,其他资源(快照、计算磁盘、附加磁盘)也使用kms_key_self_link
和自定义服务帐户,没有任何问题。如果我将kms_key_self_link
参数留在boot_disk
中,问题仍然存在,我需要指定默认代理才能解决。
有没有办法只使用自定义服务帐户来配置我的所有资源,而无需默认 Compute Engine 服务代理的任何参与,我只是在我的脚本中遗漏了一些东西,或者默认代理是否需要保留一些操作?
【问题讨论】:
根据cloud.google.com/compute/docs/disks/customer-managed-encryption,您需要授予计算引擎 SA 的权限。请注意,这与启动 VM 时的默认计算引擎服务帐户或自定义服务帐户不同。这是控制平面服务帐号。 是的,当我向 Compute Engine 服务代理授予必要的权限时,一切正常。然而,我很好奇是否可以通过将加密器/解密器权限分配给自定义服务帐户并将此自定义帐户与 VM 相关联,在不修改或涉及 CE SA 的情况下启动和运行所有内容。 服务代理帐户由 Google 创建并管理控制平面。示例在您的帐户中为您创建资源。您可以向服务代理添加/删除角色,但不能替换它。 Google 使用服务代理帐户来管理您的资源。在您的情况下,您授权 Google 代表您解密数据以创建实例。 感谢两位的详细解释。 你能解决你的问题吗? 【参考方案1】:因此,通过提供的答案证明,如果没有 Compute Engine 服务代理的参与,就不可能获得预配的所有资源。它必须有
角色/cloudkms.cryptoKeyEncrypterDecrypter
角色授予,无论使用任何其他自定义服务帐户。这是我在 Terraform 代码中用于授予它必要权限的策略:
data "google_iam_policy" "kms_key_encrypt_decrypt"
binding
role = "roles/cloudkms.cryptoKeyEncrypterDecrypter"
members = ["serviceAccount:servicePROJECT_NUMBER@computesystem.iam.gserviceaccount.com"]
resource "google_kms_crypto_key_iam_policy" "crypto_key"
crypto_key_id = google_kms_crypto_key.key.id
policy_data = data.google_iam_policy.kms_key_encrypt_decrypt.policy_data
感谢大家的回答。
【讨论】:
以上是关于使用自定义服务帐户在 GCP 中创建 VM 时,KMS 权限出现 400 错误的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Stackdriver Trace 在 App Engine Standard 中创建自定义 Span?