++ contour: k8s-secret sink k8s|vault — same resolved data routes to kubernetes_secret or vault_kv_secret_v2 (path <prefix>/<name>)

This commit is contained in:
Kochetkov S 2026-07-16 16:24:57 +03:00
parent b299ba21be
commit f6786a199f
2 changed files with 41 additions and 2 deletions

View File

@ -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 <prefix>/<name>).
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]
}

View File

@ -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 <vault_path_prefix>/<name>
}))
}
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({