From 4155776c277892a7c537311e5f9d1da759872755 Mon Sep 17 00:00:00 2001 From: pierre geeraert Date: Wed, 14 Oct 2026 00:04:14 +0100 Subject: [PATCH] module database --- modules/database/main.tf | 224 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 modules/database/main.tf diff --git a/modules/database/main.tf b/modules/database/main.tf new file mode 100644 index 0000000..7bb7b7a --- /dev/null +++ b/modules/database/main.tf @@ -0,0 +1,224 @@ +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, "") + database = optional(map(string)) + database_args = optional(list(string)) + enabled = optional(bool, true) + })) + +} + +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" + } +} + +resource "kubernetes_deployment_v1" "database-automatic" { + for_each = { for key, value in var.kubernetes_input : key => value if value.database != null && value.enabled == true && !(try(value.database.shunt, false)) } + + + metadata { + namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key) + name = "${coalesce(each.value.name, each.key)}-db" + labels = { + app = each.key + deployment_method = "Terraform" + database = "true" + } + } + + spec { + replicas = each.value.replicas + + selector { + match_labels = { + app = "${each.key}-db" + } + } + + template { + metadata { + labels = { + app = "${each.key}-db" + deployment_method = "Terraform" + database = "true" + } + } + + spec { + container { + image = try(each.value.database.image, "docker.io/library/postgres:latest") + name = "${coalesce(each.value.name, each.key)}-db" + port { + + container_port = 5432 + name = "database-port" + + } + + volume_mount { + mount_path = try(each.value.database.mountPath, "/var/lib/postgresql/") + name = "${each.key}-db-volume" + } + + dynamic "volume_mount" { + for_each = try(each.value.database.engine == "sqlserver", false) && !(try(each.value.database.shunt, false)) ? [1] : [] + content { + mount_path = "/backup" + name = "${each.key}-db-backup" + } + } + + command = try([each.value.database.command], []) + args = each.value.database_args != null ? each.value.database_args : [] + + dynamic "env_from" { + for_each = each.value.database != null && each.value.enabled == true && !(try(each.value.database.shunt, false)) ? ["${each.key}-db-terraform"] : [] + content { + dynamic "secret_ref" { + for_each = [1] + content { + name = env_from.value + } + } + } + } + + 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}-db-volume" + host_path { + path = try(each.value.database.host_path, join("/", [var.storage_path.main_storage, coalesce(each.value.namespace, each.value.connected_namespace, each.key), join("-", [each.key, "db"])])) + } + } + + dynamic "volume" { + for_each = try(each.value.database.engine == "sqlserver", false) && !(try(each.value.database.shunt, false)) ? [1] : [] + content { + name = "${each.key}-db-backup" + + host_path { + path = join("/", [var.storage_path.fast_access, "Backup", coalesce(each.value.namespace, each.value.connected_namespace, each.key), "${each.key}-db-backup"]) + } + } + } + + } + } + } +} + + +resource "kubernetes_cron_job_v1" "database-backup" { + for_each = { for key, value in var.kubernetes_input : key => value if value.database != null && value.enabled == true } + metadata { + name = "${coalesce(each.value.namespace, each.key)}-db-backup" + namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key) + labels = { + app = each.key + deployment_method = "Terraform" + database = "true" + } + } + spec { + failed_jobs_history_limit = 5 + schedule = "1 0 * * *" + timezone = "Etc/UTC" + successful_jobs_history_limit = 5 + job_template { + metadata {} + spec { + backoff_limit = 4 + ttl_seconds_after_finished = 100 + template { + metadata {} + spec { + container { + name = "${coalesce(each.value.namespace, each.key)}-db-backup" + image = try(var.database_backup_info[each.value.database.engine].image, var.database_backup_info.postgres.image) + command = ["/bin/sh", "-c"] + args = [try(var.database_backup_info[each.value.database.engine].command, var.database_backup_info.postgres.command)] + env_from { + secret_ref { + name = "${each.key}-db-terraform" + } + } + volume_mount { + mount_path = "/backup" + name = "${each.key}-db-backup" + } + } + volume { + name = "${each.key}-db-backup" + host_path { + path = join("/", [var.storage_path.fast_access, "Backup", coalesce(each.value.namespace, each.value.connected_namespace, each.key), "${each.key}-db-backup"]) + } + } + } + } + } + } + } +}