From b48c17fc8cc451628f77dca017bbbc46c09814b0 Mon Sep 17 00:00:00 2001 From: pierre geeraert Date: Wed, 14 Oct 2026 00:42:29 +0100 Subject: [PATCH] secret module + make things equal --- applications/module.tf | 85 ++--------- applications/redis.tf | 183 +---------------------- applications/secrets.tf | 137 +---------------- core/module.tf | 14 -- infrastructure/module.tf | 42 ------ infrastructure/redis.tf | 127 +--------------- infrastructure/secrets.tf | 202 +------------------------ modules/redis/main.tf | 113 ++++++++++++++ modules/secrets/main.tf | 304 ++++++++++++++++++++++++++++++++++++++ 9 files changed, 444 insertions(+), 763 deletions(-) create mode 100644 modules/redis/main.tf create mode 100644 modules/secrets/main.tf diff --git a/applications/module.tf b/applications/module.tf index 3fbb2bc..1b9a49d 100644 --- a/applications/module.tf +++ b/applications/module.tf @@ -26,7 +26,7 @@ variable "kubernetes" { name = optional(string) image = string pvc = optional(map(object({ - name = string + name = optional(string) pvc = optional(bool, false) config_map = optional(bool, false) secret = optional(bool, false) @@ -56,6 +56,8 @@ variable "kubernetes" { service_type = optional(string, "ClusterIP") service_name = optional(string) domain_name = optional(list(string)) + legacy_domain = optional(bool, false) + exposed = optional(bool, true) liveness_tcp_socket = optional(number) liveness_http_get = optional(string) liveness_http_get_path = optional(string) @@ -80,77 +82,20 @@ variable "kubernetes" { service_account_name = optional(string) environment_variables = optional(map(string), { name = "value" }) security_context = optional(bool, false) + import_database_secret = optional(object({ + #putting them a non optional as the code doesn't allow optional value + host = string + name = string + password = string + port = string + username = string + })) })) } -variable "database_backup_info" { - type = map(object({ - image = optional(string) - command = optional(string) - })) - description = "based on DB engine, give the docker image and the command used to backup" - default = { - postgres = { - image = "alpine/psql" - command = "pg_dump |gzip -9 > /backup/$(DB_DATABASE_NAME)-DB-$(date +%Y%m%d).sql.gz" - } - mysql = { - image = "mysql" - command = "mysqldump -h $DB_HOST -u $MYSQL_USER -p$MYSQL_ROOT_PASSWORD $MYSQL_DATABASE |gzip -9 > /backup/$(DB_DATABASE_NAME)-DB-$(date +%Y%m%d).sql.gz" - } - sqlserver = { - image = "mcr.microsoft.com/mssql-tools" - command = "/opt/mssql-tools/bin/sqlcmd -S $DB_HOST -U $DB_USERNAME -P $DB_PASSWORD -Q \"BACKUP DATABASE $DB_DATABASE_NAME TO DISK = '/backup/$DB_DATABASE_NAME-$(date +%Y%m%d).bak' WITH COPY_ONLY, CHECKSUM,FORMAT, MEDIANAME = 'SQLServerBackups',NAME = 'Full Backup of SQLTestDB'\";exit" - } - } -} - -locals { - pvc_list = flatten([ - for key, value in var.kubernetes : [ - for index, pvc in value.pvc : { - key = "${coalesce(value.namespace, value.connected_namespace, key)}/${pvc.name}" - index = index - pvc = pvc.pvc - name = pvc.name - pvc_size = pvc.pvc_size - mount_path = pvc.mount_path - storage_class_name = pvc.storage_class_name - annotations_fileType = pvc.annotations_fileType - existing_pvc = pvc.existing_pvc - sub_path = pvc.sub_path - namespace = coalesce(value.namespace, value.connected_namespace, key) - }] if value.enabled == true && value.pvc != null - ]) - - # group duplicates instead of throwing an error - pvc_map_grouped = { - for p in local.pvc_list : - p.key => p... - } - - # keep only one PVC per key (take the first) - pvc_map = { - for k, list in local.pvc_map_grouped : - k => list[0] - } - - pvc_details = values(local.pvc_map) -} - -locals { - env_details = flatten([ - for key, value in var.kubernetes : [ - for index, env in value.environment_variables : { - index = index - name = env - }] if value.enabled == true && value.environment_variables != null - ]) -} -data "kubernetes_all_namespaces" "allns" {} resource "kubernetes_namespace_v1" "automatic" { for_each = { for key, value in var.kubernetes : key => value if value.enabled == true && value.connected_namespace == "" } @@ -163,7 +108,6 @@ resource "kubernetes_namespace_v1" "automatic" { } name = coalesce(each.value.namespace, each.key) } - depends_on = [data.kubernetes_all_namespaces.allns] } locals { @@ -188,10 +132,3 @@ resource "kubernetes_manifest" "manifest" { provider = kubernetes } - - - - - - - diff --git a/applications/redis.tf b/applications/redis.tf index d000990..946fa3b 100644 --- a/applications/redis.tf +++ b/applications/redis.tf @@ -1,182 +1,7 @@ -resource "bitwarden-secrets_secret" "automatic_bitwarden_secret_redis_host" { - for_each = { for key, value in var.kubernetes : key => value if value.redis != null && value.enabled == true } - key = "${each.key}__redis__host" - project_id = "b5fc4c48-e951-442f-97ca-b3e800c143cd" - value = try(each.value.redis.host, "${each.key}-redis-svc.${coalesce(each.value.namespace, each.value.connected_namespace, each.key)}.svc") -} - -resource "bitwarden-secrets_secret" "automatic_bitwarden_secret_redis_port" { - for_each = { for key, value in var.kubernetes : key => value if value.redis != null && value.enabled == true } - key = "${each.key}__redis__port" - project_id = "b5fc4c48-e951-442f-97ca-b3e800c143cd" - value = try(each.value.redis.port, 5432) -} - -## -## Commenting until I use the redis password option -## -#resource "bitwarden-secrets_secret" "automatic_bitwarden_secret_redis_password" { -# for_each = { for key, value in var.kubernetes : key => value if value.redis != null && value.enabled == true } -# key = "${each.key}__redis__password" -# project_id = "b5fc4c48-e951-442f-97ca-b3e800c143cd" -# length = 32 -# special = true -# min_special = 5 -# avoid_ambiguous = true -#} - -resource "bitwarden-secrets_secret" "automatic_bitwarden_secret_redis_REPLICATION_MODE" { - for_each = { for key, value in var.kubernetes : key => value if value.redis != null && value.enabled == true } - key = "${each.key}__redis__REPLICATION_MODE" - project_id = "b5fc4c48-e951-442f-97ca-b3e800c143cd" - value = try(each.value.redis.REPLICATION_MODE, "master") -} - -resource "bitwarden-secrets_secret" "automatic_bitwarden_secret_redis_TLS_ENABLED" { - for_each = { for key, value in var.kubernetes : key => value if value.redis != null && value.enabled == true } - key = "${each.key}__redis__TLS_ENABLED" - project_id = "b5fc4c48-e951-442f-97ca-b3e800c143cd" - value = try(each.value.redis.TLS_ENABLED, "no") -} - -resource "kubernetes_secret_v1" "automatic-redis-secret" { - for_each = { for key, value in var.kubernetes : key => value if value.redis != null && value.enabled == true } - metadata { - name = "${each.key}-redis-terraform" - namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key) - } - - data = { - REDIS_HOSTNAME = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_redis_host[each.key].value}" - REDIS_PORT = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_redis_port[each.key].value}" - REDIS_REPLICATION_MODE = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_redis_REPLICATION_MODE[each.key].value}" - REDIS_TLS_ENABLED = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_redis_TLS_ENABLED[each.key].value}" - } - -} -resource "kubernetes_deployment_v1" "redis-automatic" { - for_each = { for key, value in var.kubernetes : key => value if value.redis != null && value.enabled == true } - - - metadata { - namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key) - name = "${coalesce(each.value.name, each.key)}-redis" - labels = { - app = each.key - deployment_method = "Terraform" - redis = "true" - } - } - - spec { - replicas = each.value.replicas - - selector { - match_labels = { - app = "${each.key}-redis" - } - } - - template { - metadata { - labels = { - app = "${each.key}-redis" - deployment_method = "Terraform" - redis = "true" - } - } - - spec { - container { - image = try(each.value.redis.image, "docker.io/library/redis:7") - name = "${coalesce(each.value.name, each.key)}-redis" - port { - - container_port = 6379 - name = "redis-port" - - } - - volume_mount { - mount_path = "/data" - name = "${each.key}-redis-pvc" - } - - - - - - dynamic "env" { - for_each = each.value.environment != null ? each.value.environment : {} - content { - name = env.key - value = env.value.value != null ? env.value.value : null - dynamic "value_from" { - for_each = env.value.value_from != null ? env.value.value_from : {} - content { - dynamic "secret_key_ref" { - for_each = [1] - content { - name = env.value.value_from.secret_key_ref.name - key = env.value.value_from.secret_key_ref.key - # optional = true - } - } - } - } - - } - } - - - # resources { - # limits = { - # cpu = each.value.requirements.limits-cpu - # memory = each.value.requirements.limits-memory - # } - # requests = { - # cpu = each.value.requirements.requests-cpu - # memory = each.value.requirements.requests-memory - # } - # } - - # dynamic "liveness_probe" { - # for_each = each.value.liveness_tcp_socket != null || each.value.liveness_http_get != null ? [""] : [] - # content { - # dynamic "tcp_socket" { - # for_each = each.value.liveness_tcp_socket != null ? [""] : [] - # content { - # port = each.value.liveness_tcp_socket - # } - # } - - - # dynamic "http_get" { - # for_each = each.value.liveness_http_get != null ? [""] : [] - # content { - # port = each.value.liveness_http_get - # path = coalesce(each.value.liveness_http_get_path, "/") - # } - # } - - # initial_delay_seconds = 3 - # period_seconds = 3 - # } - # } - } - - - volume { - name = "${each.key}-redis-pvc" - persistent_volume_claim { - claim_name = "${each.key}-redis-pvc" - } - } - - } - } - } -} +module "Redis-automatic" { + source = "../modules/redis" + kubernetes_input = var.kubernetes +} \ No newline at end of file diff --git a/applications/secrets.tf b/applications/secrets.tf index 96cd806..5f1997e 100644 --- a/applications/secrets.tf +++ b/applications/secrets.tf @@ -1,133 +1,4 @@ - -data "bitwarden-secrets_secret" "configmap_import" { - for_each = { - for pair in flatten([ - for k, v in var.kubernetes : [ - for id in v.config_map_import : { - map_key = k - secret_id = id - } - ] if v.config_map_import != null && v.enabled == true - ]) : "${pair.map_key}-${pair.secret_id}" => pair.secret_id - } - id = each.value -} - -resource "kubernetes_config_map_v1" "configmap_import" { - for_each = { for key, value in data.bitwarden-secrets_secret.configmap_import : key => value } - metadata { - name = each.value.note - namespace = split("__", each.value.key)[0] - } - data = yamldecode(each.value.value) -} - - -data "bitwarden-secrets_secret" "secret_import" { - for_each = { - for pair in flatten([ - for k, v in var.kubernetes : [ - for id in v.secret_import : { - map_key = k - secret_id = id - } - ] if v.secret_import != null && v.enabled == true - ]) : "${pair.map_key}-${pair.secret_id}" => pair.secret_id - } - id = each.value -} - -resource "kubernetes_secret_v1" "secret_import" { - for_each = { for key, value in data.bitwarden-secrets_secret.secret_import : key => value } - metadata { - name = each.value.note - namespace = split("__", each.value.key)[0] - } - data = yamldecode(each.value.value) -} - - -resource "kubernetes_secret_v1" "automatic-database-secret" { - for_each = { for key, value in var.kubernetes : key => value if value.database != null && value.enabled == true } - metadata { - name = "${each.key}-db-terraform" - namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key) - } - - data = { - DB_DATABASE_NAME = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_name[each.key].value}" - DB_DATABASE = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_name[each.key].value}" - POSTGRES_DB = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_name[each.key].value}" - MYSQL_DATABASE = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_name[each.key].value}" - PGDATABASE = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_name[each.key].value}" - DB_HOST = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_host[each.key].value}" - PGHOST = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_host[each.key].value}" - POSTGRES_HOST = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_host[each.key].value}" - DB_PASSWORD = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_password[each.key].value}" - MYSQL_PASSWORD = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_password[each.key].value}" - MYSQL_ROOT_PASSWORD = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_password[each.key].value}" - POSTGRES_PASSWORD = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_password[each.key].value}" - PGPASSWORD = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_password[each.key].value}" - DB_USERNAME = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_username[each.key].value}" - POSTGRES_USER = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_username[each.key].value}" - MYSQL_USER = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_username[each.key].value}" - PGUSER = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_username[each.key].value}" - DATABASE_URL = "postgresql://${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_username[each.key].value}:${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_password[each.key].value}@${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_host[each.key].value}:${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_port[each.key].value}/${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_name[each.key].value}" - } - -} - -resource "kubernetes_secret_v1" "automatic-database-mapped-secret" { - for_each = { for key, value in var.kubernetes : key => value if value.database != null && value.enabled == true } - metadata { - name = "${each.key}-db-mapped-terraform" - namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key) - } - - data = { - "${try(each.value.database.map_name, "DB_DATABASE_NAME")}" = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_name[each.key].value}" - "${try(each.value.database.map_host, "DB_DATABASE_NAME")}" = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_host[each.key].value}" - "${try(each.value.database.map_password, "DB_DATABASE_NAME")}" = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_password[each.key].value}" - "${try(each.value.database.map_username, "DB_DATABASE_NAME")}" = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_username[each.key].value}" - } -} - - -resource "bitwarden-secrets_secret" "automatic_bitwarden_secret_db_username" { - for_each = { for key, value in var.kubernetes : key => value if value.database != null && value.enabled == true } - key = "${each.key}__db__username" - value = try(each.value.database.username, each.key) - project_id = "b5fc4c48-e951-442f-97ca-b3e800c143cd" -} - -resource "bitwarden-secrets_secret" "automatic_bitwarden_secret_db_password" { - for_each = { for key, value in var.kubernetes : key => value if value.database != null && value.enabled == true } - key = "${each.key}__db__password" - project_id = "b5fc4c48-e951-442f-97ca-b3e800c143cd" - length = 32 - special = true - min_special = 5 - avoid_ambiguous = true -} - -resource "bitwarden-secrets_secret" "automatic_bitwarden_secret_db_host" { - for_each = { for key, value in var.kubernetes : key => value if value.database != null && value.enabled == true } - key = "${each.key}__db__host" - project_id = "b5fc4c48-e951-442f-97ca-b3e800c143cd" - value = try(each.value.database.host, "${each.key}-db-svc.${coalesce(each.value.namespace, each.value.connected_namespace, each.key)}.svc") -} - -resource "bitwarden-secrets_secret" "automatic_bitwarden_secret_db_port" { - for_each = { for key, value in var.kubernetes : key => value if value.database != null && value.enabled == true } - key = "${each.key}__db__port" - project_id = "b5fc4c48-e951-442f-97ca-b3e800c143cd" - value = try(each.value.database.port, 5432) -} - -resource "bitwarden-secrets_secret" "automatic_bitwarden_secret_db_name" { - for_each = { for key, value in var.kubernetes : key => value if value.database != null && value.enabled == true } - key = "${each.key}__db__name" - project_id = "b5fc4c48-e951-442f-97ca-b3e800c143cd" - value = try(each.value.database.name, each.key) -} - +module "Secrets-automatic" { + source = "../modules/secrets" + kubernetes_input = var.kubernetes +} \ No newline at end of file diff --git a/core/module.tf b/core/module.tf index 8bdca05..f641a5e 100644 --- a/core/module.tf +++ b/core/module.tf @@ -93,20 +93,6 @@ variable "storage_path" { } } - -locals { - env_details = flatten([ - for key, value in var.kubernetes : [ - for index, env in value.environment_variables : { - index = index - name = env - }] if value.enabled == true && value.environment_variables != null && value.docker != true - ]) -} - - - - locals { kubernetes_manifests = flatten([ for k, obj in var.kubernetes : [ diff --git a/infrastructure/module.tf b/infrastructure/module.tf index 030dda7..913d819 100644 --- a/infrastructure/module.tf +++ b/infrastructure/module.tf @@ -95,48 +95,6 @@ variable "kubernetes" { } -variable "database_backup_info" { - type = map(object({ - image = optional(string) - command = optional(string) - })) - description = "based on DB engine, give the docker image and the command used to backup" - default = { - postgres = { - image = "alpine/psql" - command = "pg_dump |gzip -9 > /backup/$(DB_DATABASE_NAME)-DB-$(date +%Y%m%d).sql.gz" - } - mysql = { - image = "mysql" - command = "mysqldump -h $DB_HOST -u $MYSQL_USER -p$MYSQL_ROOT_PASSWORD $MYSQL_DATABASE |gzip -9 > /backup/$(DB_DATABASE_NAME)-DB-$(date +%Y%m%d).sql.gz" - } - sqlserver = { - image = "mcr.microsoft.com/mssql-tools" - command = "/opt/mssql-tools/bin/sqlcmd -S $DB_HOST -U $DB_USERNAME -P $DB_PASSWORD -Q \"BACKUP DATABASE $DB_DATABASE_NAME TO DISK = '/backup/$DB_DATABASE_NAME-$(date +%Y%m%d).bak' WITH COPY_ONLY, CHECKSUM,FORMAT, MEDIANAME = 'SQLServerBackups',NAME = 'Full Backup of SQLTestDB'\";exit" - } - } -} - -variable "storage_path" { - type = map(string) - default = { - main_storage = "/data/kubernetes", - fast_access = "/ssd" - } -} - - - -locals { - env_details = flatten([ - for key, value in var.kubernetes : [ - for index, env in value.environment_variables : { - index = index - name = env - }] if value.enabled == true && value.environment_variables != null - ]) -} - resource "kubernetes_namespace_v1" "automatic" { diff --git a/infrastructure/redis.tf b/infrastructure/redis.tf index 267f066..f8e4cce 100644 --- a/infrastructure/redis.tf +++ b/infrastructure/redis.tf @@ -1,123 +1,4 @@ -resource "kubernetes_deployment_v1" "redis-automatic" { - for_each = { for key, value in var.kubernetes : key => value if value.redis != null && value.enabled == true } - - - metadata { - namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key) - name = "${coalesce(each.value.name, each.key)}-redis" - labels = { - app = each.key - deployment_method = "Terraform" - redis = "true" - } - } - - spec { - replicas = each.value.replicas - - selector { - match_labels = { - app = "${each.key}-redis" - } - } - - template { - metadata { - labels = { - app = "${each.key}-redis" - deployment_method = "Terraform" - redis = "true" - } - } - - spec { - container { - image = try(each.value.redis.image, "docker.io/library/redis:7") - name = "${coalesce(each.value.name, each.key)}-redis" - port { - - container_port = 6379 - name = "redis-port" - - } - - volume_mount { - mount_path = "/data" - name = "${each.key}-redis-volume" - } - - - - - - dynamic "env" { - for_each = each.value.environment != null ? each.value.environment : {} - content { - name = env.key - value = env.value.value != null ? env.value.value : null - dynamic "value_from" { - for_each = env.value.value_from != null ? env.value.value_from : {} - content { - dynamic "secret_key_ref" { - for_each = [1] - content { - name = env.value.value_from.secret_key_ref.name - key = env.value.value_from.secret_key_ref.key - # optional = true - } - } - } - } - - } - } - - - # resources { - # limits = { - # cpu = each.value.requirements.limits-cpu - # memory = each.value.requirements.limits-memory - # } - # requests = { - # cpu = each.value.requirements.requests-cpu - # memory = each.value.requirements.requests-memory - # } - # } - - # dynamic "liveness_probe" { - # for_each = each.value.liveness_tcp_socket != null || each.value.liveness_http_get != null ? [""] : [] - # content { - # dynamic "tcp_socket" { - # for_each = each.value.liveness_tcp_socket != null ? [""] : [] - # content { - # port = each.value.liveness_tcp_socket - # } - # } - - - # dynamic "http_get" { - # for_each = each.value.liveness_http_get != null ? [""] : [] - # content { - # port = each.value.liveness_http_get - # path = coalesce(each.value.liveness_http_get_path, "/") - # } - # } - - # initial_delay_seconds = 3 - # period_seconds = 3 - # } - # } - } - - - volume { - name = "${each.key}-redis-volume" - host_path { - path = try(each.value.redis.host_path, join("/", [var.storage_path.main_storage, coalesce(each.value.namespace, each.value.connected_namespace, each.key), join("-", [each.key, "redis"])])) - } - } - - } - } - } -} +module "Redis-automatic" { + source = "../modules/redis" + kubernetes_input = var.kubernetes +} \ No newline at end of file diff --git a/infrastructure/secrets.tf b/infrastructure/secrets.tf index 8b501ec..5f1997e 100644 --- a/infrastructure/secrets.tf +++ b/infrastructure/secrets.tf @@ -1,198 +1,4 @@ - -data "bitwarden-secrets_secret" "configmap_import" { - for_each = { - for pair in flatten([ - for k, v in var.kubernetes : [ - for id in v.config_map_import : { - map_key = k - secret_id = id - } - ] if v.config_map_import != null && v.enabled == true - ]) : "${pair.map_key}-${pair.secret_id}" => pair.secret_id - } - id = each.value -} - -resource "kubernetes_config_map_v1" "configmap_import" { - for_each = { for key, value in data.bitwarden-secrets_secret.configmap_import : key => value } - metadata { - name = each.value.note - namespace = split("__", each.value.key)[0] - } - data = yamldecode(each.value.value) -} - - -data "bitwarden-secrets_secret" "secret_import" { - for_each = { - for pair in flatten([ - for k, v in var.kubernetes : [ - for id in v.secret_import : { - map_key = k - secret_id = id - } - ] if v.secret_import != null && v.enabled == true - ]) : "${pair.map_key}-${pair.secret_id}" => pair.secret_id - } - id = each.value -} - -resource "kubernetes_secret_v1" "secret_import" { - for_each = { for key, value in data.bitwarden-secrets_secret.secret_import : key => value } - metadata { - name = each.value.note - namespace = split("__", each.value.key)[0] - } - data = yamldecode(each.value.value) -} - - -resource "kubernetes_secret_v1" "automatic-database-secret" { - for_each = { for key, value in var.kubernetes : key => value if value.database != null && value.enabled == true } - metadata { - name = "${each.key}-db-terraform" - namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key) - } - - data = { - DB_DATABASE_NAME = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_name[each.key].value}" - DB_DATABASE = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_name[each.key].value}" - POSTGRES_DB = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_name[each.key].value}" - MYSQL_DATABASE = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_name[each.key].value}" - PGDATABASE = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_name[each.key].value}" - DB_HOST = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_host[each.key].value}" - PGHOST = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_host[each.key].value}" - POSTGRES_HOST = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_host[each.key].value}" - DB_PASSWORD = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_password[each.key].value}" - MYSQL_PASSWORD = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_password[each.key].value}" - MYSQL_ROOT_PASSWORD = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_password[each.key].value}" - POSTGRES_PASSWORD = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_password[each.key].value}" - PGPASSWORD = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_password[each.key].value}" - DB_USERNAME = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_username[each.key].value}" - POSTGRES_USER = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_username[each.key].value}" - MYSQL_USER = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_username[each.key].value}" - PGUSER = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_username[each.key].value}" - DATABASE_URL = "postgresql://${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_username[each.key].value}:${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_password[each.key].value}@${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_host[each.key].value}:${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_port[each.key].value}/${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_name[each.key].value}" - } - -} - -resource "kubernetes_secret_v1" "automatic-database-mapped-secret" { - for_each = { for key, value in var.kubernetes : key => value if value.database != null && value.enabled == true } - metadata { - name = "${each.key}-db-mapped-terraform" - namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key) - } - - data = { - "${try(each.value.database.map_name, "DB_DATABASE_NAME")}" = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_name[each.key].value}" - "${try(each.value.database.map_host, "DB_DATABASE_NAME")}" = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_host[each.key].value}" - "${try(each.value.database.map_password, "DB_DATABASE_NAME")}" = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_password[each.key].value}" - "${try(each.value.database.map_username, "DB_DATABASE_NAME")}" = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_username[each.key].value}" - } -} - - -resource "bitwarden-secrets_secret" "automatic_bitwarden_secret_db_username" { - for_each = { for key, value in var.kubernetes : key => value if value.database != null && value.enabled == true } - key = "${each.key}__db__username" - value = try(each.value.database.username, each.key) - project_id = "b5fc4c48-e951-442f-97ca-b3e800c143cd" - lifecycle { - ignore_changes = [ - value, key - ] - } -} - -resource "bitwarden-secrets_secret" "automatic_bitwarden_secret_db_password" { - for_each = { for key, value in var.kubernetes : key => value if value.database != null && value.enabled == true } - key = "${each.key}__db__password" - project_id = "b5fc4c48-e951-442f-97ca-b3e800c143cd" - length = 32 - special = true - min_special = 5 - avoid_ambiguous = true - lifecycle { - ignore_changes = [ - value, key - ] - } -} - -resource "bitwarden-secrets_secret" "automatic_bitwarden_secret_db_host" { - for_each = { for key, value in var.kubernetes : key => value if value.database != null && value.enabled == true } - key = "${each.key}__db__host" - project_id = "b5fc4c48-e951-442f-97ca-b3e800c143cd" - value = try(each.value.database.host, "${each.key}-db-svc.${coalesce(each.value.namespace, each.value.connected_namespace, each.key)}.svc") - lifecycle { - ignore_changes = [ - value, key - ] - } -} - -resource "bitwarden-secrets_secret" "automatic_bitwarden_secret_db_port" { - for_each = { for key, value in var.kubernetes : key => value if value.database != null && value.enabled == true } - key = "${each.key}__db__port" - project_id = "b5fc4c48-e951-442f-97ca-b3e800c143cd" - value = try(each.value.database.port, 5432) - lifecycle { - ignore_changes = [ - value, key - ] - } -} - -resource "bitwarden-secrets_secret" "automatic_bitwarden_secret_db_name" { - for_each = { for key, value in var.kubernetes : key => value if value.database != null && value.enabled == true } - key = "${each.key}__db__name" - project_id = "b5fc4c48-e951-442f-97ca-b3e800c143cd" - value = try(each.value.database.name, each.key) - lifecycle { - ignore_changes = [ - value, key - ] - } -} - -# 1. Move the loop logic to a local variable first -locals { - database_secrets_to_import = { - for key, value in var.kubernetes : key => value - if value.database != null && value.enabled == true && can(value.import_database_secret.host) - } -} - -# 2. Reference the local map in your import block using each.key and each.value -import { - for_each = local.database_secrets_to_import - - to = bitwarden-secrets_secret.automatic_bitwarden_secret_db_host[each.key] - id = each.value.import_database_secret.host -} - -import { - for_each = local.database_secrets_to_import - - to = bitwarden-secrets_secret.automatic_bitwarden_secret_db_name[each.key] - id = each.value.import_database_secret.name -} -import { - for_each = local.database_secrets_to_import - - to = bitwarden-secrets_secret.automatic_bitwarden_secret_db_password[each.key] - id = each.value.import_database_secret.password -} -import { - for_each = local.database_secrets_to_import - - to = bitwarden-secrets_secret.automatic_bitwarden_secret_db_port[each.key] - id = each.value.import_database_secret.port -} -import { - for_each = local.database_secrets_to_import - - to = bitwarden-secrets_secret.automatic_bitwarden_secret_db_username[each.key] - id = each.value.import_database_secret.username -} +module "Secrets-automatic" { + source = "../modules/secrets" + kubernetes_input = var.kubernetes +} \ No newline at end of file diff --git a/modules/redis/main.tf b/modules/redis/main.tf new file mode 100644 index 0000000..dfbe95a --- /dev/null +++ b/modules/redis/main.tf @@ -0,0 +1,113 @@ +variable "kubernetes_input" { + type = map(object({ + name = optional(string) + environment = optional(map(object({ + name = optional(string) + value = optional(string) + value_from = optional(object({ + secret_key_ref = object({ + name = string + key = optional(string, null) + }) + })) + }))) + replicas = optional(number, 1) + namespace = optional(string) + connected_namespace = optional(string, "") + redis = optional(map(string)) + enabled = optional(bool, true) + })) + +} +variable "storage_path" { + type = map(string) + default = { + main_storage = "/data/kubernetes", + fast_access = "/ssd" + } +} + +resource "kubernetes_deployment_v1" "redis-automatic" { + for_each = { for key, value in var.kubernetes_input : key => value if value.redis != null && value.enabled == true } + + + metadata { + namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key) + name = "${coalesce(each.value.name, each.key)}-redis" + labels = { + app = each.key + deployment_method = "Terraform" + redis = "true" + } + } + + spec { + replicas = each.value.replicas + + selector { + match_labels = { + app = "${each.key}-redis" + } + } + + template { + metadata { + labels = { + app = "${each.key}-redis" + deployment_method = "Terraform" + redis = "true" + } + } + + spec { + container { + image = try(each.value.redis.image, "docker.io/library/redis:7") + name = "${coalesce(each.value.name, each.key)}-redis" + port { + + container_port = 6379 + name = "redis-port" + + } + + volume_mount { + mount_path = "/data" + name = "${each.key}-redis-volume" + } + + + + + + dynamic "env" { + for_each = each.value.environment != null ? each.value.environment : {} + content { + name = env.key + value = env.value.value != null ? env.value.value : null + dynamic "value_from" { + for_each = env.value.value_from != null ? env.value.value_from : {} + content { + dynamic "secret_key_ref" { + for_each = [1] + content { + name = env.value.value_from.secret_key_ref.name + key = env.value.value_from.secret_key_ref.key + } + } + } + } + } + } + + + volume { + name = "${each.key}-redis-volume" + host_path { + path = try(each.value.redis.host_path, join("/", [var.storage_path.main_storage, coalesce(each.value.namespace, each.value.connected_namespace, each.key), join("-", [each.key, "redis"])])) + } + } + + } + } + } +} diff --git a/modules/secrets/main.tf b/modules/secrets/main.tf new file mode 100644 index 0000000..f36758d --- /dev/null +++ b/modules/secrets/main.tf @@ -0,0 +1,304 @@ +variable "kubernetes_input" { + type = map(object({ + namespace = optional(string) + connected_namespace = optional(string, "") + database = optional(map(string)) + redis = optional(map(string)) + enabled = optional(bool, true) + config_map_import = optional(list(string)) + secret_import = optional(list(string)) + requirements = optional(map(string), { + limits-cpu = "800m" + limits-memory = "500Mi" + requests-cpu = "200m" + requests-memory = "200Mi" + }) + import_database_secret = optional(object({ + #putting them a non optional as the code doesn't allow optional value + host = string + name = string + password = string + port = string + username = string + })) + })) + +} + +########################################################################################################################################################################################### +# +# +# CONFIGMAP PART +# +# +# +########################################################################################################################################################################################### +data "bitwarden-secrets_secret" "configmap_import" { + for_each = { + for pair in flatten([ + for k, v in var.kubernetes_input : [ + for id in v.config_map_import : { + map_key = k + secret_id = id + } + ] if v.config_map_import != null && v.enabled == true + ]) : "${pair.map_key}-${pair.secret_id}" => pair.secret_id + } + id = each.value +} + +resource "kubernetes_config_map_v1" "configmap_import" { + for_each = { for key, value in data.bitwarden-secrets_secret.configmap_import : key => value } + metadata { + name = each.value.note + namespace = split("__", each.value.key)[0] + } + data = yamldecode(each.value.value) +} + + +data "bitwarden-secrets_secret" "secret_import" { + for_each = { + for pair in flatten([ + for k, v in var.kubernetes_input : [ + for id in v.secret_import : { + map_key = k + secret_id = id + } + ] if v.secret_import != null && v.enabled == true + ]) : "${pair.map_key}-${pair.secret_id}" => pair.secret_id + } + id = each.value +} + +resource "kubernetes_secret_v1" "secret_import" { + for_each = { for key, value in data.bitwarden-secrets_secret.secret_import : key => value } + metadata { + name = each.value.note + namespace = split("__", each.value.key)[0] + } + data = yamldecode(each.value.value) +} + +########################################################################################################################################################################################### +# +# +# DATABASE PART +# +# +# +########################################################################################################################################################################################### +resource "kubernetes_secret_v1" "automatic-database-secret" { + for_each = { for key, value in var.kubernetes_input : key => value if value.database != null && value.enabled == true } + metadata { + name = "${each.key}-db-terraform" + namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key) + } + + data = { + DB_DATABASE_NAME = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_name[each.key].value}" + DB_DATABASE = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_name[each.key].value}" + POSTGRES_DB = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_name[each.key].value}" + MYSQL_DATABASE = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_name[each.key].value}" + PGDATABASE = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_name[each.key].value}" + DB_HOST = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_host[each.key].value}" + PGHOST = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_host[each.key].value}" + POSTGRES_HOST = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_host[each.key].value}" + DB_PASSWORD = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_password[each.key].value}" + MYSQL_PASSWORD = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_password[each.key].value}" + MYSQL_ROOT_PASSWORD = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_password[each.key].value}" + POSTGRES_PASSWORD = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_password[each.key].value}" + PGPASSWORD = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_password[each.key].value}" + DB_USERNAME = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_username[each.key].value}" + POSTGRES_USER = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_username[each.key].value}" + MYSQL_USER = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_username[each.key].value}" + PGUSER = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_username[each.key].value}" + DATABASE_URL = "postgresql://${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_username[each.key].value}:${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_password[each.key].value}@${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_host[each.key].value}:${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_port[each.key].value}/${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_name[each.key].value}" + } + +} + +resource "kubernetes_secret_v1" "automatic-database-mapped-secret" { + for_each = { for key, value in var.kubernetes_input : key => value if value.database != null && value.enabled == true } + metadata { + name = "${each.key}-db-mapped-terraform" + namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key) + } + + data = { + "${try(each.value.database.map_name, "DB_DATABASE_NAME")}" = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_name[each.key].value}" + "${try(each.value.database.map_host, "DB_DATABASE_NAME")}" = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_host[each.key].value}" + "${try(each.value.database.map_password, "DB_DATABASE_NAME")}" = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_password[each.key].value}" + "${try(each.value.database.map_username, "DB_DATABASE_NAME")}" = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_db_username[each.key].value}" + } +} + + +resource "bitwarden-secrets_secret" "automatic_bitwarden_secret_db_username" { + for_each = { for key, value in var.kubernetes_input : key => value if value.database != null && value.enabled == true } + key = "${each.key}__db__username" + value = try(each.value.database.username, each.key) + project_id = "b5fc4c48-e951-442f-97ca-b3e800c143cd" + lifecycle { + ignore_changes = [ + value, key + ] + } +} + +resource "bitwarden-secrets_secret" "automatic_bitwarden_secret_db_password" { + for_each = { for key, value in var.kubernetes_input : key => value if value.database != null && value.enabled == true } + key = "${each.key}__db__password" + project_id = "b5fc4c48-e951-442f-97ca-b3e800c143cd" + length = 32 + special = true + min_special = 5 + avoid_ambiguous = true + lifecycle { + ignore_changes = [ + value, key + ] + } +} + +resource "bitwarden-secrets_secret" "automatic_bitwarden_secret_db_host" { + for_each = { for key, value in var.kubernetes_input : key => value if value.database != null && value.enabled == true } + key = "${each.key}__db__host" + project_id = "b5fc4c48-e951-442f-97ca-b3e800c143cd" + value = try(each.value.database.host, "${each.key}-db-svc.${coalesce(each.value.namespace, each.value.connected_namespace, each.key)}.svc") + lifecycle { + ignore_changes = [ + value, key + ] + } +} + +resource "bitwarden-secrets_secret" "automatic_bitwarden_secret_db_port" { + for_each = { for key, value in var.kubernetes_input : key => value if value.database != null && value.enabled == true } + key = "${each.key}__db__port" + project_id = "b5fc4c48-e951-442f-97ca-b3e800c143cd" + value = try(each.value.database.port, 5432) + lifecycle { + ignore_changes = [ + value, key + ] + } +} + +resource "bitwarden-secrets_secret" "automatic_bitwarden_secret_db_name" { + for_each = { for key, value in var.kubernetes_input : key => value if value.database != null && value.enabled == true } + key = "${each.key}__db__name" + project_id = "b5fc4c48-e951-442f-97ca-b3e800c143cd" + value = try(each.value.database.name, each.key) + lifecycle { + ignore_changes = [ + value, key + ] + } +} + +# 1. Move the loop logic to a local variable first +locals { + database_secrets_to_import = { + for key, value in var.kubernetes_input : key => value + if value.database != null && value.enabled == true && can(value.import_database_secret.host) + } +} + +# 2. Reference the local map in your import block using each.key and each.value +import { + for_each = local.database_secrets_to_import + + to = bitwarden-secrets_secret.automatic_bitwarden_secret_db_host[each.key] + id = each.value.import_database_secret.host +} + +import { + for_each = local.database_secrets_to_import + + to = bitwarden-secrets_secret.automatic_bitwarden_secret_db_name[each.key] + id = each.value.import_database_secret.name +} +import { + for_each = local.database_secrets_to_import + + to = bitwarden-secrets_secret.automatic_bitwarden_secret_db_password[each.key] + id = each.value.import_database_secret.password +} +import { + for_each = local.database_secrets_to_import + + to = bitwarden-secrets_secret.automatic_bitwarden_secret_db_port[each.key] + id = each.value.import_database_secret.port +} +import { + for_each = local.database_secrets_to_import + + to = bitwarden-secrets_secret.automatic_bitwarden_secret_db_username[each.key] + id = each.value.import_database_secret.username +} +########################################################################################################################################################################################### +# +# +# REDIS PART +# +# +# +########################################################################################################################################################################################### + +resource "bitwarden-secrets_secret" "automatic_bitwarden_secret_redis_host" { + for_each = { for key, value in var.kubernetes_input : key => value if value.redis != null && value.enabled == true } + key = "${each.key}__redis__host" + project_id = "b5fc4c48-e951-442f-97ca-b3e800c143cd" + value = try(each.value.redis.host, "${each.key}-redis-svc.${coalesce(each.value.namespace, each.value.connected_namespace, each.key)}.svc") +} + +resource "bitwarden-secrets_secret" "automatic_bitwarden_secret_redis_port" { + for_each = { for key, value in var.kubernetes_input : key => value if value.redis != null && value.enabled == true } + key = "${each.key}__redis__port" + project_id = "b5fc4c48-e951-442f-97ca-b3e800c143cd" + value = try(each.value.redis.port, 5432) +} + +## +## Commenting until I use the redis password option +## +#resource "bitwarden-secrets_secret" "automatic_bitwarden_secret_redis_password" { +# for_each = { for key, value in var.kubernetes_input : key => value if value.redis != null && value.enabled == true } +# key = "${each.key}__redis__password" +# project_id = "b5fc4c48-e951-442f-97ca-b3e800c143cd" +# length = 32 +# special = true +# min_special = 5 +# avoid_ambiguous = true +#} + +resource "bitwarden-secrets_secret" "automatic_bitwarden_secret_redis_REPLICATION_MODE" { + for_each = { for key, value in var.kubernetes_input : key => value if value.redis != null && value.enabled == true } + key = "${each.key}__redis__REPLICATION_MODE" + project_id = "b5fc4c48-e951-442f-97ca-b3e800c143cd" + value = try(each.value.redis.REPLICATION_MODE, "master") +} + +resource "bitwarden-secrets_secret" "automatic_bitwarden_secret_redis_TLS_ENABLED" { + for_each = { for key, value in var.kubernetes_input : key => value if value.redis != null && value.enabled == true } + key = "${each.key}__redis__TLS_ENABLED" + project_id = "b5fc4c48-e951-442f-97ca-b3e800c143cd" + value = try(each.value.redis.TLS_ENABLED, "no") +} + +resource "kubernetes_secret_v1" "automatic-redis-secret" { + for_each = { for key, value in var.kubernetes_input : key => value if value.redis != null && value.enabled == true } + metadata { + name = "${each.key}-redis-terraform" + namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key) + } + + data = { + REDIS_HOSTNAME = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_redis_host[each.key].value}" + REDIS_PORT = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_redis_port[each.key].value}" + REDIS_REPLICATION_MODE = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_redis_REPLICATION_MODE[each.key].value}" + REDIS_TLS_ENABLED = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_redis_TLS_ENABLED[each.key].value}" + } + +} \ No newline at end of file