# PostgreSQL in Kubernetes Cluster # Using StatefulSet with PersistentVolume for data persistence # Kubernetes Secret for PostgreSQL resource "kubernetes_secret" "postgresql" { metadata { name = "postgresql-credentials" namespace = kubernetes_namespace.app.metadata[0].name labels = local.common_labels } data = { POSTGRES_USER = var.postgresql_admin_username POSTGRES_PASSWORD = var.postgresql_admin_password POSTGRES_DB = local.postgresql_db_name } type = "Opaque" } # PersistentVolumeClaim for PostgreSQL data resource "kubernetes_persistent_volume_claim" "postgresql" { metadata { name = "postgresql-pvc" namespace = kubernetes_namespace.app.metadata[0].name labels = local.common_labels } spec { access_modes = ["ReadWriteOnce"] resources { requests = { storage = "10Gi" } } } wait_until_bound = false } # PostgreSQL StatefulSet resource "kubernetes_stateful_set" "postgresql" { metadata { name = "postgresql" namespace = kubernetes_namespace.app.metadata[0].name labels = local.common_labels } spec { service_name = "postgresql" replicas = 1 selector { match_labels = { app = "postgresql" } } template { metadata { labels = merge( local.common_labels, { app = "postgresql" } ) } spec { container { name = "postgresql" image = "postgres:16-alpine" port { container_port = 5432 name = "postgresql" } env_from { secret_ref { name = kubernetes_secret.postgresql.metadata[0].name } } volume_mount { name = "postgresql-storage" mount_path = "/var/lib/postgresql/data" sub_path = "postgres" } resources { requests = { cpu = "250m" memory = "512Mi" } limits = { cpu = "1000m" memory = "1Gi" } } liveness_probe { exec { command = ["pg_isready", "-U", var.postgresql_admin_username] } initial_delay_seconds = 30 period_seconds = 10 timeout_seconds = 5 failure_threshold = 3 } readiness_probe { exec { command = ["pg_isready", "-U", var.postgresql_admin_username] } initial_delay_seconds = 5 period_seconds = 5 timeout_seconds = 3 failure_threshold = 3 } } volume { name = "postgresql-storage" persistent_volume_claim { claim_name = kubernetes_persistent_volume_claim.postgresql.metadata[0].name } } } } } depends_on = [ kubernetes_persistent_volume_claim.postgresql, kubernetes_secret.postgresql ] } # PostgreSQL Service resource "kubernetes_service" "postgresql" { metadata { name = "postgresql" namespace = kubernetes_namespace.app.metadata[0].name labels = local.common_labels } spec { selector = { app = "postgresql" } port { name = "postgresql" port = 5432 target_port = 5432 protocol = "TCP" } type = "ClusterIP" cluster_ip = "None" # Headless service for StatefulSet session_affinity = "None" } depends_on = [ kubernetes_stateful_set.postgresql ] }