terraform-contour-mirror/modules/k8s-secret/main.tf
2026-01-28 14:42:12 +03:00

155 lines
4.8 KiB
HCL

locals {
# Маппинг наших типов на Kubernetes типы
k8s_secret_type_map = {
"dockerconfigjson" = "kubernetes.io/dockerconfigjson"
"database" = "Opaque"
"s3" = "Opaque"
"opaque" = "Opaque"
}
secrets_map = {
for idx, secret in var.secrets : secret.name => secret
}
random_keys_flat = merge([
for secret_name, secret in local.secrets_map : {
for key, config in try(secret.random_keys, {}) : "${secret_name}:${key}" => {
secret_name = secret_name
key = key
length = try(config.length, 32)
special = try(config.special, false)
}
}
]...)
database_outputs_by_secret = {
for name, secret in local.secrets_map : name => try(
var.database_outputs_map["${try(secret.dependencies.cluster, "")}:${try(secret.dependencies.db, "")}:${try(secret.dependencies.user, "")}"],
null
)
}
secrets_data = {
for name, secret in local.secrets_map : name =>
secret.secret_type == "dockerconfigjson" ? {
".dockerconfigjson" = jsonencode({
auths = {
"${secret.registry_url}" = {
username = try(var.env_vars.DOCKER_REGISTRY_USERNAME, "")
password = try(var.env_vars.DOCKER_REGISTRY_PASSWORD, "")
auth = base64encode("${try(var.env_vars.DOCKER_REGISTRY_USERNAME, "")}:${try(var.env_vars.DOCKER_REGISTRY_PASSWORD, "")}")
}
}
})
} : secret.secret_type == "s3" ? {
access_key = var.s3_outputs.access_key
secret_key = var.s3_outputs.secret_key
bucket = var.s3_outputs.bucket_name
endpoint = try(var.constants.s3_endpoint, "https://storage.yandexcloud.net")
} : secret.secret_type == "database" && local.database_outputs_by_secret[name] != null ? merge(
# Базовые поля из database outputs
{
host = local.database_outputs_by_secret[name].host
port = try(var.constants.postgres_port, "6432")
database = local.database_outputs_by_secret[name].database_name
username = local.database_outputs_by_secret[name].user_name
password = local.database_outputs_by_secret[name].password
"ca.crt" = try(var.constants.postgres_ca, "")
},
# Кастомные статические поля
try(secret.custom_keys, {}),
# Рандомные поля
{
for key, config in try(secret.random_keys, {}) : key => random_password.secrets["${name}:${key}"].result
}
) : merge(
try(secret.custom_keys, {}),
{
for key, config in try(secret.random_keys, {}) : key => random_password.secrets["${name}:${key}"].result
}
)
}
secrets_with_data = {
for name, secret in local.secrets_map : name => {
name = secret.name
namespace = secret.namespace
secret_type = secret.secret_type
k8s_type = try(local.k8s_secret_type_map[secret.secret_type], "Opaque")
labels = try(secret.labels, {})
annotations = try(secret.annotations, {})
ignore_changes = try(secret.ignore_changes, false)
data = try(local.secrets_data[name], {})
}
}
secrets_with_ignore = {
for name, secret in local.secrets_with_data : name => secret
if secret.ignore_changes
}
secrets_without_ignore = {
for name, secret in local.secrets_with_data : name => secret
if !secret.ignore_changes
}
}
resource "random_password" "secrets" {
for_each = local.random_keys_flat
length = each.value.length
special = each.value.special
upper = true
lower = true
numeric = true
lifecycle {
ignore_changes = all
}
}
resource "kubernetes_secret" "with_ignore" {
for_each = local.secrets_with_ignore
metadata {
name = each.value.name
namespace = each.value.namespace
labels = try(each.value.labels, {})
annotations = try(each.value.annotations, {})
}
type = each.value.k8s_type
data = each.value.data
lifecycle {
# Игнорируем data, type и metadata чтобы не было phantom updates
ignore_changes = [data, type, metadata]
}
depends_on = [random_password.secrets]
}
resource "kubernetes_secret" "without_ignore" {
for_each = local.secrets_without_ignore
metadata {
name = each.value.name
namespace = each.value.namespace
labels = try(each.value.labels, {})
annotations = try(each.value.annotations, {})
}
type = each.value.k8s_type
data = each.value.data
lifecycle {
# type и metadata игнорируем чтобы не было phantom updates
ignore_changes = [type, metadata]
}
depends_on = [random_password.secrets]
}