Added CMEK for Secret auto managed (#1739)
Allow to specify custom KMS keys for Secret Manager secrets
This commit is contained in:
parent
0f446e89d4
commit
d07f8fd33d
|
@ -19,7 +19,9 @@ module "secret-manager" {
|
||||||
source = "../../../modules/secret-manager"
|
source = "../../../modules/secret-manager"
|
||||||
project_id = var.project_id
|
project_id = var.project_id
|
||||||
secrets = {
|
secrets = {
|
||||||
(local.ad_user_password_secret) = null
|
(local.ad_user_password_secret) = {
|
||||||
|
locations = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
versions = {
|
versions = {
|
||||||
(local.ad_user_password_secret) = {
|
(local.ad_user_password_secret) = {
|
||||||
|
|
|
@ -57,10 +57,12 @@ module "secret-manager" {
|
||||||
project_id = module.project.project_id
|
project_id = module.project.project_id
|
||||||
source = "../../../modules/secret-manager"
|
source = "../../../modules/secret-manager"
|
||||||
secrets = {
|
secrets = {
|
||||||
github-key = [var.region]
|
github-key = {
|
||||||
}
|
locations = [var.region]
|
||||||
encryption_key = {
|
keys = {
|
||||||
"${var.region}" = var.service_encryption_keys.secretmanager
|
"${var.region}" = var.service_encryption_keys.secretmanager
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
iam = {
|
iam = {
|
||||||
github-key = {
|
github-key = {
|
||||||
|
|
|
@ -17,8 +17,10 @@ module "secret-manager" {
|
||||||
source = "./fabric/modules/secret-manager"
|
source = "./fabric/modules/secret-manager"
|
||||||
project_id = "my-project"
|
project_id = "my-project"
|
||||||
secrets = {
|
secrets = {
|
||||||
test-auto = null
|
test-auto = {}
|
||||||
test-manual = ["europe-west1", "europe-west4"]
|
test-manual = {
|
||||||
|
locations = ["europe-west1", "europe-west4"]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# tftest modules=1 resources=2
|
# tftest modules=1 resources=2
|
||||||
|
@ -33,8 +35,10 @@ module "secret-manager" {
|
||||||
source = "./fabric/modules/secret-manager"
|
source = "./fabric/modules/secret-manager"
|
||||||
project_id = "my-project"
|
project_id = "my-project"
|
||||||
secrets = {
|
secrets = {
|
||||||
test-auto = null
|
test-auto = {}
|
||||||
test-manual = ["europe-west1", "europe-west4"]
|
test-manual = {
|
||||||
|
locations = ["europe-west1", "europe-west4"]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
iam = {
|
iam = {
|
||||||
test-auto = {
|
test-auto = {
|
||||||
|
@ -57,8 +61,10 @@ module "secret-manager" {
|
||||||
source = "./fabric/modules/secret-manager"
|
source = "./fabric/modules/secret-manager"
|
||||||
project_id = "my-project"
|
project_id = "my-project"
|
||||||
secrets = {
|
secrets = {
|
||||||
test-auto = null
|
test-auto = {}
|
||||||
test-manual = ["europe-west1", "europe-west4"]
|
test-manual = {
|
||||||
|
locations = ["europe-west1", "europe-west4"]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
versions = {
|
versions = {
|
||||||
test-auto = {
|
test-auto = {
|
||||||
|
@ -75,34 +81,40 @@ module "secret-manager" {
|
||||||
|
|
||||||
### Secret with customer managed encryption key
|
### Secret with customer managed encryption key
|
||||||
|
|
||||||
Secrets will be used if an encryption key is set in the `encryption_key` variable for the secret region.
|
CMEK will be used if an encryption key is set in the `keys` field of `secrets` object for the secret region. For secrets with auto-replication, a global key must be specified.
|
||||||
|
|
||||||
```hcl
|
```hcl
|
||||||
module "secret-manager" {
|
module "secret-manager" {
|
||||||
source = "./fabric/modules/secret-manager"
|
source = "./fabric/modules/secret-manager"
|
||||||
project_id = "my-project"
|
project_id = "my-project"
|
||||||
secrets = {
|
secrets = {
|
||||||
test-encryption = ["europe-west1", "europe-west4"]
|
test-auto = {
|
||||||
}
|
keys = {
|
||||||
encryption_key = {
|
global = "projects/PROJECT_ID/locations/global/keyRings/KEYRING/cryptoKeys/KEY"
|
||||||
europe-west1 = "projects/PROJECT_ID/locations/europe-west1/keyRings/KEYRING/cryptoKeys/KEY"
|
}
|
||||||
europe-west4 = "projects/PROJECT_ID/locations/europe-west4/keyRings/KEYRING/cryptoKeys/KEY"
|
}
|
||||||
|
test-auto-nokeys = {}
|
||||||
|
test-manual = {
|
||||||
|
locations = ["europe-west1", "europe-west4"]
|
||||||
|
keys = {
|
||||||
|
europe-west1 = "projects/PROJECT_ID/locations/europe-west1/keyRings/KEYRING/cryptoKeys/KEY"
|
||||||
|
europe-west4 = "projects/PROJECT_ID/locations/europe-west4/keyRings/KEYRING/cryptoKeys/KEY"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# tftest modules=1 resources=1
|
# tftest modules=1 resources=3
|
||||||
```
|
```
|
||||||
<!-- BEGIN TFDOC -->
|
<!-- BEGIN TFDOC -->
|
||||||
|
|
||||||
## Variables
|
## Variables
|
||||||
|
|
||||||
| name | description | type | required | default |
|
| name | description | type | required | default |
|
||||||
|---|---|:---:|:---:|:---:|
|
|---|---|:---:|:---:|:---:|
|
||||||
| [project_id](variables.tf#L35) | Project id where the keyring will be created. | <code>string</code> | ✓ | |
|
| [project_id](variables.tf#L29) | Project id where the keyring will be created. | <code>string</code> | ✓ | |
|
||||||
| [encryption_key](variables.tf#L17) | Self link of the KMS keys in {LOCATION => KEY} format. A key must be provided for all replica locations. | <code>map(string)</code> | | <code>null</code> |
|
| [iam](variables.tf#L17) | IAM bindings in {SECRET => {ROLE => [MEMBERS]}} format. | <code>map(map(list(string)))</code> | | <code>{}</code> |
|
||||||
| [iam](variables.tf#L23) | IAM bindings in {SECRET => {ROLE => [MEMBERS]}} format. | <code>map(map(list(string)))</code> | | <code>{}</code> |
|
| [labels](variables.tf#L23) | Optional labels for each secret. | <code>map(map(string))</code> | | <code>{}</code> |
|
||||||
| [labels](variables.tf#L29) | Optional labels for each secret. | <code>map(map(string))</code> | | <code>{}</code> |
|
| [secrets](variables.tf#L34) | Map of secrets to manage, their locations and KMS keys in {LOCATION => KEY} format. {GLOBAL => KEY} format enables CMEK for automatic managed secrets. If locations is null, automatic management will be set. | <code title="map(object({ locations = optional(list(string), null) keys = optional(map(string), null) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||||
| [secrets](variables.tf#L40) | Map of secrets to manage and their locations. If locations is null, automatic management will be set. | <code>map(list(string))</code> | | <code>{}</code> |
|
| [versions](variables.tf#L43) | Optional versions to manage for each secret. Version names are only used internally to track individual versions. | <code title="map(map(object({ enabled = bool data = string })))">map(map(object({…})))</code> | | <code>{}</code> |
|
||||||
| [versions](variables.tf#L46) | Optional versions to manage for each secret. Version names are only used internally to track individual versions. | <code title="map(map(object({ enabled = bool data = string })))">map(map(object({…})))</code> | | <code>{}</code> |
|
|
||||||
|
|
||||||
## Outputs
|
## Outputs
|
||||||
|
|
||||||
|
@ -112,7 +124,6 @@ module "secret-manager" {
|
||||||
| [secrets](outputs.tf#L24) | Secret resources. | |
|
| [secrets](outputs.tf#L24) | Secret resources. | |
|
||||||
| [version_ids](outputs.tf#L29) | Version ids keyed by secret name : version name. | |
|
| [version_ids](outputs.tf#L29) | Version ids keyed by secret name : version name. | |
|
||||||
| [versions](outputs.tf#L36) | Secret versions. | ✓ |
|
| [versions](outputs.tf#L36) | Secret versions. | ✓ |
|
||||||
|
|
||||||
<!-- END TFDOC -->
|
<!-- END TFDOC -->
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
|
|
|
@ -42,27 +42,32 @@ resource "google_secret_manager_secret" "default" {
|
||||||
labels = lookup(var.labels, each.key, null)
|
labels = lookup(var.labels, each.key, null)
|
||||||
|
|
||||||
dynamic "replication" {
|
dynamic "replication" {
|
||||||
for_each = each.value == null ? [""] : []
|
for_each = each.value.locations == null ? [""] : []
|
||||||
content {
|
content {
|
||||||
# TODO(jccb): support custom keys inside auto
|
auto {
|
||||||
auto {}
|
dynamic "customer_managed_encryption" {
|
||||||
|
for_each = try(lookup(each.value.keys, "global", null) == null ? [] : [""], [])
|
||||||
|
content {
|
||||||
|
kms_key_name = each.value.keys["global"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamic "replication" {
|
dynamic "replication" {
|
||||||
for_each = each.value == null ? [] : [each.value]
|
for_each = each.value.locations == null ? [] : [""]
|
||||||
iterator = locations
|
|
||||||
content {
|
content {
|
||||||
user_managed {
|
user_managed {
|
||||||
dynamic "replicas" {
|
dynamic "replicas" {
|
||||||
for_each = locations.value
|
for_each = each.value.locations
|
||||||
iterator = location
|
iterator = location
|
||||||
content {
|
content {
|
||||||
location = location.value
|
location = location.value
|
||||||
dynamic "customer_managed_encryption" {
|
dynamic "customer_managed_encryption" {
|
||||||
for_each = try(var.encryption_key[location.value] != null ? [""] : [], [])
|
for_each = try(lookup(each.value.keys, location.value, null) == null ? [] : [""], [])
|
||||||
content {
|
content {
|
||||||
kms_key_name = var.encryption_key[location.value]
|
kms_key_name = each.value.keys[location.value]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* Copyright 2022 Google LLC
|
* Copyright 2023 Google LLC
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -14,12 +14,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
variable "encryption_key" {
|
|
||||||
description = "Self link of the KMS keys in {LOCATION => KEY} format. A key must be provided for all replica locations."
|
|
||||||
type = map(string)
|
|
||||||
default = null
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "iam" {
|
variable "iam" {
|
||||||
description = "IAM bindings in {SECRET => {ROLE => [MEMBERS]}} format."
|
description = "IAM bindings in {SECRET => {ROLE => [MEMBERS]}} format."
|
||||||
type = map(map(list(string)))
|
type = map(map(list(string)))
|
||||||
|
@ -38,9 +32,12 @@ variable "project_id" {
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "secrets" {
|
variable "secrets" {
|
||||||
description = "Map of secrets to manage and their locations. If locations is null, automatic management will be set."
|
description = "Map of secrets to manage, their locations and KMS keys in {LOCATION => KEY} format. {GLOBAL => KEY} format enables CMEK for automatic managed secrets. If locations is null, automatic management will be set."
|
||||||
type = map(list(string))
|
type = map(object({
|
||||||
default = {}
|
locations = optional(list(string), null)
|
||||||
|
keys = optional(map(string), null)
|
||||||
|
}))
|
||||||
|
default = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "versions" {
|
variable "versions" {
|
||||||
|
|
Loading…
Reference in New Issue