diff --git a/.github/workflows/tofu-deploy.yaml b/.github/workflows/tofu-deploy.yaml index 576c6b4..2b1517b 100644 --- a/.github/workflows/tofu-deploy.yaml +++ b/.github/workflows/tofu-deploy.yaml @@ -24,7 +24,7 @@ jobs: uses: necro-cloud/automations/.github/workflows/tofu-deploy.yml@main with: deployment_name: Kubernetes Infrastructure - folder_path: example + folder_path: infrastructure runners: cloud pre_plan_script: tofu apply --target=module.helm -var-file terraform.tfvars.json -auto-approve secrets: diff --git a/example/README.md b/infrastructure/README.md similarity index 100% rename from example/README.md rename to infrastructure/README.md diff --git a/example/locals.tf b/infrastructure/locals.tf similarity index 100% rename from example/locals.tf rename to infrastructure/locals.tf diff --git a/example/main.tf b/infrastructure/main.tf similarity index 96% rename from example/main.tf rename to infrastructure/main.tf index a3ae104..af2e259 100644 --- a/example/main.tf +++ b/infrastructure/main.tf @@ -81,7 +81,7 @@ module "cnpg" { # FerretDB Deployment for MongoDB Database Solution module "ferretdb" { - source = "git::https://github.com/necro-cloud/modules//modules/ferretdb?ref=task/68/authn-setup" + source = "git::https://github.com/necro-cloud/modules//modules/ferretdb?ref=task/69/mongo-ui" // Garage Cluster Details for configuration of PITR Backups garage_certificate_authority = module.garage.garage_internal_certificate_secret @@ -97,8 +97,11 @@ module "ferretdb" { } ] - // Certificate details for internal certificates + // Certificate details for internal and ingress certificates cluster_issuer_name = module.cluster-issuer.cluster-issuer-name + cloudflare_token = var.cloudflare_token + cloudflare_email = var.cloudflare_email + domain = var.domain // Whitelisting Kubernetes API Endpoints in the Network Policy kubernetes_api_ip = one(flatten(data.kubernetes_endpoints_v1.kubernetes_api_endpoint.subset[*].address[*].ip)) diff --git a/example/providers.tf b/infrastructure/providers.tf similarity index 100% rename from example/providers.tf rename to infrastructure/providers.tf diff --git a/example/variables.tf b/infrastructure/variables.tf similarity index 100% rename from example/variables.tf rename to infrastructure/variables.tf diff --git a/modules/ferretdb/README.md b/modules/ferretdb/README.md index 0f21db0..d21482d 100644 --- a/modules/ferretdb/README.md +++ b/modules/ferretdb/README.md @@ -19,12 +19,17 @@ Required Modules to deploy FerretDB Database: | Name | Type | |------|------| | [kubernetes_deployment.ferretdb](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/deployment) | resource | +| [kubernetes_deployment.mongo_express](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/deployment) | resource | +| [kubernetes_ingress_v1.mongo_express_ingress](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/ingress_v1) | resource | | [kubernetes_manifest.barman_object_store](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/manifest) | resource | | [kubernetes_manifest.client_certificate_authority](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/manifest) | resource | | [kubernetes_manifest.client_issuer](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/manifest) | resource | | [kubernetes_manifest.client_streaming_replica_certificate](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/manifest) | resource | | [kubernetes_manifest.cluster](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/manifest) | resource | | [kubernetes_manifest.ferret_cluster_image_catalog](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/manifest) | resource | +| [kubernetes_manifest.ingress_certificate](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/manifest) | resource | +| [kubernetes_manifest.mongo_express_internal_certificate](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/manifest) | resource | +| [kubernetes_manifest.public_issuer](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/manifest) | resource | | [kubernetes_manifest.server_certificate](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/manifest) | resource | | [kubernetes_manifest.server_certificate_authority](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/manifest) | resource | | [kubernetes_manifest.server_issuer](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/manifest) | resource | @@ -34,42 +39,59 @@ Required Modules to deploy FerretDB Database: | [kubernetes_pod_disruption_budget_v1.cnpg_pdb](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/pod_disruption_budget_v1) | resource | | [kubernetes_pod_disruption_budget_v1.ferret_pdb](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/pod_disruption_budget_v1) | resource | | [kubernetes_secret.client_database_credentials](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/secret) | resource | +| [kubernetes_secret.cloudflare_token](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/secret) | resource | | [kubernetes_secret.ferret_database_credentials](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/secret) | resource | | [kubernetes_secret.garage_certificate_authority](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/secret) | resource | | [kubernetes_secret.garage_configuration](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/secret) | resource | +| [kubernetes_secret.ui_credentials](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/secret) | resource | | [kubernetes_service.ferret_service](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/service) | resource | +| [kubernetes_service.mongo_express](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/service) | resource | | [random_password.client_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | | [random_password.ferret_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | +| [random_password.ui_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| [acme\_server](#input\_acme\_server) | URL for the ACME Server to be used, defaults to production URL for LetsEncrypt | `string` | `"https://acme-v02.api.letsencrypt.org/directory"` | no | | [app\_name](#input\_app\_name) | App name for deploying Ferret Database | `string` | `"ferret"` | no | | [backup\_bucket\_name](#input\_backup\_bucket\_name) | Name of the bucket for storing PITR Backups in Garage | `string` | n/a | yes | | [client\_certificate\_authority\_name](#input\_client\_certificate\_authority\_name) | Name of the Certificate Authority to be used with Ferret Client | `string` | `"ferretdb-client-certificate-authority"` | no | | [client\_issuer\_name](#input\_client\_issuer\_name) | Name of the Issuer to be used with Ferret Client | `string` | `"ferretdb-client-issuer"` | no | | [client\_streaming\_replica\_certificate\_name](#input\_client\_streaming\_replica\_certificate\_name) | Name of the Certificate to be used with Ferret Streaming Replica Client | `string` | `"ferretdb-streaming-replica-client-certificate"` | no | -| [clients](#input\_clients) | Object List of clients who need databases and users to be configured for |
list(object({
namespace = string
user = string
database = string
derRequired = bool
privateKeyEncoding = string
})) | `[]` | no |
+| [clients](#input\_clients) | Object List of clients who need databases and users to be configured for | list(object({
namespace = string
user = string
})) | `[]` | no |
+| [cloudflare\_email](#input\_cloudflare\_email) | Email for generating Ingress Certificates to be associated with MongoExpress | `string` | n/a | yes |
+| [cloudflare\_issuer\_name](#input\_cloudflare\_issuer\_name) | Name of the Cloudflare Issuer to be associated with MongoExpress | `string` | `"mongo-express-cloudflare-issuer"` | no |
+| [cloudflare\_token](#input\_cloudflare\_token) | Token for generating Ingress Certificates to be associated with MongoExpress | `string` | n/a | yes |
| [cluster\_issuer\_name](#input\_cluster\_issuer\_name) | Name for the Cluster Issuer to be used to generate internal self signed certificates | `string` | n/a | yes |
| [cluster\_name](#input\_cluster\_name) | Name of the Ferret Database Cluster to be created | `string` | `"ferret-postgresql-cluster"` | no |
| [cluster\_postgresql\_version](#input\_cluster\_postgresql\_version) | Version of Ferret Database to use and deploy | `number` | `17` | no |
| [cluster\_size](#input\_cluster\_size) | Number of pods to deploy for the Ferret Cluster | `number` | `2` | no |
| [country\_name](#input\_country\_name) | Country name for deploying Ferret Database | `string` | `"India"` | no |
+| [domain](#input\_domain) | Domain for which Ingress Certificate is to be generated for | `string` | n/a | yes |
| [garage\_certificate\_authority](#input\_garage\_certificate\_authority) | Name of the Certificate Authority associated with the Garage Storage Solution | `string` | n/a | yes |
| [garage\_configuration](#input\_garage\_configuration) | Garage Configuration for storing PITR Backups | `string` | n/a | yes |
| [garage\_namespace](#input\_garage\_namespace) | Namespace for the Garage Deployment for storing PITR Backups | `string` | n/a | yes |
+| [host\_name](#input\_host\_name) | Host name for which Ingress Certificate is to be generated for | `string` | `"nosql"` | no |
+| [image](#input\_image) | Docker image to be used for deployment of FerretDB | `string` | `"ferretdb"` | no |
+| [ingress\_certificate\_name](#input\_ingress\_certificate\_name) | Name of the Ingress Certificate to be associated with MongoExpress | `string` | `"mongo-express-ingress-certificate"` | no |
| [kubernetes\_api\_ip](#input\_kubernetes\_api\_ip) | IP Address for the Kubernetes API | `string` | n/a | yes |
| [kubernetes\_api\_port](#input\_kubernetes\_api\_port) | Port for the Kubernetes API | `number` | n/a | yes |
| [kubernetes\_api\_protocol](#input\_kubernetes\_api\_protocol) | Protocol for the Kubernetes API | `string` | n/a | yes |
+| [mongo\_express\_image](#input\_mongo\_express\_image) | Docker image to be used for deployment of Mongo Express UI | `string` | `"mongo-express"` | no |
+| [mongo\_express\_repository](#input\_mongo\_express\_repository) | Repository to be used for deployment of Mongo Express UI | `string` | `"docker.io/library"` | no |
+| [mongo\_express\_tag](#input\_mongo\_express\_tag) | Docker tag to be used for deployment of Mongo Express UI | `string` | `"1.0.2-20-alpine3.19"` | no |
| [namespace](#input\_namespace) | Namespace to be used for deploying Ferret Database | `string` | `"ferret"` | no |
| [organization\_name](#input\_organization\_name) | Organization name for deploying Ferret Database | `string` | `"cloud"` | no |
+| [repository](#input\_repository) | Repository to be used for deployment of FerretDB | `string` | `"ghcr.io/ferretdb"` | no |
| [server\_certificate\_authority\_name](#input\_server\_certificate\_authority\_name) | Name of the Certificate Authority to be used with Ferret Server | `string` | `"ferretdb-server-certificate-authority"` | no |
| [server\_certificate\_name](#input\_server\_certificate\_name) | Name of the Certificate to be used with Ferret Server | `string` | `"ferretdb-server-certificate"` | no |
| [server\_issuer\_name](#input\_server\_issuer\_name) | Name of the Issuer to be used with Ferret Server | `string` | `"ferretdb-server-issuer"` | no |
+| [tag](#input\_tag) | Docker tag to be used for deployment of FerretDB | `string` | `"2.7.0"` | no |
## Outputs
| Name | Description |
|------|-------------|
-| [namespace](#output\_namespace) | Namespace where FerretDB is deployed in |
+| [namespace](#output\_namespace) | Namespace where the PostgreSQL Database is deployed in |
diff --git a/modules/ferretdb/certificates.tf b/modules/ferretdb/certificates.tf
index 5bd598e..1893429 100644
--- a/modules/ferretdb/certificates.tf
+++ b/modules/ferretdb/certificates.tf
@@ -295,3 +295,170 @@ resource "kubernetes_manifest" "client_streaming_replica_certificate" {
delete = "5m"
}
}
+
+// Internal Certificate for MongoExpress
+resource "kubernetes_manifest" "mongo_express_internal_certificate" {
+ manifest = {
+ "apiVersion" = "cert-manager.io/v1"
+ "kind" = "Certificate"
+ "metadata" = {
+ "name" = "mongo-express-internal-certificate"
+ "namespace" = kubernetes_namespace.namespace.metadata[0].name
+ "labels" = {
+ "app" = var.app_name
+ "component" = "internal-certificate"
+ }
+ }
+ "spec" = {
+ "dnsNames" = [
+ "database.${kubernetes_namespace.namespace.metadata[0].name}.svc.cluster.local",
+ "127.0.0.1",
+ "localhost",
+ ]
+ "subject" = {
+ "organizations" = [var.organization_name]
+ "countries" = [var.country_name]
+ "organizationalUnits" = [var.app_name]
+ }
+ "commonName" = "mongo-express-internal-certificate"
+ "secretName" = "mongo-express-internal-certificate"
+ "issuerRef" = {
+ "name" = kubernetes_manifest.server_issuer.manifest.metadata.name
+ }
+ }
+ }
+
+ wait {
+ condition {
+ type = "Ready"
+ status = "True"
+ }
+ }
+ timeouts {
+ create = "5m"
+ update = "5m"
+ delete = "5m"
+ }
+}
+
+// Kubernetes Secret for Cloudflare Tokens
+resource "kubernetes_secret" "cloudflare_token" {
+ metadata {
+ name = "cloudflare-token"
+ namespace = kubernetes_namespace.namespace.metadata[0].name
+ labels = {
+ "app" = var.app_name
+ "component" = "secret"
+ }
+ }
+
+ data = {
+ cloudflare-token = var.cloudflare_token
+ }
+
+ type = "Opaque"
+}
+
+// Cloudflare Issuer for MongoExpress Ingress Service
+resource "kubernetes_manifest" "public_issuer" {
+ manifest = {
+ "apiVersion" = "cert-manager.io/v1"
+ "kind" = "Issuer"
+ "metadata" = {
+ "name" = var.cloudflare_issuer_name
+ "namespace" = kubernetes_namespace.namespace.metadata[0].name
+ "labels" = {
+ "app" = var.app_name
+ "component" = "cloudflare-issuer"
+ }
+ }
+ "spec" = {
+ "acme" = {
+ "email" = var.cloudflare_email
+ "server" = var.acme_server
+ "privateKeySecretRef" = {
+ "name" = var.cloudflare_issuer_name
+ }
+ "solvers" = [
+ {
+ "dns01" = {
+ "cloudflare" = {
+ "email" = var.cloudflare_email
+ "apiTokenSecretRef" = {
+ "name" = "cloudflare-token"
+ "key" = "cloudflare-token"
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+
+ depends_on = [kubernetes_secret.cloudflare_token]
+
+ wait {
+ condition {
+ type = "Ready"
+ status = "True"
+ }
+ }
+
+ timeouts {
+ create = "5m"
+ update = "5m"
+ delete = "5m"
+ }
+}
+
+// Certificate to be used for MongoExpress Ingress
+resource "kubernetes_manifest" "ingress_certificate" {
+
+ manifest = {
+ "apiVersion" = "cert-manager.io/v1"
+ "kind" = "Certificate"
+ "metadata" = {
+ "name" = var.ingress_certificate_name
+ "namespace" = kubernetes_namespace.namespace.metadata[0].name
+ "labels" = {
+ "app" = var.app_name
+ "component" = "ingress-certificate"
+ }
+ }
+ "spec" = {
+ "duration" = "2160h"
+ "renewBefore" = "360h"
+ "subject" = {
+ "organizations" = [var.organization_name]
+ "countries" = [var.country_name]
+ "organizationalUnits" = [var.app_name]
+ }
+ "privateKey" = {
+ "algorithm" = "RSA"
+ "encoding" = "PKCS1"
+ "size" = "2048"
+ }
+ "dnsNames" = ["${var.host_name}.${var.domain}"]
+ "secretName" = var.ingress_certificate_name
+ "issuerRef" = {
+ "name" = kubernetes_manifest.public_issuer.manifest.metadata.name
+ "kind" = "Issuer"
+ "group" = "cert-manager.io"
+ }
+ }
+ }
+
+ wait {
+ condition {
+ type = "Ready"
+ status = "True"
+ }
+ }
+
+ timeouts {
+ create = "5m"
+ update = "5m"
+ delete = "5m"
+ }
+}
diff --git a/modules/ferretdb/ferret.tf b/modules/ferretdb/ferret.tf
index 082e89b..34e8749 100644
--- a/modules/ferretdb/ferret.tf
+++ b/modules/ferretdb/ferret.tf
@@ -58,7 +58,7 @@ resource "kubernetes_deployment" "ferretdb" {
container {
name = "ferret"
- image = "ghcr.io/ferretdb/ferretdb:2.7.0"
+ image = "${var.repository}/${var.image}:${var.tag}"
port {
container_port = 27017
diff --git a/modules/ferretdb/ingress.tf b/modules/ferretdb/ingress.tf
new file mode 100644
index 0000000..b72eb01
--- /dev/null
+++ b/modules/ferretdb/ingress.tf
@@ -0,0 +1,44 @@
+// Kubernetes Ingress for Mongo Express Access
+resource "kubernetes_ingress_v1" "mongo_express_ingress" {
+ metadata {
+ name = "mongo-express-ingress"
+ namespace = kubernetes_namespace.namespace.metadata[0].name
+ labels = {
+ app = var.app_name
+ component = "ingress"
+ }
+ annotations = {
+ "nginx.ingress.kubernetes.io/proxy-ssl-verify" : "on"
+ "nginx.ingress.kubernetes.io/proxy-ssl-secret" : "${kubernetes_namespace.namespace.metadata[0].name}/${kubernetes_manifest.mongo_express_internal_certificate.manifest.spec.secretName}"
+ "nginx.ingress.kubernetes.io/proxy-ssl-name" : "database.${kubernetes_namespace.namespace.metadata[0].name}.svc.cluster.local"
+ "nginx.ingress.kubernetes.io/backend-protocol" : "HTTPS"
+ "nginx.ingress.kubernetes.io/rewrite-target" : "/"
+ "nginx.ingress.kubernetes.io/proxy-body-size" : 0
+ "nginx.ingress.kubernetes.io/client-body-buffer-size" : "500M"
+ }
+ }
+
+ spec {
+ ingress_class_name = "nginx"
+ tls {
+ hosts = ["${var.host_name}.${var.domain}"]
+ secret_name = kubernetes_manifest.ingress_certificate.manifest.spec.secretName
+ }
+ rule {
+ host = "${var.host_name}.${var.domain}"
+ http {
+ path {
+ path = "/"
+ backend {
+ service {
+ name = kubernetes_service.mongo_express.metadata[0].name
+ port {
+ name = "https"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/modules/ferretdb/mongo-express.tf b/modules/ferretdb/mongo-express.tf
new file mode 100644
index 0000000..75e0301
--- /dev/null
+++ b/modules/ferretdb/mongo-express.tf
@@ -0,0 +1,192 @@
+resource "kubernetes_deployment" "mongo_express" {
+ metadata {
+ name = "mongo-express"
+ namespace = kubernetes_namespace.namespace.metadata[0].name
+ }
+
+ spec {
+ replicas = 1
+ selector {
+ match_labels = {
+ "ferret-mongo-access" = true
+ app = var.app_name
+ component = "pod"
+ used-for = "mongo-express"
+ }
+ }
+
+ template {
+ metadata {
+ labels = {
+ "ferret-mongo-access" = true
+ app = var.app_name
+ component = "pod"
+ used-for = "mongo-express"
+ }
+ }
+
+ spec {
+ // Node Affinity rule to run only on worker nodes
+ affinity {
+ node_affinity {
+ required_during_scheduling_ignored_during_execution {
+ node_selector_term {
+ match_expressions {
+ key = "worker"
+ operator = "Exists"
+ }
+ }
+ }
+ }
+ }
+
+ // Topology Spread to ensure pods are running on seperate nodes
+ topology_spread_constraint {
+ max_skew = 1
+ topology_key = "kubernetes.io/hostname"
+ when_unsatisfiable = "DoNotSchedule"
+ label_selector {
+ match_labels = {
+ app = var.app_name
+ component = "pod"
+ "part-of" = "ferretdb"
+ }
+ }
+ }
+
+ container {
+ name = "mongo-express"
+ image = "${var.mongo_express_repository}/${var.mongo_express_image}:${var.mongo_express_tag}"
+
+ // FerretDB Connection Settings
+ env {
+ name = "DB_USERNAME"
+ value_from {
+ secret_key_ref {
+ name = kubernetes_secret.ferret_database_credentials.metadata[0].name
+ key = "username"
+ }
+ }
+ }
+
+ env {
+ name = "DB_PASSWORD"
+ value_from {
+ secret_key_ref {
+ name = kubernetes_secret.ferret_database_credentials.metadata[0].name
+ key = "password"
+ }
+ }
+ }
+
+ env {
+ name = "ME_CONFIG_MONGODB_URL"
+ value = "mongodb://$(DB_USERNAME):$(DB_PASSWORD)@${kubernetes_service.ferret_service.metadata[0].name}.${kubernetes_namespace.namespace.metadata[0].name}.svc.cluster.local:27017/ferret?authMechanism=SCRAM-SHA-256"
+ }
+
+ env {
+ name = "ME_CONFIG_MONGODB_ENABLE_ADMIN"
+ value = "true"
+ }
+
+ // UI Authentication for Mongo Express
+ env {
+ name = "ME_CONFIG_BASICAUTH_ENABLED"
+ value = "true"
+ }
+
+ env {
+ name = "ME_CONFIG_BASICAUTH_USERNAME"
+ value_from {
+ secret_key_ref {
+ name = kubernetes_secret.ui_credentials.metadata[0].name
+ key = "username"
+ }
+ }
+ }
+
+ env {
+ name = "ME_CONFIG_BASICAUTH_PASSWORD"
+ value_from {
+ secret_key_ref {
+ name = kubernetes_secret.ui_credentials.metadata[0].name
+ key = "password"
+ }
+ }
+ }
+
+ // SSL Configuration for Mongo Express
+ env {
+ name = "ME_CONFIG_SITE_SSL_ENABLED"
+ value = "true"
+ }
+
+ env {
+ name = "ME_CONFIG_SITE_SSL_CRT_PATH"
+ value = "/etc/mongoexpress/certs/tls.crt"
+ }
+
+ env {
+ name = "ME_CONFIG_SITE_SSL_KEY_PATH"
+ value = "/etc/mongoexpress/certs/tls.key"
+ }
+
+ port {
+ container_port = 8081
+ name = "mongoexpress"
+ }
+
+ resources {
+ requests = {
+ cpu = "250m"
+ memory = "256Mi"
+ }
+ limits = {
+ cpu = "500m"
+ memory = "500Mi"
+ }
+ }
+
+ liveness_probe {
+ http_get {
+ path = "/status"
+ port = 8081
+ scheme = "HTTPS"
+ }
+ initial_delay_seconds = 10
+ period_seconds = 10
+ success_threshold = 1
+ failure_threshold = 5
+ }
+
+ readiness_probe {
+ http_get {
+ path = "/status"
+ port = 8081
+ scheme = "HTTPS"
+ }
+ initial_delay_seconds = 10
+ period_seconds = 10
+ success_threshold = 1
+ failure_threshold = 5
+ }
+
+ volume_mount {
+ name = "tls-certs"
+ mount_path = "/etc/mongoexpress/certs"
+ read_only = true
+ }
+ }
+
+ volume {
+ name = "tls-certs"
+ secret {
+ secret_name = kubernetes_manifest.mongo_express_internal_certificate.manifest.spec.secretName
+ }
+ }
+ }
+ }
+ }
+
+ depends_on = [ kubernetes_deployment.ferretdb ]
+}
diff --git a/modules/ferretdb/secrets.tf b/modules/ferretdb/secrets.tf
index cdced90..64d8e74 100644
--- a/modules/ferretdb/secrets.tf
+++ b/modules/ferretdb/secrets.tf
@@ -88,3 +88,30 @@ resource "kubernetes_secret" "client_database_credentials" {
type = "kubernetes.io/basic-auth"
}
+
+// UI credentials configuration for MongoExpress
+resource "random_password" "ui_password" {
+ length = 20
+ lower = true
+ numeric = true
+ special = false
+}
+
+resource "kubernetes_secret" "ui_credentials" {
+ metadata {
+ name = "ui-ferret"
+ namespace = kubernetes_namespace.namespace.metadata[0].name
+
+ labels = {
+ app = var.app_name
+ component = "secret"
+ }
+ }
+
+ data = {
+ "username" = "ferret"
+ "password" = random_password.ferret_password.result
+ }
+
+ type = "kubernetes.io/basic-auth"
+}
diff --git a/modules/ferretdb/service.tf b/modules/ferretdb/service.tf
index 4492b9f..b16ca60 100644
--- a/modules/ferretdb/service.tf
+++ b/modules/ferretdb/service.tf
@@ -25,3 +25,31 @@ resource "kubernetes_service" "ferret_service" {
type = "ClusterIP"
}
}
+
+// Mongo Express Service for Ingress Usage
+resource "kubernetes_service" "mongo_express" {
+ metadata {
+ name = "mongo-express-service"
+ namespace = kubernetes_namespace.namespace.metadata[0].name
+ labels = {
+ app = var.app_name
+ component = "service"
+ }
+ }
+
+ spec {
+ type = "ClusterIP"
+
+ port {
+ port = 8081
+ target_port = 8081
+ name = "https"
+ }
+
+ selector = {
+ app = var.app_name
+ component = "pod"
+ used-for = "mongo-express"
+ }
+ }
+}
diff --git a/modules/ferretdb/variables.tf b/modules/ferretdb/variables.tf
index 0e5f454..3585df8 100644
--- a/modules/ferretdb/variables.tf
+++ b/modules/ferretdb/variables.tf
@@ -79,6 +79,47 @@ variable "client_streaming_replica_certificate_name" {
default = "ferretdb-streaming-replica-client-certificate"
}
+variable "cloudflare_token" {
+ description = "Token for generating Ingress Certificates to be associated with MongoExpress"
+ type = string
+ nullable = false
+}
+
+variable "cloudflare_email" {
+ description = "Email for generating Ingress Certificates to be associated with MongoExpress"
+ type = string
+ nullable = false
+}
+
+variable "cloudflare_issuer_name" {
+ description = "Name of the Cloudflare Issuer to be associated with MongoExpress"
+ type = string
+ default = "mongo-express-cloudflare-issuer"
+}
+
+variable "acme_server" {
+ description = "URL for the ACME Server to be used, defaults to production URL for LetsEncrypt"
+ type = string
+ default = "https://acme-v02.api.letsencrypt.org/directory"
+}
+
+variable "ingress_certificate_name" {
+ description = "Name of the Ingress Certificate to be associated with MongoExpress"
+ type = string
+ default = "mongo-express-ingress-certificate"
+}
+
+variable "host_name" {
+ description = "Host name for which Ingress Certificate is to be generated for"
+ type = string
+ default = "nosql"
+}
+
+variable "domain" {
+ description = "Domain for which Ingress Certificate is to be generated for"
+ type = string
+}
+
# --------------- USER CONFIGURATION VARIABLES --------------- #
variable "clients" {
description = "Object List of clients who need databases and users to be configured for"
@@ -120,6 +161,43 @@ variable "backup_bucket_name" {
nullable = false
}
+# --------------- FERRET DEPLOYMENT VARIABLES --------------- #
+variable "repository" {
+ description = "Repository to be used for deployment of FerretDB"
+ type = string
+ default = "ghcr.io/ferretdb"
+}
+
+variable "image" {
+ description = "Docker image to be used for deployment of FerretDB"
+ type = string
+ default = "ferretdb"
+}
+
+variable "tag" {
+ description = "Docker tag to be used for deployment of FerretDB"
+ type = string
+ default = "2.7.0"
+}
+
+variable "mongo_express_repository" {
+ description = "Repository to be used for deployment of Mongo Express UI"
+ type = string
+ default = "docker.io/library"
+}
+
+variable "mongo_express_image" {
+ description = "Docker image to be used for deployment of Mongo Express UI"
+ type = string
+ default = "mongo-express"
+}
+
+variable "mongo_express_tag" {
+ description = "Docker tag to be used for deployment of Mongo Express UI"
+ type = string
+ default = "1.0.2-20-alpine3.19"
+}
+
# --------------- NETWORK POLICY VARIABLES --------------- #
variable "kubernetes_api_ip" {
description = "IP Address for the Kubernetes API"