MongoDB

Add locals for MongoDB:

locals {

  replica_count = 3

  replica_set_name = "mongodb"

  endpoints = [
    for index in range(local.replica_count) : "${local.replica_set_name}-${index}.mongodb-headless.mongodb.svc.cluster.local:27017"
  ]

  mongodb_hostname_string = join(",", local.endpoints)

  mongodb_users = [
    {
      database = "accounts"
      username = "auth"
      role     = "readWrite"
    },
    {
      database = "workflows"
      username = "command"
      role     = "readWrite"
    },
    {
      database = "workflows"
      username = "query"
      role     = "read"
    }
  ]

  mongodb_users_map = {
    for user in local.mongodb_users : user.username => user
  }

  mongodb_database_credentials_map = {
    for user, data in local.mongodb_users_map : user => merge(data, {
      password   = random_password.mongodb_passwords[user].result
      credential = "${data.username}:${random_password.mongodb_passwords[user].result}"
    })
  }
  mongodb_init_scripts = {
    for user in local.mongodb_users : "grant-${user.username}-${user.database}.js" => templatefile(
      "${path.module}/scripts/mongodb/grant-user.js.tpl",
      { user = user }
    )
  }

  credentials_pre_map = {
    for user, data in local.mongodb_database_credentials_map : user => merge(data, {
      connection_string = "mongodb://${data.username}:${random_password.mongodb_passwords[user].result}@${local.mongodb_hostname_string}/${data.database}?ssl=false&replicaSet=${local.replica_set_name}"
    })
  }

  credentials_map = {
    for user, data in local.credentials_pre_map : user => merge(data, {
      connection_string_escaped = replace(data.connection_string, "/[,.=]/", "\\$0")
    })
  }
}

Create namespace for MongoDB:

resource "kubernetes_namespace" "mongodb" {
  metadata {
    name = "mongodb"
    labels = {
      "pod-security.kubernetes.io/enforce" = "restricted"
    }
  }
}

Create users and passwords for MongoDB:

resource "random_password" "mongodb_root_user" {
  length  = 32
  special = false
}

resource "random_password" "mongodb_root_password" {
  length  = 64
  special = false
}

resource "random_password" "mongodb_passwords" {
  for_each = local.mongodb_users_map

  length  = 32
  special = false
}

resource "random_password" "replica_set_key" {
  length  = 64
  special = false
}

resource "kubernetes_secret" "mongodb" {
  metadata {
    name      = "mongodb-passwords"
    namespace = kubernetes_namespace.mongodb.metadata[0].name
  }

  data = {
    mongodb-passwords       = join(",", [for user in local.mongodb_users : random_password.mongodb_passwords[user.username].result])
    mongodb-replica-set-key = random_password.replica_set_key.result
    mongodb-root-password   = random_password.mongodb_root_password.result
  }
}

Deploy the mongodb Helm chart from Bitnami:

# https://artifacthub.io/packages/helm/bitnami/mongodb
resource "helm_release" "mongodb" {
  name       = "mongodb"
  namespace  = kubernetes_namespace.mongodb.metadata[0].name
  repository = "oci://registry-1.docker.io/bitnamicharts"
  version    = "15.0.2"
  chart      = "mongodb"

  values = [yamlencode({
    arbiter = {
      enabled = false
    }

    architecture = "replicaset"

    auth = {
      databases      = [for user in local.mongodb_users : user.database]
      usernames      = [for user in local.mongodb_users : user.username]
      existingSecret = kubernetes_secret.mongodb.metadata[0].name
    }

    initdbScripts = local.mongodb_init_scripts

    persistentVolumeClaimRetentionPolicy = {
      enabled     = true
      whenScaled  = "Retain"
      whenDeleted = "Retain"
    }

    podAntiAffinityPreset = "hard"

    replicaCount        = local.replica_count
    replicaSetHostnames = true
    replicaSetName      = local.replica_set_name

    resourcesPreset = "large"

    topologyKey = "topology.kubernetes.io/zone"
  })]

  set_sensitive {
    name  = "auth.rootUser"
    value = random_password.mongodb_root_user.result
  }
}