问题描述
我正在使用 terraform 创建一个虚拟机实例和连接到所述实例的网络、计算磁盘、该磁盘的快照以及用于加密数据的 KMS 密钥环和密钥。
我使用自己创建的服务帐户对 GCP 进行身份验证,使用以下块:
credentials = file("gcp-account.json")
该帐户具有以下权限:
然后,在 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
块中做同样的事情,并在 kms_key_self_link
和 boot_disk
中提供 attached_disk
并指定 VM 应使用自定义服务帐户进行请求:
service_account {
email = var.service_account
scopes = []
}
然后,在运行 terraform apply
时,我收到以下错误:
错误:创建实例时出错:googleapi:错误 400:Cloud KMS 错误 使用钥匙时 项目/{项目名称}/locations/{位置}/keyRings/{密钥环名称}/cryptoKeys/{密钥名称}:权限“cloudkms.cryptokeyversions.usetoEncrypt”被拒绝 资源 'projects/{project name}/locations/{location}/keyRings/{key ring name}/cryptoKeys/{key name}:'(或者它可能不存在),kmsPermissionDenied
什么在我授予时得到解决
roles/cloudkms.cryptoKeyEncrypterDecrypter
获得 Compute Engine 服务代理的权限,然后脚本运行得很好。
data "google_iam_policy" "kms_key_encrypt_decrypt" {
binding {
role = "roles/cloudkms.cryptoKeyEncrypterDecrypter"
members = ["serviceAccount:service{{PROJECT_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 服务代理分配了哪些角色,只有一个:
Compute Engine 服务代理
并为我的自定义服务帐户分配了完全相同的角色。
这没有帮助。后来我注意到,问题只发生在 VM 的 boot_disk
中:
boot_disk {
kms_key_self_link = var.kms_key_selflink
initialize_params {
image = var.vm_image
type = var.gce_disk_type
}
}
当我注释掉 kms_key_self_link
块中的 boot_disk
时,其他资源(快照、计算磁盘、附加磁盘)也使用 kms_key_self_link
和自定义服务帐户毫无问题地进行配置。如果我将 kms_key_self_link
参数保留在 boot_disk
中,问题仍然存在,我需要指定默认代理才能解决问题。
有没有办法只使用自定义服务帐户来配置我的所有资源,而无需默认计算引擎服务代理的任何参与,我只是在我的脚本中遗漏了一些东西,或者默认代理是否需要保留对于某些操作?
解决方法
因此,正如通过提供的答案所证明的那样,如果没有 Compute Engine 服务代理的参与,就不可能获得所有资源。它必须具有
roles/cloudkms.cryptoKeyEncrypterDecrypter
授予的角色,与使用的任何其他自定义服务帐户无关。这是我在 Terraform 代码中使用的策略来授予它必要的权限:
data "google_iam_policy" "kms_key_encrypt_decrypt" {
binding {
role = "roles/cloudkms.cryptoKeyEncrypterDecrypter"
members = ["serviceAccount:service{{PROJECT_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
}
感谢大家的回答。