diff --git a/modules/k8s-secret/main.tf b/modules/k8s-secret/main.tf index 9f2378b..489c611 100644 --- a/modules/k8s-secret/main.tf +++ b/modules/k8s-secret/main.tf @@ -288,17 +288,26 @@ locals { labels = try(secret.labels, {}) annotations = try(secret.annotations, {}) ignore_changes = try(secret.ignore_changes, false) + sink = try(secret.sink, "k8s") + vault_path = try(secret.vault_path, "") != "" ? secret.vault_path : "${var.vault_path_prefix}/${secret.name}" data = try(local.secrets_data[name], {}) } } + # k8s-sink secrets, split by ignore_changes semantics. secrets_with_ignore = { for name, secret in local.secrets_with_data : name => secret - if secret.ignore_changes + if secret.sink == "k8s" && secret.ignore_changes } secrets_without_ignore = { for name, secret in local.secrets_with_data : name => secret - if !secret.ignore_changes + if secret.sink == "k8s" && !secret.ignore_changes + } + + # vault-sink secrets: same resolved data, written to Vault KV v2 instead. + secrets_vault = { + for name, secret in local.secrets_with_data : name => secret + if secret.sink == "vault" } } @@ -359,3 +368,15 @@ resource "kubernetes_secret" "without_ignore" { depends_on = [random_password.secrets] } + +# Vault-sink: same resolved (plaintext) data map, written to Vault KV v2 instead +# of a Kubernetes Secret. Path = secret.vault_path (default /). +resource "vault_kv_secret_v2" "this" { + for_each = local.secrets_vault + + mount = var.vault_kv_mount + name = each.value.vault_path + data_json = jsonencode(each.value.data) + + depends_on = [random_password.secrets] +} diff --git a/modules/k8s-secret/variables.tf b/modules/k8s-secret/variables.tf index fb9d5e2..d5baa98 100644 --- a/modules/k8s-secret/variables.tf +++ b/modules/k8s-secret/variables.tf @@ -37,9 +37,27 @@ variable "secrets" { labels = optional(map(string), {}) annotations = optional(map(string), {}) ignore_changes = optional(bool, false) + + # Sink: where the resolved secret data lands. "k8s" (default) writes a + # Kubernetes Secret; "vault" writes a Vault KV v2 entry instead. Keys and + # resolution (static/dynamic from module outputs) are identical either way. + sink = optional(string, "k8s") + vault_path = optional(string, "") # KV name relative to mount; default / })) } +variable "vault_kv_mount" { + description = "Vault KV v2 mount for secrets with sink=vault" + type = string + default = "secrets" +} + +variable "vault_path_prefix" { + description = "Default path prefix under the KV mount for sink=vault secrets (used when vault_path is unset)" + type = string + default = "vault" +} + variable "s3_outputs" { description = "Outputs от модуля S3 (default/первый бакет)" type = object({