From 5bc6057dc675d146d9b7a5b23199892b677c262d Mon Sep 17 00:00:00 2001 From: Scott McDonald Date: Fri, 28 Aug 2026 17:44:06 +0000 Subject: [PATCH] fix(3-security): apply kms_protection_level to keys that set no version_template core-prod.tf and core-dev.tf passed kms_protection_level to modules/kms inside the keyring object, but that module's keyring variable is object({location, name}); Terraform drops the extra attribute silently, so every key in kms_keys that did not carry its own version_template was created at Cloud KMS's default protection level (SOFTWARE) regardless of kms_protection_level. Apply the stage-wide protection level per key instead: keys without an explicit version_template now get GOOGLE_SYMMETRIC_ENCRYPTION at var.kms_protection_level, keys with one keep it, and a null kms_protection_level leaves the module default untouched. Signed-off-by: Scott McDonald --- fast/stages-aw/3-security/core-dev.tf | 4 ---- fast/stages-aw/3-security/core-prod.tf | 4 ---- fast/stages-aw/3-security/main.tf | 17 ++++++++++++++++- fast/stages-aw/3-security/variables.tf | 2 +- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/fast/stages-aw/3-security/core-dev.tf b/fast/stages-aw/3-security/core-dev.tf index 0a34b6eb2..b8fdfd99f 100644 --- a/fast/stages-aw/3-security/core-dev.tf +++ b/fast/stages-aw/3-security/core-dev.tf @@ -54,10 +54,6 @@ module "dev-sec-kms" { keyring = { location = each.key name = "dev-${each.key}" - version_template = { - algorithm = "GOOGLE_SYMMETRIC_ENCRYPTION" - protection_level = var.kms_protection_level - } } keys = local.kms_locations_keys[each.key] } diff --git a/fast/stages-aw/3-security/core-prod.tf b/fast/stages-aw/3-security/core-prod.tf index 318525eb2..9e7a55041 100644 --- a/fast/stages-aw/3-security/core-prod.tf +++ b/fast/stages-aw/3-security/core-prod.tf @@ -53,10 +53,6 @@ module "prod-sec-kms" { keyring = { location = each.key name = "prod-${each.key}" - version_template = { - algorithm = "GOOGLE_SYMMETRIC_ENCRYPTION" - protection_level = var.kms_protection_level - } } keys = local.kms_locations_keys[each.key] } diff --git a/fast/stages-aw/3-security/main.tf b/fast/stages-aw/3-security/main.tf index a72bd7b78..88365d6b6 100644 --- a/fast/stages-aw/3-security/main.tf +++ b/fast/stages-aw/3-security/main.tf @@ -39,11 +39,26 @@ locals { for k, v in var.kms_keys : v.locations ])) # map { location -> { key_name -> key_details } } + # Keys that do not set their own version_template inherit the stage-wide + # protection level here. modules/kms only honours version_template per key + # (its keyring object is {location, name}), so this is the only place the + # stage can apply var.kms_protection_level. kms_locations_keys = { for loc in local.kms_locations : loc => { for k, v in var.kms_keys : - k => v + k => merge(v, { + version_template = ( + v.version_template != null + ? v.version_template + : var.kms_protection_level == null + ? null + : { + algorithm = "GOOGLE_SYMMETRIC_ENCRYPTION" + protection_level = var.kms_protection_level + } + ) + }) if contains(v.locations, loc) } } diff --git a/fast/stages-aw/3-security/variables.tf b/fast/stages-aw/3-security/variables.tf index 7206afa28..afb3bf412 100644 --- a/fast/stages-aw/3-security/variables.tf +++ b/fast/stages-aw/3-security/variables.tf @@ -111,7 +111,7 @@ variable "kms_keys" { } variable "kms_protection_level" { - description = "KMS protection level." + description = "Protection level (HSM or SOFTWARE) applied to every key in kms_keys that does not set its own version_template." type = string nullable = true }