add support for additive IAM roles to KMS (#417)

This commit is contained in:
Ludovico Magnocavallo 2022-01-10 16:35:02 +01:00 committed by GitHub
parent ea17e65652
commit 4b500c2366
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 75 additions and 7 deletions

View File

@ -17,7 +17,7 @@ module "kms" {
source = "./modules/kms"
project_id = "my-project"
iam = {
"roles/owner" = ["user:user1@example.com"]
"roles/cloudkms.admin" = ["user:user1@example.com"]
}
keyring = { location = "europe-west1", name = "test" }
keyring_create = false
@ -32,9 +32,21 @@ module "kms" {
module "kms" {
source = "./modules/kms"
project_id = "my-project"
iam_additive = {
"roles/cloudkms.cryptoKeyEncrypterDecrypter" = [
"user:user1@example.com", "user:user2@example.com"
]
}
key_iam = {
key-a = {
"roles/owner" = ["user:user1@example.com"]
"roles/cloudkms.admin" = ["user:user3@example.com"]
}
}
key_iam_additive = {
key-b = {
"roles/cloudkms.cryptoKeyEncrypterDecrypter" = [
"user:user4@example.com", "user:user5@example.com"
]
}
}
keyring = { location = "europe-west1", name = "test" }
@ -44,7 +56,7 @@ module "kms" {
key-c = { rotation_period = null, labels = { env = "test" } }
}
}
# tftest:modules=1:resources=5
# tftest:modules=1:resources=9
```
### Crypto key purpose
@ -77,8 +89,10 @@ module "kms" {
|---|---|:---:|:---:|:---:|
| keyring | Keyring attributes. | <code title="object&#40;&#123;&#10; location &#61; string&#10; name &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | |
| project_id | Project id where the keyring will be created. | <code>string</code> | ✓ | |
| iam | Keyring IAM bindings for topic in {ROLE => [MEMBERS]} format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| key_iam | Key IAM bindings for topic in {KEY => {ROLE => [MEMBERS]}} format. | <code>map&#40;map&#40;list&#40;string&#41;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| iam | Keyring IAM bindings in {ROLE => [MEMBERS]} format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| iam_additive | Keyring IAM additive bindings in {ROLE => [MEMBERS]} format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| key_iam | Key IAM bindings in {KEY => {ROLE => [MEMBERS]}} format. | <code>map&#40;map&#40;list&#40;string&#41;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| key_iam_additive | Key IAM additive bindings in {ROLE => [MEMBERS]} format. | <code>map&#40;map&#40;list&#40;string&#41;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| key_purpose | Per-key purpose, if not set defaults will be used. If purpose is not `ENCRYPT_DECRYPT` (the default), `version_template.algorithm` is required. | <code title="map&#40;object&#40;&#123;&#10; purpose &#61; string&#10; version_template &#61; object&#40;&#123;&#10; algorithm &#61; string&#10; protection_level &#61; string&#10; &#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| key_purpose_defaults | Defaults used for key purpose when not defined at the key level. If purpose is not `ENCRYPT_DECRYPT` (the default), `version_template.algorithm` is required. | <code title="object&#40;&#123;&#10; purpose &#61; string&#10; version_template &#61; object&#40;&#123;&#10; algorithm &#61; string&#10; protection_level &#61; string&#10; &#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; purpose &#61; null&#10; version_template &#61; null&#10;&#125;">&#123;&#8230;&#125;</code> |
| keyring_create | Set to false to manage keys and IAM bindings in an existing keyring. | <code>bool</code> | | <code>true</code> |
@ -97,3 +111,6 @@ module "kms" {
<!-- END TFDOC -->

View File

@ -15,6 +15,25 @@
*/
locals {
iam_additive_members = flatten([
for role, members in var.iam_additive : [
for member in members : {
member = member
role = role
}
]
])
key_iam_additive_members = flatten([
for key, roles in var.key_iam_additive : [
for role, members in roles : [
for member in members : {
key = key
member = member
role = role
}
]
]
])
key_iam_members = flatten([
for key, roles in var.key_iam : [
for role, members in roles : {
@ -57,6 +76,16 @@ resource "google_kms_key_ring_iam_binding" "default" {
members = each.value
}
resource "google_kms_key_ring_iam_member" "default" {
for_each = {
for binding in local.iam_additive_members :
"${binding.role}${binding.member}" => binding
}
key_ring_id = local.keyring.id
role = each.value.role
member = each.value.member
}
resource "google_kms_crypto_key" "default" {
for_each = var.keys
key_ring = local.keyring.id
@ -82,3 +111,13 @@ resource "google_kms_crypto_key_iam_binding" "default" {
crypto_key_id = google_kms_crypto_key.default[each.value.key].id
members = each.value.members
}
resource "google_kms_crypto_key_iam_member" "default" {
for_each = {
for binding in local.key_iam_additive_members :
"${binding.key}.${binding.role}${binding.member}" => binding
}
role = each.value.role
crypto_key_id = google_kms_crypto_key.default[each.value.key].id
member = each.value.member
}

View File

@ -15,13 +15,25 @@
*/
variable "iam" {
description = "Keyring IAM bindings for topic in {ROLE => [MEMBERS]} format."
description = "Keyring IAM bindings in {ROLE => [MEMBERS]} format."
type = map(list(string))
default = {}
}
variable "iam_additive" {
description = "Keyring IAM additive bindings in {ROLE => [MEMBERS]} format."
type = map(list(string))
default = {}
}
variable "key_iam" {
description = "Key IAM bindings for topic in {KEY => {ROLE => [MEMBERS]}} format."
description = "Key IAM bindings in {KEY => {ROLE => [MEMBERS]}} format."
type = map(map(list(string)))
default = {}
}
variable "key_iam_additive" {
description = "Key IAM additive bindings in {ROLE => [MEMBERS]} format."
type = map(map(list(string)))
default = {}
}