94 Commits
Author SHA1 Message Date
pierre.geeraert 891eb792c2 enable immich 2026-10-14 17:28:58 +01:00
pierre.geeraert 6cceced282 stash deployed 2026-10-14 17:20:37 +01:00
pierre.geeraert c8757429f7 enable wikijs 2026-10-14 17:19:40 +01:00
pi-ux-ce@ARES dca80eec1d enable wikijs 2026-10-14 17:18:39 +01:00
pierre.geeraert 08fa7ce92e typo 2026-10-14 16:57:03 +01:00
pierre.geeraert 94e042da92 missing bracket 2026-10-14 16:56:32 +01:00
pierre.geeraert 8da0085b99 enable wikijs 2026-10-14 16:55:26 +01:00
pierre.geeraert 6f3bedb6fa no need of these extra files 2026-10-14 16:39:59 +01:00
pierre.geeraert 4f2873b6c7 forgot to enable the replicas 2026-10-14 16:34:23 +01:00
pierre.geeraert 132b2de0ec no need to be exposed 2026-10-14 16:32:31 +01:00
pierre.geeraert f07d2b90ea enable gotenberg and tika 2026-10-14 16:31:23 +01:00
pierre.geeraert f106ad123e add paperless 2026-10-14 16:17:45 +01:00
pierre.geeraert 1d9e44b4ab fix stash 2026-10-14 16:16:36 +01:00
pierre.geeraert a1fbb90aba fix stash 2026-10-14 16:15:59 +01:00
pierre.geeraert c0c0c8e309 reformat 2026-10-14 16:13:11 +01:00
pierre.geeraert 7321c766f4 add paperless 2026-10-14 16:13:04 +01:00
pierre.geeraert 2771397993 prepare paperless but needs cleanup for the secret 2026-10-14 15:55:03 +01:00
pi-ux-ce@ARES e0d03891a2 test git hook 2026-10-14 15:48:18 +01:00
pi-ux-ce@ARES f3175d22a0 test git hook 2026-10-14 15:46:15 +01:00
pi-ux-ce@ARES b60ad2cacf fix merge 2026-10-14 15:43:42 +01:00
pi-ux-ce@ARES d709856523 test git hook 2026-10-14 15:42:41 +01:00
pierre.geeraert c8714b4831 add stash 2026-10-14 15:37:25 +01:00
pierre.geeraert a7408db1b5 delete healthcheck as not working 2026-10-14 15:34:58 +01:00
pierre.geeraert 88241a54e1 Middleware in version v1alpha1 cannot be handled as a Middleware: strict decoding error: unknown field spec.customResponse 2026-10-14 14:55:27 +01:00
pierre.geeraert a9792230c0 only one file allowed per manifest 2026-10-14 14:53:36 +01:00
pierre.geeraert 9e03fc0cc4 typo 2026-10-14 14:50:24 +01:00
pierre.geeraert d53e5f58dc typo 2026-10-14 14:50:01 +01:00
pierre.geeraert 4191a5a1c9 add middlewares for nextcloud 2026-10-14 14:49:09 +01:00
pi-ux-ce@ARES ba76aca41f nextcloud change 2026-10-14 14:42:12 +01:00
pi-ux-ce@ARES 0502a6189c old database with old path 2026-10-14 13:20:42 +01:00
pierre.geeraert 55cf6db9c8 nextcloud 2026-10-14 12:03:51 +01:00
pi-ux-ce@ARES 220efdda98 granular 2026-10-14 11:12:48 +01:00
pierre.geeraert fa384ba2b0 disbale all of them , will start them one by one 2026-10-14 11:11:00 +01:00
pi-ux-ce@ARES 019c557b9c moving bitwarden.tryton to bitwarden 2026-10-14 11:02:54 +01:00
pierre.geeraert 5dae1f5734 change the certificate for the ingress , otherwise 1 cert valid only for 1 url but only for the legacy one as it is the second one to be created , it overwrite 2026-10-14 10:49:08 +01:00
pi-ux-ce@ARES dfc1d80c50 moving bitwarden.tryton to bitwarden 2026-10-14 10:47:25 +01:00
pi-ux-ce@ARES 26f8b728a6 moving to the secret module 2026-10-14 10:39:31 +01:00
pi-ux-ce@ARES c7f4b46efa Merge branch 'restructure' of https://gitea.geeraert.eu/pi-ux-ce/Terraform_kube into restructure 2026-10-14 00:56:19 +01:00
pi-ux-ce@ARES 61245b8799 creds required 2026-10-14 00:55:42 +01:00
pierre geeraert 6c14bb15f1 fix redis typo 2026-10-14 00:54:11 +01:00
pierre geeraert 36869e060d wrong import 2026-10-14 00:47:42 +01:00
pierre geeraert 27c474fc5f wrong import 2026-10-14 00:46:19 +01:00
pierre geeraert 5c19f17a65 clsing brackets 2026-10-14 00:44:21 +01:00
pierre geeraert b48c17fc8c secret module + make things equal 2026-10-14 00:42:29 +01:00
pierre geeraert f8c9ffdb10 module deployment 2026-10-14 00:16:24 +01:00
pierre geeraert 28e8bc3fb4 module deployment 2026-10-14 00:15:57 +01:00
pierre geeraert fcf5730c7b module deployment 2026-10-14 00:14:34 +01:00
pierre geeraert 84c524fce6 module database 2026-10-14 00:05:23 +01:00
pierre geeraert 4155776c27 module database 2026-10-14 00:04:14 +01:00
pierre.geeraert 7553bcc923 reformat 2026-10-13 21:31:30 +01:00
pierre.geeraert b88864a731 not using gitea.tryton anymore 2026-10-13 19:02:08 +01:00
pierre.geeraert e21065a35c fix django secret missing 2026-10-13 19:00:00 +01:00
pierre.geeraert 40aa901a50 fix django secret missing 2026-10-13 18:58:38 +01:00
pierre.geeraert 147f862978 add import secrets 2026-10-13 18:49:36 +01:00
pi-ux-ce@ARES c9ade2f851 In your try() block, when the attribute doesn't exist, it correctly returns . However, when the attribute does exist, it returns the whole nested object (e.g., { host = ..., name = ... }). In Terraform, comparing a complex object/map to an empty string ({...} != ) is technically invalid or doesn't evaluate cleanly to a false check, causing the filter to let it slip through or crash when it expects a string. 2026-10-13 18:47:57 +01:00
pierre.geeraert aef087cfe1 enable more 2026-10-13 18:35:03 +01:00
pi-ux-ce@ARES ca989177da adding django and django-testing 2026-10-13 18:31:53 +01:00
pierre.geeraert 8848037c0f missed 2026-10-13 18:26:25 +01:00
pierre.geeraert a78a3c4e48 missed 2026-10-13 18:22:21 +01:00
pierre.geeraert 0fb7df60da cleanup incoming variables 2026-10-13 18:21:09 +01:00
pierre.geeraert ab4ef16a5e cleanup incoming variables 2026-10-13 18:18:06 +01:00
pierre.geeraert 51cef87475 ingress module 2026-10-13 18:12:14 +01:00
pierre.geeraert 23f59668a8 enable multiple domain name 2026-10-13 18:04:22 +01:00
pierre.geeraert 8002d9d0b7 ingress module 2026-10-13 18:00:23 +01:00
pierre.geeraert 243bd3a998 module service 2026-10-13 17:53:30 +01:00
pierre.geeraert 36d9421156 module service 2026-10-13 17:42:09 +01:00
pierre.geeraert 8e354b36b3 ingress module 2026-10-13 17:36:06 +01:00
pierre.geeraert e80f53c2e5 ingress module 2026-10-13 17:29:57 +01:00
pi-ux-ce@ARES c158dffcc9 beginning of modules 2026-10-13 17:26:10 +01:00
pierre.geeraert d7f6bc0869 cleanup 2026-10-13 16:18:28 +01:00
pierre.geeraert 56a02818cd cleanup 2026-10-13 16:15:59 +01:00
pierre.geeraert 6578e10274 bitwarden needs to expose 8080 not 5000 2026-10-13 14:55:42 +01:00
pierre.geeraert 6c2c971338 duplicate names 2026-10-13 14:52:29 +01:00
pierre.geeraert b4fdbccf98 add legacy domain support 2026-10-13 14:49:48 +01:00
pierre.geeraert 96236c6baf two ingress instead 2026-10-13 14:48:25 +01:00
pierre.geeraert bd2d151ebd disable reverse proxy and add extra site 2026-10-13 14:45:50 +01:00
pierre.geeraert dce7d02073 fix manifest and ingress 2026-10-13 13:49:34 +01:00
pierre.geeraert 763582404c fix changes 2026-10-13 13:35:02 +01:00
pierre.geeraert 22d22483b6 deploy clusterissuer 2026-10-13 13:33:38 +01:00
pierre.geeraert bdcc54d9b5 adding cert-manager helm chart 2026-10-13 11:55:56 +01:00
pi-ux-ce@ARES be06a539ea made some work on the ingress 2026-10-13 11:27:41 +01:00
pierre.geeraert a0d77cc2d6 auto create namespace 2026-10-13 08:53:57 +01:00
pierre.geeraert fe4f056c97 adding ingress helm 2026-10-13 08:51:12 +01:00
pierre.geeraert 086197f4f1 fix the misake 2026-10-12 19:45:31 +01:00
pierre.geeraert 591c1f83c4 fix the misake 2026-10-12 19:44:06 +01:00
pierre.geeraert 080eed640d fix the misake 2026-10-12 19:43:10 +01:00
pierre.geeraert 96bdb57a8e revert back the config file 2026-10-12 19:26:45 +01:00
pierre.geeraert a3adeb8406 try new method 2026-10-12 19:16:07 +01:00
pierre.geeraert 661ee11d6d big cleanup 2026-10-12 18:34:25 +01:00
pierre.geeraert 7f9bc2019d work on the reverse proxy 2026-10-12 18:24:51 +01:00
pierre.geeraert 9f872ebea0 cleanup 2026-10-12 18:14:23 +01:00
pierre.geeraert a69e4dd7a2 pvc.name not in use 2026-10-12 18:12:50 +01:00
pierre.geeraert 5f88c306a3 frogot the pvc part 2026-10-12 18:11:13 +01:00
pierre.geeraert fdba5cea6b forgot the pvc part 2026-10-12 18:08:07 +01:00
43 changed files with 1476 additions and 7571 deletions
+4
View File
@@ -0,0 +1,4 @@
module "Database-automatic" {
source = "../modules/database"
kubernetes_input = var.kubernetes
}
+15
View File
@@ -0,0 +1,15 @@
module "ingress" {
source = "../modules/ingress"
kubernetes_input = var.kubernetes
}
module "services" {
source = "../modules/services"
kubernetes_input = var.kubernetes
}
module "Deployment-automatic" {
source = "../modules/deployment"
kubernetes_input = var.kubernetes
}
+15 -937
View File
@@ -15,8 +15,8 @@ provider "kubernetes" {
provider "bitwarden-secrets" { provider "bitwarden-secrets" {
api_url = "https://bitwarden.tryton.geeraert.eu/api" api_url = "https://bitwarden.geeraert.eu/api"
identity_url = "https://bitwarden.tryton.geeraert.eu/identity" identity_url = "https://bitwarden.geeraert.eu/identity"
access_token = "0.9f4b7c5f-e6e7-4eff-929e-b474016a2b9c.bMRELajGGb7qMuXXvzgCCJdDfxfTCS:mFDT7tHSi43KJSnkwvTSYg==" access_token = "0.9f4b7c5f-e6e7-4eff-929e-b474016a2b9c.bMRELajGGb7qMuXXvzgCCJdDfxfTCS:mFDT7tHSi43KJSnkwvTSYg=="
organization_id = "a6361589-badd-4bde-9cb4-af8901161c0d" organization_id = "a6361589-badd-4bde-9cb4-af8901161c0d"
} }
@@ -26,7 +26,7 @@ variable "kubernetes" {
name = optional(string) name = optional(string)
image = string image = string
pvc = optional(map(object({ pvc = optional(map(object({
name = string name = optional(string)
pvc = optional(bool, false) pvc = optional(bool, false)
config_map = optional(bool, false) config_map = optional(bool, false)
secret = optional(bool, false) secret = optional(bool, false)
@@ -55,10 +55,13 @@ variable "kubernetes" {
service_port = optional(list(number)) service_port = optional(list(number))
service_type = optional(string, "ClusterIP") service_type = optional(string, "ClusterIP")
service_name = optional(string) service_name = optional(string)
domain_name = optional(string) domain_name = optional(list(string))
legacy_domain = optional(bool, false)
exposed = optional(bool, true)
liveness_tcp_socket = optional(number) liveness_tcp_socket = optional(number)
liveness_http_get = optional(string) liveness_http_get = optional(string)
liveness_http_get_path = optional(string) liveness_http_get_path = optional(string)
middlewares = optional(string)
database = optional(map(string)) database = optional(map(string))
database_command = optional(list(string)) database_command = optional(list(string))
database_args = optional(list(string)) database_args = optional(list(string))
@@ -80,77 +83,20 @@ variable "kubernetes" {
service_account_name = optional(string) service_account_name = optional(string)
environment_variables = optional(map(string), { name = "value" }) environment_variables = optional(map(string), { name = "value" })
security_context = optional(bool, false) 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" { resource "kubernetes_namespace_v1" "automatic" {
for_each = { for key, value in var.kubernetes : key => value if value.enabled == true && value.connected_namespace == "" } for_each = { for key, value in var.kubernetes : key => value if value.enabled == true && value.connected_namespace == "" }
@@ -163,7 +109,6 @@ resource "kubernetes_namespace_v1" "automatic" {
} }
name = coalesce(each.value.namespace, each.key) name = coalesce(each.value.namespace, each.key)
} }
depends_on = [data.kubernetes_all_namespaces.allns]
} }
locals { locals {
@@ -188,870 +133,3 @@ resource "kubernetes_manifest" "manifest" {
provider = kubernetes provider = kubernetes
} }
resource "kubernetes_persistent_volume_claim_v1" "automatic-pvc" {
for_each = { for key, value in local.pvc_details : "${value.index}" => merge(value, { mew_key = value.index }) if value.pvc && value.existing_pvc != true }
metadata {
namespace = coalesce(each.value.namespace, each.key)
name = "${each.value.name}-pvc"
labels = {
deployment_method = "Terraform"
}
annotations = {
fileType = try(each.value.annotations_fileType, "file")
}
}
spec {
access_modes = ["ReadWriteMany"]
storage_class_name = each.value.storage_class_name
resources {
requests = {
storage = each.value.pvc_size
}
}
}
}
resource "kubernetes_persistent_volume_claim_v1" "automatic-pvc-database" {
for_each = { for key, value in var.kubernetes : 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 = "${each.key}-db-pvc"
labels = {
deployment_method = "Terraform"
}
}
spec {
access_modes = ["ReadWriteMany"]
storage_class_name = "nfs-storage-intelligent"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_persistent_volume_claim_v1" "backup-pvc-database" {
for_each = { for key, value in var.kubernetes : key => value if value.database != null && value.enabled == true }
metadata {
namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key)
name = "${each.key}-db-backup"
labels = {
deployment_method = "Terraform"
}
annotations = {
fileType = "Backup" }
}
spec {
access_modes = ["ReadWriteMany"]
storage_class_name = "nfs-storage-fastaccess"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_persistent_volume_claim_v1" "automatic-pvc-redis" {
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 = "${each.key}-redis-pvc"
labels = {
deployment_method = "Terraform"
}
}
spec {
access_modes = ["ReadWriteMany"]
storage_class_name = "nfs-storage-intelligent"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_service_v1" "automatic_service" {
for_each = { for key, value in var.kubernetes : key => value if value.service_port != null && value.enabled == true }
metadata {
name = "${each.key}-svc"
namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key)
labels = {
deployment_method = "Terraform"
}
annotations = each.value.service_type == "LoadBalancer" ? {
"metallb.universe.tf/ip-allocated-from-pool" = "first-pool"
} : {}
}
spec {
selector = {
app = each.key
}
dynamic "port" {
for_each = each.value.service_port != null ? each.value.service_port : []
content {
port = port.value
target_port = port.value
name = replace("${port.value}${each.key}", "/(.{0,15})(.*)/", "$1")
}
}
# port {
# port = each.value.service_port
# target_port = each.value.service_port
# }
type = each.value.service_type
}
}
resource "kubernetes_service_v1" "automatic_service_database" {
for_each = { for key, value in var.kubernetes : key => value if value.database != null && value.enabled == true && !(try(value.database.shunt, false)) }
metadata {
name = "${each.key}-db-svc"
namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key)
labels = {
deployment_method = "Terraform"
#username = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_password[each.key].key}"
}
}
spec {
selector = {
app = "${each.key}-db"
}
port {
port = try(each.value.database.port, 5432)
target_port = try(each.value.database.port, 5432)
}
}
}
resource "kubernetes_service_v1" "automatic_service_redis" {
for_each = { for key, value in var.kubernetes : key => value if value.redis != null && value.enabled == true }
metadata {
name = "${each.key}-redis-svc"
namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key)
labels = {
deployment_method = "Terraform"
}
}
spec {
selector = {
app = "${each.key}-redis"
}
port {
port = 6379
target_port = 6379
}
}
}
resource "kubernetes_deployment_v1" "automatic" {
for_each = { for key, value in var.kubernetes : key => value if value.enabled == true }
metadata {
namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key)
name = coalesce(each.value.name, each.key)
labels = {
app = each.key
deployment_method = "Terraform"
}
}
spec {
replicas = each.value.replicas
selector {
match_labels = {
app = each.key
}
}
template {
metadata {
labels = {
app = each.key
deployment_method = "Terraform"
}
}
spec {
container {
image = each.value.image
name = coalesce(each.value.name, each.key)
dynamic "port" {
for_each = each.value.service_port != null ? each.value.service_port : []
content {
container_port = port.value
# name = "${each.key}-${port.value}"
name = replace("${port.value}${each.key}", "/(.{0,15})(.*)/", "$1")
}
}
dynamic "volume_mount" {
for_each = each.value.pvc != null ? each.value.pvc : {}
content {
mount_path = volume_mount.value.mount_path
name = "${volume_mount.value.name}-pvc"
sub_path = volume_mount.value.sub_path != null ? volume_mount.value.sub_path : ""
}
}
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"
}
}
dynamic "env_from" {
for_each = each.value.secret_ref != null ? each.value.secret_ref : []
content {
dynamic "secret_ref" {
for_each = [1]
content {
name = env_from.value
}
}
}
}
dynamic "env_from" {
for_each = each.value.database != null && each.value.enabled == true && !(try(each.value.database.shunt, false)) ? ["${each.key}-db-terraform"] : []
#for_each = each.value.database != null && each.value.enabled == true ? ["${each.key}-db-terraform"] : []
content {
dynamic "secret_ref" {
for_each = [1]
content {
name = env_from.value
}
}
}
}
dynamic "env_from" {
for_each = each.value.database != null && each.value.enabled == true ? ["${each.key}-db-mapped-terraform"] : []
content {
dynamic "secret_ref" {
for_each = [1]
content {
name = env_from.value
}
}
}
}
dynamic "env_from" {
for_each = each.value.config_map_ref != null ? each.value.config_map_ref : []
content {
dynamic "config_map_ref" {
for_each = [1]
content {
name = env_from.value
}
}
}
}
command = each.value.command != null ? each.value.command : []
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
}
}
}
}
}
}
dynamic "resources" {
for_each = each.value.requirements != null ? [1] : []
content {
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 "security_context" {
for_each = each.value.security_context == true ? [1] : []
content {
privileged = true
#capabilities = {
# add : ["NET_ADMIN", "NET_RAW"]
#}
}
}
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
}
}
}
dynamic "dns_config" {
for_each = each.value.dns_nameservers != null ? [1] : []
content {
nameservers = [each.value.dns_nameservers]
}
}
service_account_name = each.value.service_account_name != null ? each.value.service_account_name : null
dynamic "volume" {
for_each = each.value.pvc != null ? each.value.pvc : {}
content {
name = "${volume.value.name}-pvc"
dynamic "persistent_volume_claim" {
for_each = volume.value.pvc ? [1] : []
content {
claim_name = "${volume.value.name}-pvc"
}
}
dynamic "config_map" {
for_each = volume.value.config_map ? [1] : []
content {
name = volume.value.name
}
}
dynamic "host_path" {
for_each = volume.value.host_path != null ? [1] : []
content {
path = volume.value.host_path
}
}
dynamic "secret" {
for_each = volume.value.secret ? [1] : []
content {
secret_name = volume.value.name
}
}
}
}
dynamic "volume" {
for_each = try(each.value.database.engine == "sqlserver", false) && try(each.value.database.shunt, false) ? [1] : []
content {
name = "${each.key}-db-backup"
persistent_volume_claim {
claim_name = "${each.key}-db-backup"
}
}
}
}
}
}
depends_on = [kubernetes_persistent_volume_claim_v1.automatic-pvc]
}
resource "kubernetes_deployment_v1" "database-automatic" {
for_each = { for key, value in var.kubernetes : 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-pvc"
}
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
# optional = true
}
}
}
}
}
}
}
volume {
name = "${each.key}-db-pvc"
persistent_volume_claim {
claim_name = "${each.key}-db-pvc"
}
}
dynamic "volume" {
for_each = try(each.value.database.engine == "sqlserver", false) && !(try(each.value.database.shunt, false)) ? [1] : []
content {
name = "${each.key}-db-backup"
persistent_volume_claim {
claim_name = "${each.key}-db-backup"
}
}
}
}
}
}
}
resource "kubernetes_cron_job_v1" "database-backup" {
for_each = { for key, value in var.kubernetes : 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"
persistent_volume_claim {
claim_name = "${each.key}-db-backup"
}
}
}
}
}
}
}
}
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"
}
}
}
}
}
}
resource "kubernetes_config_map_v1" "automatic-configmap" {
metadata {
name = "extra-sites-terraform"
namespace = "reverse-proxy"
annotations = {
"reloader.stakater.com/match" : "true",
}
}
data = {
for key, value in var.kubernetes :
"${value.domain_name}.conf" => templatefile("nginx_config.tftpl", {
name_site = value.domain_name
name_service = "${key}-svc.${coalesce(value.namespace, value.connected_namespace, key)}.svc:${value.service_port.0}"
}) if value.domain_name != null && value.enabled == true
}
}
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)
}
+3 -52
View File
@@ -1,56 +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" { module "Redis-automatic" {
for_each = { for key, value in var.kubernetes : key => value if value.redis != null && value.enabled == true } source = "../modules/redis"
key = "${each.key}__redis__REPLICATION_MODE" kubernetes_input = var.kubernetes
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}"
}
} }
+4
View File
@@ -0,0 +1,4 @@
module "Secrets-automatic" {
source = "../modules/secrets"
kubernetes_input = var.kubernetes
}
+67 -256
View File
@@ -1,10 +1,9 @@
kubernetes = { kubernetes = {
bookstack = { bookstack = {
#enabled = false enabled = false
replicas = 01 replicas = 01
image = "linuxserver/bookstack:latest" image = "linuxserver/bookstack:latest"
service_port = [80, 443] service_port = [80, 443]
domain_name = "bookstack"
database = { database = {
"engine" = "mysql" "engine" = "mysql"
"image" = "lscr.io/linuxserver/mariadb" "image" = "lscr.io/linuxserver/mariadb"
@@ -100,7 +99,6 @@ kubernetes = {
enabled = false enabled = false
name = "stirling-pdf" name = "stirling-pdf"
image = "stirlingtools/stirling-pdf:2.0.0" image = "stirlingtools/stirling-pdf:2.0.0"
domain_name = "stirling"
service_port = [8080] service_port = [8080]
environment = { environment = {
@@ -131,13 +129,11 @@ kubernetes = {
stash = { stash = {
# enabled = false #enabled = false
replicas = 0 replicas = 0
name = "stash" name = "stash"
#image = "stashapp/stash:latest"
image = "stashapp/stash:v0.30.1" image = "stashapp/stash:v0.30.1"
service_port = [9999] service_port = [9999]
#extra_manifest = ["/opt/kubernetes/Terraform_kube/external_manifests/stash/stash-reddit-dowloader.configmap.yml"]
environment = { environment = {
STASH_STASH = { STASH_STASH = {
value = "/data/" value = "/data/"
@@ -163,28 +159,16 @@ kubernetes = {
} }
pvc = { pvc = {
data = { data = {
name = "data" mount_path = "/data"
pvc_size = "100Mi" host_path = "/ssd/stash/data-pvc/"
pvc = true
mount_path = "/data"
storage_class_name = "nfs-storage-fastaccess"
} }
metadata = { metadata-pvc = {
name = "metadata"
pvc_size = "100Mi"
pvc = true
mount_path = "/metadata" mount_path = "/metadata"
} }
generated = { generated-pvc = {
name = "generated"
pvc_size = "100Mi"
pvc = true
mount_path = "/generated" mount_path = "/generated"
} }
config = { config-pvc = {
name = "config"
pvc_size = "100Mi"
pvc = true
mount_path = "/root/.stash" mount_path = "/root/.stash"
} }
} }
@@ -195,7 +179,6 @@ kubernetes = {
onitama = { onitama = {
enabled = false enabled = false
namespace = "onitama" namespace = "onitama"
domain_name = "onitama"
image = "ghcr.io/jackadamson/onitama:latest" image = "ghcr.io/jackadamson/onitama:latest"
service_port = [8080] service_port = [8080]
requirements = { requirements = {
@@ -337,52 +320,19 @@ kubernetes = {
paperless = { paperless = {
#enabled = false #enabled = false
#namespace = "paper"
#replicas = 0
image = "ghcr.io/paperless-ngx/paperless-ngx:2.18.4" image = "ghcr.io/paperless-ngx/paperless-ngx:2.18.4"
service_port = [8000] service_port = [8000]
domain_name = "paperless2"
database = { database = {
image = "postgres:15.6" image = "postgres:15.6"
mountPath = "/var/lib/postgresql/data" mountPath = "/var/lib/postgresql/data"
} }
redis = { redis = {
image = "redis:7.4.1" } image = "redis:7.4.1"
#requirements = { }
# limits-cpu = "800m" secret_ref = ["paperless-credentials"]
# limits-memory = "800Mi" secret_import = ["a4d00a05-fe57-4aea-b935-b4e300f9a633"]
# requests-cpu = "10m"
# requests-memory = "300Mi"
#}
extra_manifest = ["/opt/kubernetes/Terraform_kube/external_manifests/paperless/Paperless.secret.yaml"]
#config_map_ref = ["config"]
environment = { environment = {
POSTGRES_DB = {
value_from = {
secret_key_ref = {
name = "paperless-credentials"
key = "POSTGRES_DB"
}
}
}
POSTGRES_USER = {
value_from = {
secret_key_ref = {
name = "paperless-credentials"
key = "POSTGRES_USER"
}
}
}
POSTGRES_PASSWORD = {
value_from = {
secret_key_ref = {
name = "paperless-credentials"
key = "POSTGRES_PASSWORD"
}
}
}
PAPERLESS_URL = { PAPERLESS_URL = {
value = "https://paperless.geeraert.eu" value = "https://paperless.geeraert.eu"
} }
@@ -395,81 +345,50 @@ kubernetes = {
PAPERLESS_TIKA_ENDPOINT = { PAPERLESS_TIKA_ENDPOINT = {
value = "http://tika-svc.paperless.svc:9998" value = "http://tika-svc.paperless.svc:9998"
} }
PAPERLESS_DBHOST = { PAPERLESS_DBHOST = {
value_from = { value_from = {
secret_key_ref = { secret_key_ref = {
name = "paperless-credentials" name = "paperless-db-terraform"
key = "POSTGRES_HOST" key = "POSTGRES_HOST"
} }
} }
} }
PAPERLESS_REDIS = { PAPERLESS_REDIS = {
value = "redis://paperless-redis-svc:6379" value = "redis://paperless-redis-svc:6379"
} }
PAPERLESS_ADMIN_USER = {
value_from = {
secret_key_ref = {
name = "paperless-credentials"
key = "POSTGRES_USER"
}
}
}
PAPERLESS_ADMIN_PASSWORD = {
value_from = {
secret_key_ref = {
name = "paperless-credentials"
key = "POSTGRES_PASSWORD"
}
}
}
# PAPERLESS_ADMIN_USER = {
# value = "admin"
# }
# PAPERLESS_ADMIN_PASSWORD = {
# value = "admin"
# }
PAPERLESS_OCR_USER_ARGS = { PAPERLESS_OCR_USER_ARGS = {
value = "{'invalidate_digital_signatures': true}" value = "{'invalidate_digital_signatures': true}"
} }
} }
pvc = { pvc = {
paperless-data = { paperless-data-pvc = {
pvc = true
name = "paperless-data" name = "paperless-data"
pvc_size = "2Mi"
mount_path = "/usr/src/paperless/data" mount_path = "/usr/src/paperless/data"
} }
paperless-media = { paperless-media-pvc = {
pvc = true
name = "paperless-media" name = "paperless-media"
pvc_size = "2Mi"
mount_path = "/usr/src/paperless/media" mount_path = "/usr/src/paperless/media"
} }
# export = { consume-pvc = {
# host_path = "/tmp"
# name = "export"
# pvc_size = "2Mi"
# mount_path = "/usr/src/paperless/export"
# }
consume = {
pvc = true
name = "consume" name = "consume"
pvc_size = "2Mi"
mount_path = "/usr/src/paperless/consume" mount_path = "/usr/src/paperless/consume"
} }
} }
import_database_secret = {
host = "65cb674e-9f45-47db-973f-b3ed00b0f079"
name = "44458c8d-816d-459f-9cb8-b3ed00b6a11c"
password = "8d6923eb-17dd-4733-b957-b3ed00b0f14b"
port = "668265dd-b47a-4f84-b3ee-b3ed00b0f089"
username = "f50a7b15-d03e-4aa6-a2f2-b3ed00b0f0fc"
}
} }
gotenberg = { gotenberg = {
#enabled = false #enabled = false
name = "gotenberg" name = "gotenberg"
command = ["gotenberg", "--chromium-disable-javascript=true", "--chromium-allow-list=file:///tmp/.*", "--chromium-auto-start"] command = ["gotenberg", "--chromium-disable-javascript=true", "--chromium-allow-list=file:///tmp/.*", "--chromium-auto-start"]
connected_namespace = "paperless" connected_namespace = "paperless"
exposed = false
image = "gotenberg/gotenberg:8" image = "gotenberg/gotenberg:8"
#image = "gotenberg/gotenberg:7.4.3" #image = "gotenberg/gotenberg:7.4.3"
service_port = [3000] service_port = [3000]
@@ -529,6 +448,7 @@ kubernetes = {
#enabled = false #enabled = false
name = "tika" name = "tika"
connected_namespace = "paperless" connected_namespace = "paperless"
exposed = false
image = "docker.io/apache/tika:latest" image = "docker.io/apache/tika:latest"
service_port = [9998] service_port = [9998]
requirements = { requirements = {
@@ -587,58 +507,39 @@ kubernetes = {
nextcloud = { nextcloud = {
enabled = false image = "nextcloud:29.0.3-apache"
namespace = "next" domain_name = ["nextcloud"]
#replicas = 0 service_port = [80]
image = "nextcloud:29.0.3-apache" secret_ref = ["nextcloud-credentials"]
domain_name = "next" secret_import = ["b207c4b6-0489-4ab2-a032-b4a400a708e0"]
service_port = [80] extra_manifest = ["../external_manifests/nextcloud/nextcloud-caldav-redirect.yaml", "../external_manifests/nextcloud/nextcloud-carddav-redirect.yaml"]
#extra_manifest = ["/opt/kubernetes/Nextcloud_kube/next.secret.yaml"] middlewares = "kube-system-nextcloud-carddav-redirect@kubernetescrd,kube-system-nextcloud-caldav-redirect@kubernetescrd"
secret_ref = ["nextcloud-credentials"]
secret_import = ["b207c4b6-0489-4ab2-a032-b4a400a708e0"]
database = { database = {
image = "docker.io/library/postgres:14" } image = "docker.io/library/postgres:14"
mountPath = "/var/lib/postgresql/data"
}
redis = { redis = {
image = "docker.io/library/redis:7" } image = "docker.io/library/redis:7" }
#requirements = {
# limits-cpu = "800Mi"
# limits-memory = "800Mi"
# requests-cpu = "800Mi"
# requests-memory = "800Mi"
#}
environment = { environment = {
TRUSTED_PROXIES = { TRUSTED_PROXIES = {
value = "192.168.88.50 192.168.88.52" value = "192.168.88.50 192.168.88.52"
} }
OVERWRITECLIURL = { OVERWRITECLIURL = {
value = "https://next.geeraert.eu" value = "https://nextcloud.geeraert.eu"
} }
OVERWRITEPROTOCOL = { OVERWRITEPROTOCOL = {
value = "https" value = "https"
} }
NEXTCLOUD_TRUSTED_DOMAINS = { NEXTCLOUD_TRUSTED_DOMAINS = {
value = "next.geeraert.eu next.tryton.geeraert.eu 192.168.88.52" value = "nextcloud.geeraert.eu nextcloud.tryton.geeraert.eu 192.168.0.200"
} }
NEXTCLOUD_ADMIN_USER = {
value = "admin"
}
NEXTCLOUD_ADMIN_PASSWORD = {
value_from = {
secret_key_ref = {
name = "nextcloud-credentials"
key = "PI_USER_PASSWORD"
}
}
}
} }
pvc = { pvc = {
nextcloud-webserver = { nextcloud-webserver = {
name = "nextcloud-webserver" name = "nextcloud-webserver"
pvc_size = "2Mi"
pvc = true
mount_path = "/var/www/html" mount_path = "/var/www/html"
} }
} }
@@ -838,7 +739,7 @@ kubernetes = {
prowlarr = { prowlarr = {
# enabled = false enabled = false ##was enabled
image = "linuxserver/prowlarr:latest" image = "linuxserver/prowlarr:latest"
namespace = "servarr" namespace = "servarr"
#replicas = 0 #replicas = 0
@@ -911,7 +812,7 @@ kubernetes = {
} }
radarr = { radarr = {
#enabled = false enabled = false ##was enabled
image = "lscr.io/linuxserver/radarr:latest" image = "lscr.io/linuxserver/radarr:latest"
connected_namespace = "servarr" connected_namespace = "servarr"
#replicas = 0 #replicas = 0
@@ -954,7 +855,7 @@ kubernetes = {
sonarr = { sonarr = {
#enabled = false enabled = false ##was enabled
image = "lscr.io/linuxserver/sonarr:latest" image = "lscr.io/linuxserver/sonarr:latest"
connected_namespace = "servarr" connected_namespace = "servarr"
#replicas = 0 #replicas = 0
@@ -1029,7 +930,7 @@ kubernetes = {
} }
qbittorrent = { qbittorrent = {
#enabled = false enabled = false ##was enabled
image = "lscr.io/linuxserver/qbittorrent:latest" image = "lscr.io/linuxserver/qbittorrent:latest"
connected_namespace = "servarr" connected_namespace = "servarr"
service_port = [8080] service_port = [8080]
@@ -1075,13 +976,13 @@ kubernetes = {
flaresolverr = { flaresolverr = {
enabled = false ##was enabled
#image = "ghcr.io/flaresolverr/flaresolverr:latest" #image = "ghcr.io/flaresolverr/flaresolverr:latest"
image = "alexfozor/flaresolverr:pr-1300-experimental" image = "alexfozor/flaresolverr:pr-1300-experimental"
connected_namespace = "servarr" connected_namespace = "servarr"
#enabled = false image = "ghcr.io/flaresolverr/flaresolverr:latest"
image = "ghcr.io/flaresolverr/flaresolverr:latest" service_port = [8191]
service_port = [8191]
environment = { environment = {
PUID = { PUID = {
@@ -1142,10 +1043,8 @@ kubernetes = {
wikijs = { wikijs = {
#enabled = false #enabled = false
image = "ghcr.io/requarks/wiki:2.5" image = "ghcr.io/requarks/wiki:2.5"
service_port = [3000] service_port = [3000]
#domain_name = "wikijs"
extra_manifest = ["/opt/kubernetes/Terraform_kube/external_manifests/wikijs/wikijs-db.secret.yaml"]
database = { database = {
image = "postgres:17" image = "postgres:17"
name = "wiki" name = "wiki"
@@ -1165,36 +1064,10 @@ kubernetes = {
} }
DB_TYPE = { value = "postgres" } DB_TYPE = { value = "postgres" }
DB_PORT = { value = "5432" } DB_PORT = { value = "5432" }
POSTGRES_DB = {
value_from = {
secret_key_ref = {
name = "wikijs-db-credentials"
key = "DB_DATABASE"
}
}
}
POSTGRES_USER = {
value_from = {
secret_key_ref = {
name = "wikijs-db-credentials"
key = "DB_USER"
}
}
}
POSTGRES_PASSWORD = {
value_from = {
secret_key_ref = {
name = "wikijs-db-credentials"
key = "DB_PASS"
}
}
}
DB_NAME = { DB_NAME = {
value_from = { value_from = {
secret_key_ref = { secret_key_ref = {
name = "wikijs-db-credentials" name = "wikijs-db-terraform"
key = "DB_DATABASE" key = "DB_DATABASE"
} }
} }
@@ -1202,38 +1075,31 @@ kubernetes = {
DB_USER = { DB_USER = {
value_from = { value_from = {
secret_key_ref = { secret_key_ref = {
name = "wikijs-db-credentials" name = "wikijs-db-terraform"
key = "DB_USER" key = "DB_USERNAME"
} }
} }
} }
DB_PASS = { DB_PASS = {
value_from = { value_from = {
secret_key_ref = { secret_key_ref = {
name = "wikijs-db-credentials" name = "wikijs-db-terraform"
key = "DB_PASS" key = "DB_PASSWORD"
} }
} }
} }
DB_HOST = { import_database_secret = {
value_from = { host = "54ddb01c-94c7-46ad-a753-b3ed00b0f0bb"
secret_key_ref = { name = "ff2325ad-407f-460a-b087-b3ed00b6a13e"
name = "wikijs-db-credentials" password = "faabca95-dd65-40b1-bf96-b3ed00b0f11f"
key = "DB_HOST" port = "3fa80292-7164-4fd9-840c-b3ed00b0f0d5"
} username = "00435cc0-cd79-4524-bc10-b3ed00b0f041"
}
} }
} }
} }
immich = { immich = {
#enabled = false enabled = false ##was enabled
#replicas = 0 replicas = 0
connected_namespace = "immich"
image = "ghcr.io/immich-app/immich-server:v3.0.0" image = "ghcr.io/immich-app/immich-server:v3.0.0"
service_port = [2283] service_port = [2283]
database = { database = {
@@ -1249,72 +1115,27 @@ kubernetes = {
requests-cpu = "10m" requests-cpu = "10m"
requests-memory = "300Mi" requests-memory = "300Mi"
} }
extra_manifest = ["/opt/kubernetes/Terraform_kube/external_manifests/immich/immich-db.secret.yaml"]
environment = { environment = {
DB_DATABASE_NAME = {
value_from = {
secret_key_ref = {
name = "immich-db-credentials"
key = "DB_DATABASE_NAME"
}
}
}
DB_USERNAME = {
value_from = {
secret_key_ref = {
name = "immich-db-credentials"
key = "DB_USERNAME"
}
}
}
DB_PASSWORD = {
value_from = {
secret_key_ref = {
name = "immich-db-credentials"
key = "DB_PASSWORD"
}
}
}
POSTGRES_DATABASE = { POSTGRES_DATABASE = {
value_from = { value_from = {
secret_key_ref = { secret_key_ref = {
name = "immich-db-credentials" name = "immich-db-terraform"
key = "DB_DATABASE_NAME" key = "DB_DATABASE_NAME"
} }
} }
} }
POSTGRES_USER = {
value_from = {
secret_key_ref = {
name = "immich-db-credentials"
key = "DB_USERNAME"
}
}
}
POSTGRES_PASSWORD = {
value_from = {
secret_key_ref = {
name = "immich-db-credentials"
key = "DB_PASSWORD"
}
}
}
POSTGRES_POSTGRES_PASSWORD = { POSTGRES_POSTGRES_PASSWORD = {
value_from = { value_from = {
secret_key_ref = { secret_key_ref = {
name = "immich-db-credentials" name = "immich-db-terraform"
key = "DB_PASSWORD" key = "DB_PASSWORD"
} }
} }
} }
DB_HOSTNAME = { DB_HOSTNAME = {
value_from = { value_from = {
secret_key_ref = { secret_key_ref = {
name = "immich-db-credentials" name = "immich-db-terraform"
key = "DB_HOST" key = "DB_HOST"
} }
} }
@@ -1342,16 +1163,10 @@ kubernetes = {
} }
pvc = { pvc = {
immich-data = { immich-data = {
name = "immich-data"
pvc_size = "10Mi"
pvc = false
host_path = "/ssd/Image/immich/immich-storage-fastaccess" host_path = "/ssd/Image/immich/immich-storage-fastaccess"
mount_path = "/usr/src/app/upload" mount_path = "/usr/src/app/upload"
} }
stash-data = { stash-data = {
name = "stash-data"
pvc_size = "10Mi"
pvc = false
host_path = "/ssd/stash/data-pvc" host_path = "/ssd/stash/data-pvc"
mount_path = "/stash/" mount_path = "/stash/"
} }
@@ -1359,9 +1174,10 @@ kubernetes = {
} }
} }
machinelearning = { machinelearning = {
#enabled = false enabled = false ##was enabled
#replicas = 0 #replicas = 0
connected_namespace = "immich" connected_namespace = "immich"
exposed = false
image = "ghcr.io/immich-app/immich-machine-learning:v2.5.6" image = "ghcr.io/immich-app/immich-machine-learning:v2.5.6"
service_port = [3003] service_port = [3003]
environment = { environment = {
@@ -1935,7 +1751,6 @@ kubernetes = {
#disabled because it needs AI to import a pdf and AI integration is not working #disabled because it needs AI to import a pdf and AI integration is not working
enabled = false enabled = false
replicas = 01 replicas = 01
domain_name = "reactive"
image = "ghcr.io/amruthpillai/reactive-resume:latest" image = "ghcr.io/amruthpillai/reactive-resume:latest"
service_port = [3000] service_port = [3000]
environment = { environment = {
@@ -1968,7 +1783,6 @@ kubernetes = {
replicas = 01 replicas = 01
image = "opencloudeu/opencloud-rolling:latest" image = "opencloudeu/opencloud-rolling:latest"
service_port = [9200] service_port = [9200]
#domain_name = "opencloud"
environment = { environment = {
#IDM_CREATE_DEMO_USERS = { #IDM_CREATE_DEMO_USERS = {
@@ -2009,7 +1823,6 @@ kubernetes = {
replicas = 0 replicas = 0
image = "owncloud/server" image = "owncloud/server"
service_port = [8080] service_port = [8080]
domain_name = "owncloud"
database = { database = {
"engine" = "mysql" "engine" = "mysql"
"image" = "lscr.io/linuxserver/mariadb" "image" = "lscr.io/linuxserver/mariadb"
@@ -2065,7 +1878,6 @@ kubernetes = {
replicas = 01 replicas = 01
image = "kopia/kopia" image = "kopia/kopia"
service_port = [51515] service_port = [51515]
domain_name = "kopia"
command = ["start", "--disable-csrf-token-checks", "--insecure", "--address=0.0.0.0:51515", "--server-username=USERNAME", "--server-password=SECRET_PASSWORD"] command = ["start", "--disable-csrf-token-checks", "--insecure", "--address=0.0.0.0:51515", "--server-username=USERNAME", "--server-password=SECRET_PASSWORD"]
environment = { environment = {
KOPIA_PASSWORD = { KOPIA_PASSWORD = {
@@ -2096,7 +1908,6 @@ kubernetes = {
replicas = 01 replicas = 01
image = "ghcr.io/degoog-org/degoog:latest" image = "ghcr.io/degoog-org/degoog:latest"
service_port = [4444] service_port = [4444]
domain_name = "degoog"
environment = { environment = {
DEGOOG_SETTINGS_PASSWORDS = { DEGOOG_SETTINGS_PASSWORDS = {
value = "Crease1-City-Canned" value = "Crease1-City-Canned"
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -96,7 +96,7 @@ resource "kubernetes_deployment_v1" "database-automatic" {
name = "${each.key}-db-backup" name = "${each.key}-db-backup"
host_path { host_path {
path = join("/", [var.storage_path.fast_access,"Backup", coalesce(each.value.namespace, each.value.connected_namespace, each.key), "${each.key}-db-backup"]) path = join("/", [var.storage_path.fast_access, "Backup", coalesce(each.value.namespace, each.value.connected_namespace, each.key), "${each.key}-db-backup"])
} }
} }
} }
+1 -1
View File
@@ -198,7 +198,7 @@ resource "kubernetes_deployment_v1" "automatic" {
name = "${each.key}-db-backup" name = "${each.key}-db-backup"
host_path { host_path {
path = join("/", [var.storage_path.fast_access,"Backup", coalesce(each.value.namespace, each.value.connected_namespace, each.key), "${each.key}-db-backup"]) path = join("/", [var.storage_path.fast_access, "Backup", coalesce(each.value.namespace, each.value.connected_namespace, each.key), "${each.key}-db-backup"])
} }
} }
} }
+73
View File
@@ -0,0 +1,73 @@
resource "helm_release" "cert_manager" {
name = "cert-manager"
repository = "oci://quay.io"
chart = "jetstack/charts/cert-manager"
version = "v1.21.2"
namespace = "cert-manager"
create_namespace = true
wait = false
set = [
{
name = "crds.enabled"
value = "true"
}
]
}
resource "helm_release" "nginx_ingress" {
name = "traefik"
repository = "https://traefik.github.io/charts"
chart = "traefik"
version = "v41.7.1"
namespace = "traefik"
create_namespace = true
wait = false
set = [
{
name = "ports.web.nodePort"
value = "80"
},
{
name = "ports.websecure.nodePort"
value = "443"
},
{
name = "service.type"
value = "NodePort"
}
]
}
resource "kubernetes_manifest" "letsencrypt_prod" {
manifest = {
"apiVersion" = "cert-manager.io/v1"
"kind" = "ClusterIssuer"
"metadata" = {
"name" = "letsencrypt-prod"
}
"spec" = {
"acme" = {
"email" = "franckrobbin6@gmail.com"
"privateKeySecretRef" = {
"name" = "letsencrypt-prod-account-key"
}
"server" = "https://acme-v02.api.letsencrypt.org/directory"
"solvers" = [
{
"http01" = {
"ingress" = {
"class" = "traefik"
}
}
}
]
}
}
}
}
+8 -15
View File
@@ -15,6 +15,11 @@ provider "kubernetes" {
provider "docker" { provider "docker" {
host = "unix:///var/run/docker.sock" host = "unix:///var/run/docker.sock"
} }
provider "helm" {
kubernetes = {
config_path = "~/.kube/config"
}
}
variable "kubernetes" { variable "kubernetes" {
type = map(object({ type = map(object({
@@ -50,7 +55,9 @@ variable "kubernetes" {
external_port = optional(bool, false) external_port = optional(bool, false)
service_type = optional(string, "ClusterIP") service_type = optional(string, "ClusterIP")
service_name = optional(string) service_name = optional(string)
domain_name = optional(string) domain_name = optional(list(string))
legacy_domain = optional(bool, false)
exposed = optional(bool, true)
liveness_tcp_socket = optional(number) liveness_tcp_socket = optional(number)
liveness_http_get = optional(string) liveness_http_get = optional(string)
liveness_http_get_path = optional(string) liveness_http_get_path = optional(string)
@@ -86,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 { locals {
kubernetes_manifests = flatten([ kubernetes_manifests = flatten([
for k, obj in var.kubernetes : [ for k, obj in var.kubernetes : [
+4 -4
View File
@@ -44,7 +44,7 @@ resource "kubernetes_deployment_v1" "redis-automatic" {
volume_mount { volume_mount {
mount_path = "/data" mount_path = "/data"
name = "${each.key}-redis-pvc" name = "${each.key}-redis-volume"
} }
@@ -112,9 +112,9 @@ resource "kubernetes_deployment_v1" "redis-automatic" {
volume { volume {
name = "${each.key}-redis-pvc" name = "${each.key}-redis-volume"
persistent_volume_claim { host_path {
claim_name = "${each.key}-redis-pvc" 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"])]))
} }
} }
+6 -79
View File
@@ -1,88 +1,15 @@
resource "kubernetes_service_v1" "automatic_service" { module "ingress" {
for_each = { for key, value in var.kubernetes : key => value if value.service_port != null && value.enabled == true && value.docker != true } source = "../modules/ingress"
metadata { kubernetes_input = var.kubernetes
name = "${each.key}-svc"
namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key)
labels = {
deployment_method = "Terraform"
}
annotations = each.value.service_type == "LoadBalancer" ? {
"metallb.universe.tf/ip-allocated-from-pool" = "first-pool"
} : {}
}
spec {
selector = {
app = each.key
}
dynamic "port" {
for_each = each.value.service_port != null ? each.value.service_port : []
content {
port = port.value
target_port = port.value
name = replace("${port.value}${each.key}", "/(.{0,15})(.*)/", "$1")
node_port = each.value.service_type == "NodePort" ? port.value : 0
}
}
type = each.value.service_type
}
}
resource "kubernetes_service_v1" "automatic_service_database" {
for_each = { for key, value in var.kubernetes : key => value if value.database != null && value.enabled == true && !(try(value.database.shunt, false)) && value.docker != true }
metadata {
name = "${each.key}-db-svc"
namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key)
labels = {
deployment_method = "Terraform"
#username = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_password[each.key].key}"
}
}
spec {
selector = {
app = "${each.key}-db"
}
port {
port = try(each.value.database.port, 5432)
target_port = try(each.value.database.port, 5432)
}
}
} }
module "services" {
resource "kubernetes_service_v1" "automatic_service_redis" { source = "../modules/services"
for_each = { for key, value in var.kubernetes : key => value if value.redis != null && value.enabled == true && value.docker != true } kubernetes_input = var.kubernetes
metadata {
name = "${each.key}-redis-svc"
namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key)
labels = {
deployment_method = "Terraform"
}
}
spec {
selector = {
app = "${each.key}-redis"
}
port {
port = 6379
target_port = 6379
}
}
} }
resource "docker_network" "terraform_network" { resource "docker_network" "terraform_network" {
#avoiding this to create if the shunt_docker is on #avoiding this to create if the shunt_docker is on
count = var.shunt_docker ? 0 : 1 count = var.shunt_docker ? 0 : 1
View File
-33
View File
@@ -1,33 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
volumeMounts:
- name: data
mountPath: /hello
volumes:
- name: data
hostPath:
path: /data/kubernetes/degoog/degoog-data-pvc
type: DirectoryOrCreate
+41 -62
View File
@@ -1,41 +1,34 @@
kubernetes = { kubernetes = {
reverse-proxy = { echo = {
#enabled = false #enabled = false
#docker = true #docker = true
image = "nginx:latest" image = "ealen/echo-server:latest"
service_port = [80, 443] service_port = [4580]
service_type = "NodePort"
external_port = true external_port = true
service_type = "NodePort"
domain_name = ["echo", "hello"]
#command = ["-text=Hello authenticated world!"]
pvc = { pvc = {
nginx-sites-terraform = { echo-config = {
name = "nginx-sites-terraform" mount_path = "/app/configs"
mount_path = "/etc/nginx/conf.d/"
host_path = "/data/kubernetes/reverse-proxy/reverse-proxy-sites"
} }
echo-testing = {
reverse-proxy-log = { mount_path = "/app/test"
name = "reverse-proxy-log"
mount_path = "/var/log/nginx/"
host_path = "/data/kubernetes/reverse-proxy/reverse-proxy-log"
}
reverse-proxy-ssl = {
name = "reverse-proxy-ssl"
mount_path = "/etc/nginx/ssl/"
host_path = "/data/kubernetes/reverse-proxy/reverse-proxy-ssl"
}
nginx-configfile = {
name = "nginx-configfile"
mount_path = "/etc/nginx/nginx.conf"
host_path = "/data/kubernetes/reverse-proxy/reverse-proxy-configfile/nginx.conf"
} }
} }
environment = {
PORT = {
value = 4580
}
PAPERLESS_REDIS = {
value = "redis://paperless-redis-svc:6379"
}
database = {
value = "datgg"
}
}
} }
gitea = { gitea = {
#enabled = false #enabled = false
#docker = true #docker = true
@@ -78,6 +71,7 @@ kubernetes = {
#enabled = false #enabled = false
#docker = true #docker = true
image = "gitea/act_runner:latest" image = "gitea/act_runner:latest"
exposed = false
connected_namespace = "gitea" connected_namespace = "gitea"
environment = { environment = {
GITEA_INSTANCE_URL = { value = "https://gitea.geeraert.eu/" } GITEA_INSTANCE_URL = { value = "https://gitea.geeraert.eu/" }
@@ -100,35 +94,7 @@ kubernetes = {
} }
echo = {
#enabled = false
#docker = true
image = "ealen/echo-server:latest"
service_port = [4580]
external_port = true
service_type = "NodePort"
#command = ["-text=Hello authenticated world!"]
pvc = {
echo-config = {
mount_path = "/app/configs"
}
echo-testing = {
mount_path = "/app/test"
}
}
environment = {
PORT = {
value = 4580
}
PAPERLESS_REDIS = {
value = "redis://paperless-redis-svc:6379"
}
database = {
value = "datgg"
}
}
}
bitwarden-admin = { bitwarden-admin = {
@@ -137,8 +103,9 @@ kubernetes = {
replicas = 1 replicas = 1
name = "bitwarden-admin" name = "bitwarden-admin"
image = "ghcr.io/bitwarden/admin:2026.1.0" image = "ghcr.io/bitwarden/admin:2026.1.0"
extra_manifest = ["/opt/kubernetes/Terraform_kube/external_manifests/bitwarden/config.configmap.yml", "/opt/kubernetes/Terraform_kube/external_manifests/bitwarden/global.env.configmap.yml", "/opt/kubernetes/Terraform_kube/external_manifests/bitwarden/global.override.env.configmap.yml", "/opt/kubernetes/Terraform_kube/external_manifests/bitwarden/mssql.env.configmap.yml", "/opt/kubernetes/Terraform_kube/external_manifests/bitwarden/mssql.override.env.configmap.yml", "/opt/kubernetes/Terraform_kube/external_manifests/bitwarden/uid.env.configmap.yml", "/opt/kubernetes/Terraform_kube/external_manifests/bitwarden/bitwarden-identity-cert-password.secret.yml"] extra_manifest = ["../external_manifests/bitwarden/config.configmap.yml", "../external_manifests/bitwarden/global.env.configmap.yml", "../external_manifests/bitwarden/global.override.env.configmap.yml", "../external_manifests/bitwarden/mssql.env.configmap.yml", "../external_manifests/bitwarden/mssql.override.env.configmap.yml", "../external_manifests/bitwarden/uid.env.configmap.yml", "../external_manifests/bitwarden/bitwarden-identity-cert-password.secret.yml"]
service_port = [5000] service_port = [5000]
exposed = false
config_map_ref = ["global.env", "uid.env", "global.override.env"] config_map_ref = ["global.env", "uid.env", "global.override.env"]
environment = {} environment = {}
@@ -165,8 +132,9 @@ kubernetes = {
connected_namespace = "bitwarden" connected_namespace = "bitwarden"
replicas = 1 replicas = 1
name = "bitwarden-api" name = "bitwarden-api"
image = "gitea.tryton.geeraert.eu/pi-ux-ce/bitbetter_api:2026.1.0" image = "gitea.geeraert.eu/pi-ux-ce/bitbetter_api:2026.1.0"
service_port = [5000] service_port = [5000]
exposed = false
config_map_ref = ["global.env", "uid.env", "global.override.env"] config_map_ref = ["global.env", "uid.env", "global.override.env"]
environment = {} environment = {}
@@ -194,6 +162,7 @@ kubernetes = {
name = "bitwarden-attachments" name = "bitwarden-attachments"
image = "ghcr.io/bitwarden/attachments:2026.1.0" image = "ghcr.io/bitwarden/attachments:2026.1.0"
service_port = [5000] service_port = [5000]
exposed = false
config_map_ref = ["global.env", "uid.env"] config_map_ref = ["global.env", "uid.env"]
environment = {} environment = {}
@@ -212,6 +181,7 @@ kubernetes = {
name = "bitwarden-events" name = "bitwarden-events"
image = "ghcr.io/bitwarden/events:2026.1.0" image = "ghcr.io/bitwarden/events:2026.1.0"
service_port = [5000] service_port = [5000]
exposed = false
config_map_ref = ["global.env", "uid.env", "global.override.env"] config_map_ref = ["global.env", "uid.env", "global.override.env"]
environment = {} environment = {}
@@ -234,6 +204,7 @@ kubernetes = {
name = "bitwarden-icons" name = "bitwarden-icons"
image = "ghcr.io/bitwarden/icons:2026.1.0" image = "ghcr.io/bitwarden/icons:2026.1.0"
service_port = [5000] service_port = [5000]
exposed = false
config_map_ref = ["global.env", "uid.env"] config_map_ref = ["global.env", "uid.env"]
environment = {} environment = {}
@@ -253,8 +224,9 @@ kubernetes = {
connected_namespace = "bitwarden" connected_namespace = "bitwarden"
replicas = 1 replicas = 1
name = "bitwarden-identity" name = "bitwarden-identity"
image = "gitea.tryton.geeraert.eu/pi-ux-ce/bitbetter_identity:2026.1.0" image = "gitea.geeraert.eu/pi-ux-ce/bitbetter_identity:2026.1.0"
service_port = [5000] service_port = [5000]
exposed = false
config_map_ref = ["global.env", "uid.env", "global.override.env"] config_map_ref = ["global.env", "uid.env", "global.override.env"]
environment = {} environment = {}
@@ -282,6 +254,7 @@ kubernetes = {
name = "bitwarden-mssql" name = "bitwarden-mssql"
image = "ghcr.io/bitwarden/mssql:2026.1.0" image = "ghcr.io/bitwarden/mssql:2026.1.0"
service_port = [1433, 5000] service_port = [1433, 5000]
exposed = false
config_map_ref = ["mssql.env", "uid.env", "mssql.override.env"] config_map_ref = ["mssql.env", "uid.env", "mssql.override.env"]
environment = {} environment = {}
database = { database = {
@@ -309,7 +282,10 @@ kubernetes = {
replicas = 1 replicas = 1
name = "bitwarden-nginx" name = "bitwarden-nginx"
image = "ghcr.io/bitwarden/nginx:2026.1.0" image = "ghcr.io/bitwarden/nginx:2026.1.0"
service_port = [5000, 8080, 8443] service_port = [8080, 5000, 8443]
exposed = true #no need to set as true but I did it for easy access
legacy_domain = true
domain_name = ["bitwarden"]
config_map_ref = ["uid.env"] config_map_ref = ["uid.env"]
environment = {} environment = {}
@@ -337,6 +313,7 @@ kubernetes = {
name = "bitwarden-notifications" name = "bitwarden-notifications"
image = "ghcr.io/bitwarden/notifications:2026.1.0" image = "ghcr.io/bitwarden/notifications:2026.1.0"
service_port = [5000] service_port = [5000]
exposed = false
config_map_ref = ["global.env", "uid.env", "global.override.env"] config_map_ref = ["global.env", "uid.env", "global.override.env"]
environment = {} environment = {}
@@ -358,6 +335,7 @@ kubernetes = {
name = "bitwarden-sso" name = "bitwarden-sso"
image = "ghcr.io/bitwarden/sso:2026.1.0" image = "ghcr.io/bitwarden/sso:2026.1.0"
service_port = [5000] service_port = [5000]
exposed = false
config_map_ref = ["global.env", "uid.env", "global.override.env"] config_map_ref = ["global.env", "uid.env", "global.override.env"]
environment = {} environment = {}
@@ -384,6 +362,7 @@ kubernetes = {
name = "bitwarden-web" name = "bitwarden-web"
image = "ghcr.io/bitwarden/web:2026.1.0" image = "ghcr.io/bitwarden/web:2026.1.0"
service_port = [5000] service_port = [5000]
exposed = false
config_map_ref = ["global.env", "uid.env"] config_map_ref = ["global.env", "uid.env"]
environment = {} environment = {}
@@ -2,7 +2,7 @@ apiVersion: v1
data: data:
ACCEPT_EULA: "Y" ACCEPT_EULA: "Y"
adminSettings__admins: pierre@geeraert.eu adminSettings__admins: pierre@geeraert.eu
globalSettings__baseServiceUri__vault: http://bitwarden.tryton.geeraert.eu globalSettings__baseServiceUri__vault: http://bitwarden.geeraert.eu
globalSettings__disableUserRegistration: "false" globalSettings__disableUserRegistration: "false"
globalSettings__duo__aKey: p9jCHtnG4NZNZu4SThpVlCuOF1oePGhu53Wa4RJwuyeqRAWQ0aJN7GsKYrGbYIYO globalSettings__duo__aKey: p9jCHtnG4NZNZu4SThpVlCuOF1oePGhu53Wa4RJwuyeqRAWQ0aJN7GsKYrGbYIYO
globalSettings__hibpApiKey: REPLACE globalSettings__hibpApiKey: REPLACE
@@ -1,10 +0,0 @@
apiVersion: v1
data:
DB_DATABASE_NAME: aW1taWNo
DB_HOST: aW1taWNoLWRiLXN2Yw==
DB_PASSWORD: U3Bvb24tQm9yb3VnaC1CYXNpczg=
DB_USERNAME: aW1taWNo
kind: Secret
metadata:
name: immich-db-credentials
namespace: immich
@@ -0,0 +1,10 @@
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: nextcloud-caldav-redirect
namespace: kube-system
spec:
redirectRegex:
regex: "^https://(.*)/\\.well-known/caldav"
replacement: "https://$1/remote.php/dav"
permanent: true
@@ -0,0 +1,10 @@
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: nextcloud-carddav-redirect
namespace: kube-system # Recommended to put global middlewares in kube-system or a shared ingress namespace
spec:
redirectRegex:
regex: "^https://(.*)/\\.well-known/carddav"
replacement: "https://$1/remote.php/dav"
permanent: true
@@ -1,13 +0,0 @@
apiVersion: v1
data:
POSTGRES_DB: cGFwZXJsZXNz
POSTGRES_USER: cGFwZXJsZXNz
POSTGRES_PASSWORD: cGFwZXJsZXNz
PAPERLESS_ADMIN_USER: YWRtaW4=
PAPERLESS_ADMIN_PASSWORD: YWRtaW4=
POSTGRES_HOST: cGFwZXJsZXNzLWRiLXN2Yw==
kind: Secret
metadata:
name: paperless-credentials
namespace: paperless
type: Opaque
@@ -1,5 +0,0 @@
[IMAP-1993]
documentation = *** note: this server will work for both Office 365 and personal Outlook/Hotmail accounts ***
server_address = outlook.office365.com
server_port = 993
local_address = 127.0.0.1
@@ -1,13 +0,0 @@
apiVersion: v1
data:
emailproxy.config: |
[IMAP-1993]
documentation = *** note: this server will work for both Office 365 and personal Outlook/Hotmail accounts ***
server_address = outlook.office365.com
server_port = 993
local_address = 127.0.0.1
kind: ConfigMap
metadata:
creationTimestamp: null
name: emailproxyconfig
namespace: paperless
@@ -1,45 +0,0 @@
apiVersion: batch/v1
kind: CronJob
metadata:
name: paperless-calendar-backup
namespace: paperless
spec:
schedule: "0 0 * * *"
jobTemplate:
spec:
backoffLimit: 4
ttlSecondsAfterFinished: 100
template:
spec:
containers:
- name: paperless-database-backup
image: alpine/psql
envFrom:
- secretRef:
name: paperless-db-terraform
optional: false
command: ["/bin/sh","-c"]
args: ["pg_dump |gzip -9 > /backup/$(DB_DATABASE_NAME)-DB-$(date +%Y%m%d).sql.gz "]
volumeMounts:
- name: backup
mountPath: /backup
volumes:
- name: backup
persistentVolumeClaim:
claimName: paperless-database-backup
restartPolicy: Never
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: paperless-database-backup
namespace: paperless
annotations:
fileType: Backup
spec:
storageClassName: nfs-storage-fastaccess
accessModes:
- ReadWriteMany
resources:
requests:
storage: 2Gi
@@ -1,10 +0,0 @@
apiVersion: v1
data:
DB_DATABASE: d2lraQ==
DB_HOST: d2lraWpzLWRiLXN2Yw==
DB_PASS: VmVzdDctUHJvZHVjdC1VbnN0ZWFkeQ==
DB_USER: d2lraWpzX3VzZXJuYW1l
kind: Secret
metadata:
name: wikijs-db-credentials
namespace: wikijs
+1
View File
@@ -0,0 +1 @@
terraform 1.16.5
+3 -195
View File
@@ -1,196 +1,4 @@
resource "kubernetes_service_v1" "automatic_service_database" { module "Database-automatic" {
for_each = { for key, value in var.kubernetes : key => value if value.database != null && value.enabled == true && !(try(value.database.shunt, false)) } source = "../modules/database"
metadata { kubernetes_input = var.kubernetes
name = "${each.key}-db-svc"
namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key)
labels = {
deployment_method = "Terraform"
#username = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_password[each.key].key}"
}
}
spec {
selector = {
app = "${each.key}-db"
}
port {
port = try(each.value.database.port, 5432)
target_port = try(each.value.database.port, 5432)
}
}
}
resource "kubernetes_deployment_v1" "database-automatic" {
for_each = { for key, value in var.kubernetes : 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-pvc"
}
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
# optional = true
}
}
}
}
}
}
}
volume {
name = "${each.key}-db-pvc"
persistent_volume_claim {
claim_name = "${each.key}-db-pvc"
}
}
dynamic "volume" {
for_each = try(each.value.database.engine == "sqlserver", false) && !(try(each.value.database.shunt, false)) ? [1] : []
content {
name = "${each.key}-db-backup"
persistent_volume_claim {
claim_name = "${each.key}-db-backup"
}
}
}
}
}
}
}
resource "kubernetes_cron_job_v1" "database-backup" {
for_each = { for key, value in var.kubernetes : 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"
persistent_volume_claim {
claim_name = "${each.key}-db-backup"
}
}
}
}
}
}
}
} }
+12 -270
View File
@@ -1,274 +1,16 @@
resource "kubernetes_service_v1" "automatic_service" {
for_each = { for key, value in var.kubernetes : key => value if value.service_port != null && value.enabled == true }
metadata {
name = "${each.key}-svc"
namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key)
labels = {
deployment_method = "Terraform"
}
annotations = each.value.service_type == "LoadBalancer" ? {
"metallb.universe.tf/ip-allocated-from-pool" = "first-pool"
} : {}
}
spec {
selector = {
app = each.key
}
dynamic "port" {
for_each = each.value.service_port != null ? each.value.service_port : []
content {
port = port.value
target_port = port.value
name = replace("${port.value}${each.key}", "/(.{0,15})(.*)/", "$1")
}
}
# port {
# port = each.value.service_port
# target_port = each.value.service_port
# }
type = each.value.service_type
}
depends_on = [resource.kubernetes_namespace_v1.automatic]
module "ingress" {
source = "../modules/ingress"
kubernetes_input = var.kubernetes
} }
module "services" {
resource "kubernetes_deployment_v1" "automatic" { source = "../modules/services"
for_each = { for key, value in var.kubernetes : key => value if value.enabled == true } kubernetes_input = var.kubernetes
metadata {
namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key)
name = coalesce(each.value.name, each.key)
labels = {
app = each.key
deployment_method = "Terraform"
}
}
spec {
replicas = each.value.replicas
selector {
match_labels = {
app = each.key
}
}
template {
metadata {
labels = {
app = each.key
deployment_method = "Terraform"
}
}
spec {
container {
image = each.value.image
name = coalesce(each.value.name, each.key)
dynamic "port" {
for_each = each.value.service_port != null ? each.value.service_port : []
content {
container_port = port.value
# name = "${each.key}-${port.value}"
name = replace("${port.value}${each.key}", "/(.{0,15})(.*)/", "$1")
}
}
dynamic "volume_mount" {
for_each = each.value.pvc != null ? each.value.pvc : {}
content {
mount_path = volume_mount.value.mount_path
name = "${volume_mount.key}-volume"
sub_path = volume_mount.value.sub_path != null ? volume_mount.value.sub_path : ""
}
}
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"
}
}
dynamic "env_from" {
for_each = each.value.secret_ref != null ? each.value.secret_ref : []
content {
dynamic "secret_ref" {
for_each = [1]
content {
name = env_from.value
}
}
}
}
dynamic "env_from" {
for_each = each.value.database != null && each.value.enabled == true && !(try(each.value.database.shunt, false)) ? ["${each.key}-db-terraform"] : []
#for_each = each.value.database != null && each.value.enabled == true ? ["${each.key}-db-terraform"] : []
content {
dynamic "secret_ref" {
for_each = [1]
content {
name = env_from.value
}
}
}
}
dynamic "env_from" {
for_each = each.value.database != null && each.value.enabled == true ? ["${each.key}-db-mapped-terraform"] : []
content {
dynamic "secret_ref" {
for_each = [1]
content {
name = env_from.value
}
}
}
}
dynamic "env_from" {
for_each = each.value.config_map_ref != null ? each.value.config_map_ref : []
content {
dynamic "config_map_ref" {
for_each = [1]
content {
name = env_from.value
}
}
}
}
command = each.value.command != null ? each.value.command : []
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
}
}
}
}
}
}
dynamic "resources" {
for_each = each.value.requirements != null ? [1] : []
content {
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 "security_context" {
for_each = each.value.security_context == true ? [1] : []
content {
privileged = true
#capabilities = {
# add : ["NET_ADMIN", "NET_RAW"]
#}
}
}
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
}
}
}
dynamic "dns_config" {
for_each = each.value.dns_nameservers != null ? [1] : []
content {
nameservers = [each.value.dns_nameservers]
}
}
service_account_name = each.value.service_account_name != null ? each.value.service_account_name : null
dynamic "volume" {
for_each = each.value.pvc != null ? each.value.pvc : {}
content {
name = "${volume.key}-volume"
dynamic "config_map" {
for_each = volume.value.config_map ? [1] : []
content {
name = volume.key
}
}
dynamic "host_path" {
for_each = volume.value.host_path != null || (!(volume.value.config_map) && !(volume.value.secret)) ? [1] : []
content {
path = coalesce(volume.value.host_path, join("/", [var.storage_path.main_storage, coalesce(each.value.namespace, each.value.connected_namespace, each.key), volume.key]))
}
}
dynamic "secret" {
for_each = volume.value.secret ? [1] : []
content {
secret_name = volume.key
}
}
}
}
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"])
}
}
}
}
}
}
} }
module "Deployment-automatic" {
source = "../modules/deployment"
kubernetes_input = var.kubernetes
}
+11 -110
View File
@@ -13,20 +13,21 @@ provider "kubernetes" {
config_path = "~/.kube/config" config_path = "~/.kube/config"
} }
provider "bitwarden-secrets" { provider "bitwarden-secrets" {
api_url = "https://bitwarden.tryton.geeraert.eu/api" api_url = "https://bitwarden.geeraert.eu/api"
identity_url = "https://bitwarden.tryton.geeraert.eu/identity" identity_url = "https://bitwarden.geeraert.eu/identity"
access_token = "0.9f4b7c5f-e6e7-4eff-929e-b474016a2b9c.bMRELajGGb7qMuXXvzgCCJdDfxfTCS:mFDT7tHSi43KJSnkwvTSYg==" access_token = "0.9f4b7c5f-e6e7-4eff-929e-b474016a2b9c.bMRELajGGb7qMuXXvzgCCJdDfxfTCS:mFDT7tHSi43KJSnkwvTSYg=="
organization_id = "a6361589-badd-4bde-9cb4-af8901161c0d" organization_id = "a6361589-badd-4bde-9cb4-af8901161c0d"
} }
variable "kubernetes" { variable "kubernetes" {
type = map(object({ type = map(object({
name = optional(string) name = optional(string)
image = string docker = optional(bool)
image = string
pvc = optional(map(object({ pvc = optional(map(object({
name = string name = optional(string)
pvc = optional(bool, false) pvc = optional(bool, false)
config_map = optional(bool, false) config_map = optional(bool, false)
secret = optional(bool, false) secret = optional(bool, false)
@@ -55,10 +56,13 @@ variable "kubernetes" {
service_port = optional(list(number)) service_port = optional(list(number))
service_type = optional(string, "ClusterIP") service_type = optional(string, "ClusterIP")
service_name = optional(string) service_name = optional(string)
domain_name = optional(string) domain_name = optional(list(string))
legacy_domain = optional(bool, false)
exposed = optional(bool, true)
liveness_tcp_socket = optional(number) liveness_tcp_socket = optional(number)
liveness_http_get = optional(string) liveness_http_get = optional(string)
liveness_http_get_path = optional(string) liveness_http_get_path = optional(string)
middlewares = optional(string)
database = optional(map(string)) database = optional(map(string))
database_command = optional(list(string)) database_command = optional(list(string))
database_args = optional(list(string)) database_args = optional(list(string))
@@ -92,79 +96,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 {
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
])
}
resource "kubernetes_namespace_v1" "automatic" { resource "kubernetes_namespace_v1" "automatic" {
@@ -202,33 +133,3 @@ resource "kubernetes_manifest" "manifest" {
provider = kubernetes provider = kubernetes
} }
# resource "kubernetes_config_map_v1" "automatic-configmap" {
# metadata {
# name = "extra-sites-terraform"
# namespace = "reverse-proxy"
# annotations = {
# "reloader.stakater.com/match" : "true",
# }
# }
#
# data = {
# for key, value in var.kubernetes :
# "${value.domain_name}.conf" => templatefile("nginx_config.tftpl", {
# name_site = value.domain_name
# name_service = "${key}-svc.${coalesce(value.namespace, value.connected_namespace, key)}.svc:${value.service_port.0}"
# }) if value.domain_name != null && value.enabled == true
# }
#
# }
+3 -141
View File
@@ -1,142 +1,4 @@
resource "kubernetes_service_v1" "automatic_service_redis" { module "Redis-automatic" {
for_each = { for key, value in var.kubernetes : key => value if value.redis != null && value.enabled == true } source = "../modules/redis"
metadata { kubernetes_input = var.kubernetes
name = "${each.key}-redis-svc"
namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key)
labels = {
deployment_method = "Terraform"
}
}
spec {
selector = {
app = "${each.key}-redis"
}
port {
port = 6379
target_port = 6379
}
}
}
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"
}
}
}
}
}
} }
+3 -197
View File
@@ -1,198 +1,4 @@
module "Secrets-automatic" {
data "bitwarden-secrets_secret" "configmap_import" { source = "../modules/secrets"
for_each = { kubernetes_input = var.kubernetes
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 && try(value.import_database_secret, "") != ""
}
}
# 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
} }
View File
+13 -48
View File
@@ -2,19 +2,14 @@ kubernetes = {
gluetun = { gluetun = {
#enabled = false #enabled = false
dns_nameservers = "1.1.1.1" dns_nameservers = "1.1.1.1"
replicas = 01 replicas = 01
image = "qmcgaw/gluetun:latest" image = "qmcgaw/gluetun:latest"
service_port = [8888] exposed = false
#extra_manifest = ["/opt/kubernetes/Terraform_kube/external_manifests/gluetun/gluetun-secret-netherlandNL-FREE-280.yaml"] service_port = [8888]
secret_import = ["5527ba11-07e3-415b-8d1f-b3ee0154eb56", "b0d22160-d81a-4702-a3dd-b40e0168d617", "643dbe99-ace0-4ef5-8a2e-b44f014dccb0"] secret_import = ["5527ba11-07e3-415b-8d1f-b3ee0154eb56", "b0d22160-d81a-4702-a3dd-b40e0168d617", "643dbe99-ace0-4ef5-8a2e-b44f014dccb0"]
security_context = true security_context = true
# requirements = {
# limits-cpu = "800Mi"
# limits-memory = "800Mi"
# requests-cpu = "800Mi"
# requests-memory = "800Mi"
# }
environment = { environment = {
WIREGUARD_PRIVATE_KEY = { WIREGUARD_PRIVATE_KEY = {
value_from = { value_from = {
@@ -33,9 +28,6 @@ kubernetes = {
HTTPPROXY_LISTENING_ADDRESS = { HTTPPROXY_LISTENING_ADDRESS = {
value = "0.0.0.0:8888" value = "0.0.0.0:8888"
} }
# DNS_KEEP_NAMESERVER = {
# value = "on"
# }
VPN_SERVICE_PROVIDER = { VPN_SERVICE_PROVIDER = {
value = "protonvpn" value = "protonvpn"
} }
@@ -53,9 +45,6 @@ kubernetes = {
value = "on" value = "on"
} }
# WIREGUARD_ADDRESSES = {
# value = "10.2.0.2/32"
# }
FIREWALL_INPUT_PORTS = { FIREWALL_INPUT_PORTS = {
value = "8081,7878,9696,9091,51413,8080,6881,8989,8191,8888,8000" value = "8081,7878,9696,9091,51413,8080,6881,8989,8191,8888,8000"
} }
@@ -63,28 +52,22 @@ kubernetes = {
value = "ip2location" value = "ip2location"
} }
# HEALTH_TARGET_ADDRESS = {
# value = "protonvpn.com:80"
# }
# FIREWALL_OUTBOUND_SUBNETS = {
# value = "10.0.0.0/24" }
} }
} }
django = { django = {
enabled = false #enabled = false
namespace = "django" namespace = "django"
image = "gitea.tryton.geeraert.eu/pi-ux-ce/django-python:latest" domain_name = ["django", "admin", "redirect", "streaming", "stash", "simpsons", "kubernetes", "cloudmanager", "podcast"]
image = "gitea.geeraert.eu/pi-ux-ce/django-python:latest"
service_port = [8000] service_port = [8000]
database = { database = {
image = "docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0" image = "docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0"
username = "django_username" username = "django_username"
mountPath = "/var/lib/postgresql/data" mountPath = "/var/lib/postgresql/data"
} }
#redis = {}
secret_ref = ["django-bitwarden-credentials"] secret_ref = ["django-bitwarden-credentials"]
secret_import = ["9fc5a725-75f5-4bab-b595-b474017146c3"] secret_import = ["9fc5a725-75f5-4bab-b595-b474017146c3"]
requirements = { requirements = {
@@ -105,11 +88,6 @@ kubernetes = {
ENVIRONMENT = { ENVIRONMENT = {
value = "PRODUCTION" value = "PRODUCTION"
} }
#CELERY_BROKER_URL = {
# value = "redis://django-redis-svc:6379"
#}
#HTTP_PROXY = {
#value = "http://gluetun-svc.gluetun.svc:8888" }
DB_PASSWORD = { DB_PASSWORD = {
value_from = { value_from = {
@@ -157,16 +135,13 @@ kubernetes = {
} }
pvc = { pvc = {
kubeconfig-secret = { kubeconfig = {
secret = true secret = true
name = "kubeconfig"
mount_path = "/kubeconfig" mount_path = "/kubeconfig"
} }
stash-django-pvc = { stash-django-pvc = {
host_path = "/ssd/stash/data-pvc/" host_path = "/ssd/stash/data-pvc/"
name = "stash-django-pvc"
pvc_size = "2Mi"
mount_path = "/stash" mount_path = "/stash"
} }
} }
@@ -174,10 +149,10 @@ kubernetes = {
django-testing = { django-testing = {
#enabled = false #enabled = false
image = "gitea.tryton.geeraert.eu/pi-ux-ce/django-testing:latest" image = "gitea.geeraert.eu/pi-ux-ce/django-testing:latest"
service_port = [8000] service_port = [8000]
domain_name = ["django-testing", "admin-testing", "redirect-testing", "streaming-testing", "stash-testing", "simpsons-testing", "kubernetes-testing", "cloudmanager-testing", "podcast-testing"]
database = {} database = {}
#redis = {}
requirements = { requirements = {
limits-cpu = "800m" limits-cpu = "800m"
limits-memory = "800Mi" limits-memory = "800Mi"
@@ -210,16 +185,6 @@ kubernetes = {
mount_path = "/kubeconfig" mount_path = "/kubeconfig"
} }
} }
import_database_secret = {
host = "097f10de-63ee-405c-b46a-b41001781e07"
name = "20530a85-e446-4d79-8985-b41001781e07"
password = "a3385f49-ba92-4478-b6f1-b4e100ff01fb"
port = "e15e00eb-db1e-47ea-ab0e-b41001781e09"
username = "3c67d310-7113-45b7-8f3f-b41001781e08"
}
} }
@@ -288,7 +253,7 @@ kubernetes = {
image = "debian" image = "debian"
enabled = false enabled = false
service_port = [19999] service_port = [19999]
domain_name = "netdata" domain_name = ["netdata"]
command = ["sleep", "3600"] command = ["sleep", "3600"]
security_context = true security_context = true
+224
View File
@@ -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"])
}
}
}
}
}
}
}
}
+287
View File
@@ -0,0 +1,287 @@
variable "kubernetes_input" {
type = map(object({
name = optional(string)
image = string
pvc = optional(map(object({
name = optional(string)
pvc = optional(bool, false)
config_map = optional(bool, false)
secret = optional(bool, false)
host_path = optional(string)
pvc_size = optional(string)
storage_class_name = optional(string, "nfs-storage-intelligent")
annotations_fileType = optional(string)
existing_pvc = optional(bool, false)
mount_path = string
sub_path = 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, "")
command = optional(list(string))
service_port = optional(list(number))
liveness_tcp_socket = optional(number)
liveness_http_get = optional(string)
liveness_http_get_path = optional(string)
database = optional(map(string))
enabled = optional(bool, true)
secret_ref = optional(list(string))
config_map_ref = optional(list(string))
requirements = optional(map(string))
dns_nameservers = optional(string)
service_account_name = optional(string)
security_context = optional(bool, false)
}))
}
variable "storage_path" {
type = map(string)
default = {
main_storage = "/data/kubernetes",
fast_access = "/ssd"
}
}
resource "kubernetes_deployment_v1" "automatic" {
for_each = { for key, value in var.kubernetes_input : key => value if value.enabled == true }
metadata {
namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key)
name = coalesce(each.value.name, each.key)
labels = {
app = each.key
deployment_method = "Terraform"
}
}
spec {
replicas = each.value.replicas
selector {
match_labels = {
app = each.key
}
}
template {
metadata {
labels = {
app = each.key
deployment_method = "Terraform"
}
}
spec {
container {
image = each.value.image
name = coalesce(each.value.name, each.key)
dynamic "port" {
for_each = each.value.service_port != null ? each.value.service_port : []
content {
container_port = port.value
# name = "${each.key}-${port.value}"
name = replace("${port.value}${each.key}", "/(.{0,15})(.*)/", "$1")
}
}
dynamic "volume_mount" {
for_each = each.value.pvc != null ? each.value.pvc : {}
content {
mount_path = volume_mount.value.mount_path
name = "${volume_mount.key}-volume"
sub_path = volume_mount.value.sub_path != null ? volume_mount.value.sub_path : ""
}
}
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"
}
}
dynamic "env_from" {
for_each = each.value.secret_ref != null ? each.value.secret_ref : []
content {
dynamic "secret_ref" {
for_each = [1]
content {
name = env_from.value
}
}
}
}
dynamic "env_from" {
for_each = each.value.database != null && each.value.enabled == true && !(try(each.value.database.shunt, false)) ? ["${each.key}-db-terraform"] : []
#for_each = each.value.database != null && each.value.enabled == true ? ["${each.key}-db-terraform"] : []
content {
dynamic "secret_ref" {
for_each = [1]
content {
name = env_from.value
}
}
}
}
dynamic "env_from" {
for_each = each.value.database != null && each.value.enabled == true ? ["${each.key}-db-mapped-terraform"] : []
content {
dynamic "secret_ref" {
for_each = [1]
content {
name = env_from.value
}
}
}
}
dynamic "env_from" {
for_each = each.value.config_map_ref != null ? each.value.config_map_ref : []
content {
dynamic "config_map_ref" {
for_each = [1]
content {
name = env_from.value
}
}
}
}
command = each.value.command != null ? each.value.command : []
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
}
}
}
}
}
}
dynamic "resources" {
for_each = each.value.requirements != null ? [1] : []
content {
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 "security_context" {
for_each = each.value.security_context == true ? [1] : []
content {
privileged = true
#capabilities = {
# add : ["NET_ADMIN", "NET_RAW"]
#}
}
}
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
}
}
}
dynamic "dns_config" {
for_each = each.value.dns_nameservers != null ? [1] : []
content {
nameservers = [each.value.dns_nameservers]
}
}
service_account_name = each.value.service_account_name != null ? each.value.service_account_name : null
dynamic "volume" {
for_each = each.value.pvc != null ? each.value.pvc : {}
content {
name = "${volume.key}-volume"
dynamic "config_map" {
for_each = volume.value.config_map ? [1] : []
content {
name = volume.key
}
}
dynamic "host_path" {
for_each = volume.value.host_path != null || (!(volume.value.config_map) && !(volume.value.secret)) ? [1] : []
content {
path = coalesce(volume.value.host_path, join("/", [var.storage_path.main_storage, coalesce(each.value.namespace, each.value.connected_namespace, each.key), volume.key]))
}
}
dynamic "secret" {
for_each = volume.value.secret ? [1] : []
content {
secret_name = volume.key
}
}
}
}
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"])
}
}
}
}
}
}
}
+126
View File
@@ -0,0 +1,126 @@
variable "kubernetes_input" {
type = map(object({
name = optional(string)
docker = optional(bool)
namespace = optional(string)
connected_namespace = optional(string, "")
service_port = optional(list(number))
service_type = optional(string, "ClusterIP")
domain_name = optional(list(string))
middlewares = optional(string)
legacy_domain = optional(bool, false)
exposed = optional(bool, true)
enabled = optional(bool, true)
}))
}
resource "kubernetes_ingress_v1" "automatic_ingress" {
# Keep your top-level filter for filtering active services
for_each = { for key, value in var.kubernetes_input : key => value if value.service_port != null && value.enabled == true && value.docker != true && value.exposed == true }
metadata {
name = "${each.key}-ingress"
namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key)
annotations = merge(
{
"cert-manager.io/cluster-issuer" = "letsencrypt-prod"
"traefik.ingress.kubernetes.io/router.entrypoints" = "websecure"
},
# Simply injects the middleware string if it is present and not empty
lookup(each.value, "middlewares", "") != "" ? {
"traefik.ingress.kubernetes.io/router.middlewares" = each.value.middlewares
} : {}
)
}
spec {
ingress_class_name = "traefik"
# --- DYNAMIC TLS BLOCK ---
# Generates a separate TLS block + secret per domain entry
dynamic "tls" {
for_each = toset(coalesce(each.value.domain_name, [each.key]))
content {
hosts = [join(".", [tls.value, "geeraert.eu"])]
secret_name = "${each.key}-${tls.value}-tls-secret"
}
}
# --- DYNAMIC RULE BLOCK ---
# Loops through the domain list and creates an HTTP path routing rule for each
dynamic "rule" {
for_each = toset(coalesce(each.value.domain_name, [each.key]))
content {
host = join(".", [rule.value, "geeraert.eu"])
http {
path {
path = "/"
backend {
service {
name = "${each.key}-svc"
port {
number = each.value.service_port[0]
}
}
}
}
}
}
}
}
}
resource "kubernetes_ingress_v1" "automatic_ingress_legacy" {
for_each = { for key, value in var.kubernetes_input : key => value if value.service_port != null && value.enabled == true && value.docker != true && value.exposed == true && value.legacy_domain == true }
metadata {
name = "${each.key}-legacy-ingress"
namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key)
annotations = {
"cert-manager.io/cluster-issuer" = "letsencrypt-prod"
"traefik.ingress.kubernetes.io/router.entrypoints" = "websecure"
}
}
spec {
ingress_class_name = "traefik"
# --- DYNAMIC TLS BLOCK ---
# Generates a separate TLS block + secret per domain entry
dynamic "tls" {
for_each = toset(coalesce(each.value.domain_name, [each.key]))
content {
hosts = [join(".", [tls.value, "tryton.geeraert.eu"])]
secret_name = "${each.key}-${tls.value}-tryton-tls-secret"
}
}
# --- DYNAMIC RULE BLOCK ---
# Loops through the domain list and creates an HTTP path routing rule for each
dynamic "rule" {
for_each = toset(coalesce(each.value.domain_name, [each.key]))
content {
host = join(".", [rule.value, "tryton.geeraert.eu"])
http {
path {
path = "/"
backend {
service {
name = "${each.key}-svc"
port {
number = each.value.service_port[0]
}
}
}
}
}
}
}
}
}
+109
View File
@@ -0,0 +1,109 @@
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"])]))
}
}
}
}
}
}
+321
View File
@@ -0,0 +1,321 @@
terraform {
required_version = "> 0.8.0"
required_providers {
bitwarden-secrets = {
source = "bitwarden/bitwarden-secrets"
version = "0.5.4-pre"
}
}
}
provider "bitwarden-secrets" {
api_url = "https://bitwarden.geeraert.eu/api"
identity_url = "https://bitwarden.geeraert.eu/identity"
access_token = "0.9f4b7c5f-e6e7-4eff-929e-b474016a2b9c.bMRELajGGb7qMuXXvzgCCJdDfxfTCS:mFDT7tHSi43KJSnkwvTSYg=="
organization_id = "a6361589-badd-4bde-9cb4-af8901161c0d"
}
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}"
}
}
+97
View File
@@ -0,0 +1,97 @@
variable "kubernetes_input" {
type = map(object({
docker = optional(bool)
namespace = optional(string)
connected_namespace = optional(string, "")
service_port = optional(list(number))
service_type = optional(string, "ClusterIP")
database = optional(map(string))
redis = optional(map(string))
enabled = optional(bool, true)
}))
}
resource "kubernetes_service_v1" "automatic_service" {
for_each = { for key, value in var.kubernetes_input : key => value if value.service_port != null && value.enabled == true && value.docker != true }
metadata {
name = "${each.key}-svc"
namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key)
labels = {
deployment_method = "Terraform"
}
annotations = each.value.service_type == "LoadBalancer" ? {
"metallb.universe.tf/ip-allocated-from-pool" = "first-pool"
} : {}
}
spec {
selector = {
app = each.key
}
dynamic "port" {
for_each = each.value.service_port != null ? each.value.service_port : []
content {
port = port.value
target_port = port.value
name = replace("${port.value}${each.key}", "/(.{0,15})(.*)/", "$1")
node_port = each.value.service_type == "NodePort" ? port.value : 0
}
}
type = each.value.service_type
}
}
resource "kubernetes_service_v1" "automatic_service_database" {
for_each = { for key, value in var.kubernetes_input : key => value if value.database != null && value.enabled == true && !(try(value.database.shunt, false)) && value.docker != true }
metadata {
name = "${each.key}-db-svc"
namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key)
labels = {
deployment_method = "Terraform"
#username = "${resource.bitwarden-secrets_secret.automatic_bitwarden_secret_password[each.key].key}"
}
}
spec {
selector = {
app = "${each.key}-db"
}
port {
port = try(each.value.database.port, 5432)
target_port = try(each.value.database.port, 5432)
}
}
}
resource "kubernetes_service_v1" "automatic_service_redis" {
for_each = { for key, value in var.kubernetes_input : key => value if value.redis != null && value.enabled == true && value.docker != true }
metadata {
name = "${each.key}-redis-svc"
namespace = coalesce(each.value.namespace, each.value.connected_namespace, each.key)
labels = {
deployment_method = "Terraform"
}
}
spec {
selector = {
app = "${each.key}-redis"
}
port {
port = 6379
target_port = 6379
}
}
}
-83
View File
@@ -1,83 +0,0 @@
terraform {
required_version = "> 0.8.0"
}
provider "kubernetes" {
config_path = "~/.kube/config"
}
variable "shunt_kubernetes" {
type = bool
default = true
}
variable "nginx_sites" {
type = map(object({
service = string
docker_service = optional(string)
enabled = optional(bool, true)
proxy_cache = optional(bool, false)
extra-value = optional(string, "")
extra-value-location = optional(string, "")
http2_bool = optional(bool, false)
proxy_pass_https = optional(bool, false)
authentication_required = optional(bool, false)
redirect_to_https_bool = optional(bool, true)
listen_port_80_bool = optional(bool, false)
geoip_blocking = optional(bool, false)
geoip_allow = optional(list(string), ["FR", "GB"])
redirect_to_root_domain = optional(bool, true)
}))
}
resource "kubernetes_config_map" "automatic-configmap" {
#avoiding this to create if the shunt_kubernetes is on
count = var.shunt_kubernetes ? 0 : 1
metadata {
name = "sites-terraform"
namespace = "reverse-proxy"
annotations = {
"reloader.stakater.com/match" : "true",
}
}
data = {
for key, value in var.nginx_sites :
"${key}.conf" => templatefile("nginx_config.tftpl", {
name_site = key
name_service = value.service
proxy_cache = value.proxy_cache
extra-value = value.extra-value
extra-value-location = value.extra-value-location
http2_bool = value.http2_bool
proxy_pass_https = value.proxy_pass_https
authentication_required = value.authentication_required
redirect_to_https_bool = value.redirect_to_https_bool
listen_port_80_bool = value.listen_port_80_bool
geoip_blocking = value.geoip_blocking
geoip_allow = value.geoip_allow
redirect_to_root_domain = value.redirect_to_root_domain
}) if value.enabled == true
}
}
resource "local_file" "nginx_configs" {
for_each = { for key, value in var.nginx_sites : key => value if value.enabled == true && value.docker_service != null }
filename = "/data/kubernetes/reverse-proxy/reverse-proxy-sites/${each.key}.conf"
content = templatefile("nginx_config.tftpl", {
name_site = each.key
name_service = each.value.docker_service
proxy_cache = each.value.proxy_cache
extra-value = each.value.extra-value
extra-value-location = each.value.extra-value-location
http2_bool = each.value.http2_bool
proxy_pass_https = each.value.proxy_pass_https
authentication_required = each.value.authentication_required
redirect_to_https_bool = each.value.redirect_to_https_bool
listen_port_80_bool = each.value.listen_port_80_bool
redirect_to_root_domain = each.value.redirect_to_root_domain
})
}
-144
View File
@@ -1,144 +0,0 @@
############################################
# config file for ${name_site}
############################################
upstream ${name_site}_backend {
server ${name_service};
server 1.1.1.1 backup;
}
server {
server_name ${name_site}.tryton.geeraert.eu www.${name_site}.tryton.geeraert.eu;
%{~ if redirect_to_root_domain~}
if ($host = www.${name_site}.tryton.geeraert.eu) {
return 301 https://${name_site}.geeraert.eu$request_uri;
}
if ($host = ${name_site}.tryton.geeraert.eu) {
return 301 https://${name_site}.geeraert.eu$request_uri;
}
%{~ endif ~}
%{ if redirect_to_root_domain != true }
location / {
proxy_pass %{ if proxy_pass_https}https%{else}http%{ endif }://${name_site}_backend;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
${extra-value-location}
}
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
%{ endif }
access_log /var/log/nginx/access.log my_custom_format;
access_log /var/log/nginx/ip_audit.log ip_audit;
access_log /var/log/nginx/backend_debug.log backend_debug;
${extra-value}
%{~ if http2_bool~}
http2 on;
ssl_protocols TLSv1.2;
%{~ endif ~}
listen 443 ssl;
%{~ if listen_port_80_bool~}
listen 80;
%{~ endif ~}
ssl_certificate /etc/nginx/ssl/live/tryton.geeraert.eu/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/live/tryton.geeraert.eu/privkey.pem;
}
%{~ if redirect_to_https_bool~}
server {
if ($host = www.${name_site}.tryton.geeraert.eu) {
return 301 https://$host$request_uri;
}
if ($host = ${name_site}.tryton.geeraert.eu) {
return 301 https://$host$request_uri;
}
server_name www.${name_site}.tryton.geeraert.eu ${name_site}.tryton.geeraert.eu ;
listen 80;
return 404;
}
%{~ endif ~}
############################################
# config file for ${name_site}
############################################
upstream ${name_site}_backend_root {
server ${name_service};
server 1.1.1.1 backup;
}
server {
server_name ${name_site}.geeraert.eu www.${name_site}.geeraert.eu;
location / {
proxy_pass %{ if proxy_pass_https}https%{else}http%{ endif }://${name_site}_backend_root;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
${extra-value-location}
}
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
access_log /var/log/nginx/access.log my_custom_format;
access_log /var/log/nginx/ip_audit.log ip_audit;
access_log /var/log/nginx/backend_debug.log backend_debug;
${extra-value}
%{~ if http2_bool~}
http2 on;
ssl_protocols TLSv1.2;
%{~ endif ~}
listen 443 ssl;
%{~ if listen_port_80_bool~}
listen 80;
%{~ endif ~}
ssl_certificate /etc/nginx/ssl/live/geeraert.eu/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/live/geeraert.eu/privkey.pem;
}
%{~ if redirect_to_https_bool~}
server {
if ($host = www.${name_site}.geeraert.eu) {
return 301 https://$host$request_uri;
}
if ($host = ${name_site}.geeraert.eu) {
return 301 https://$host$request_uri;
}
server_name www.${name_site}.geeraert.eu ${name_site}.geeraert.eu ;
listen 80;
return 404;
}
%{~ endif ~}
-600
View File
@@ -1,600 +0,0 @@
nginx_sites = {
bitwarden = {
#service = "nginx.bitwarden.svc:8080"
#extra-value-location = <<EOT
#proxy_set_header Host $host;
#proxy_set_header X-Real-IP $remote_addr;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_set_header Proxy "";
# EOT
service = "bitwarden-nginx-svc.bitwarden.svc:8080"
http2_bool = true
redirect_to_root_domain = false
}
bookstack = {
enabled = false
# service = "webserver.bookstack.svc"
service = "bookstack-svc.bookstack.svc"
proxy_cache = false
}
django = {
service = "django-svc.django:8000"
proxy_cache = true
http2_bool = true
}
admin = {
service = "django-svc.django:8000"
proxy_cache = true
http2_bool = true
}
redirect = {
service = "django-svc.django:8000"
proxy_cache = true
http2_bool = true
}
streaming = {
service = "django-svc.django:8000"
proxy_cache = true
http2_bool = true
}
stash = {
service = "django-svc.django:8000"
proxy_cache = true
http2_bool = true
}
simpsons = {
service = "django-svc.django:8000"
proxy_cache = true
http2_bool = true
}
kubernetes = {
service = "django-svc.django:8000"
proxy_cache = true
http2_bool = true
}
cloudmanager = {
service = "django-svc.django:8000"
proxy_cache = true
http2_bool = true
}
podcast = {
service = "django-svc.django:8000"
proxy_cache = true
http2_bool = true
}
django-testing = {
service = "django-testing-svc.django-testing.svc:8000"
proxy_cache = true
http2_bool = true
}
admin-testing = {
service = "django-testing-svc.django-testing.svc:8000"
proxy_cache = true
http2_bool = true
}
redirect-testing = {
service = "django-testing-svc.django-testing.svc:8000"
proxy_cache = true
http2_bool = true
}
streaming-testing = {
service = "django-testing-svc.django-testing.svc:8000"
proxy_cache = true
http2_bool = true
}
stash-testing = {
service = "django-testing-svc.django-testing.svc:8000"
proxy_cache = true
http2_bool = true
}
simpsons-testing = {
service = "django-testing-svc.django-testing.svc:8000"
proxy_cache = true
http2_bool = true
}
kubernetes-testing = {
service = "django-testing-svc.django-testing.svc:8000"
proxy_cache = true
http2_bool = true
}
cloudmanager-testing = {
service = "django-testing-svc.django-testing.svc:8000"
proxy_cache = true
http2_bool = true
}
podcast-testing = {
service = "django-testing-svc.django-testing.svc:8000"
proxy_cache = true
http2_bool = true
}
echo = {
enabled = true
# service = "echo-server.echo-server.svc:80"
service = "echo-svc.echo.svc"
docker_service = "echo"
proxy_cache = true
http2_bool = true
#extra-value-location = <<EOT
# auth_request /oauth2/auth;
# error_page 401 = @oauth2_signin;
# proxy_set_header X-Auth-Request-Redirect $request_uri;
# EOT
#extra-value = <<EOT
# location = /oauth2/auth {
# internal;
#proxy_pass http://oauthn_backend;
## proxy_pass https://oauthn.tryton.geeraert.eu/oauth2/auth;
# proxy_pass_request_body off;
# proxy_set_header Content-Length "";
# proxy_set_header X-Original-URI $request_uri;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Scheme $scheme;
#}
#location @oauth2_signin {
# return 302 https://$host/oauth2/start?rd=https://$host$request_uri;
# #return 302 https://oauthn.tryton.geeraert.eu/oauth2/start?rd=https://$host$request_uri;
#}
#location /oauth2/ {
#proxy_pass http://oauthn_backend;
#proxy_set_header Host $host;
#proxy_set_header X-Real-IP $remote_addr;
#proxy_set_header X-Scheme $scheme;
#proxy_set_header X-Auth-Request-Redirect $request_uri;
#}
# EOT
}
gitlab = {
service = "webserver.gitlab.svc:443"
proxy_cache = true
extra_value_bool = true
enabled = false
extra-value = <<EOT
client_max_body_size 20m;
proxy_request_buffering off;
EOT
http2_bool = true
proxy_pass_https = true
}
sonarr = {
service = "sonarr-svc.servarr.svc:8989"
geoip_allow = ["FR", "GB", "NL"]
}
keycloak = {
service = "keycloak.keycloak.svc:8080"
enabled = false
extra-value = <<EOT
set_real_ip_from 0.0.0.0/0;
real_ip_header X-Real-IP;
real_ip_recursive on;
EOT
}
nextcloud = {
redirect_to_root_domain = false
service = "webserver.nextcloud.svc"
#service = "nextcloud-svc.next.svc"
proxy_cache = true
http2_bool = true
extra-value = <<EOT
location /.well-known/carddav {
return 301 $scheme://$host/remote.php/dav;
}
location /.well-known/caldav {
return 301 $scheme://$host/remote.php/dav;
}
location = /health {
default_type text/html;
return 200 "<!DOCTYPE html><h2>health check</h2>\n";
}
EOT
}
router = {
service = "192.168.88.1"
authentication_required = true
}
homeassistant = {
enabled = false
service = "homeassistant-svc.homeassistant.svc:8123"
}
octoprint = {
service = "192.168.0.32:5000"
extra-value-location = <<EOT
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme; # Crucial for HTTPS to HTTP matching
# Required for OctoPrint WebSockets to function properly
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
client_max_body_size 0; # Allows large file uploads like gcode
EOT
}
onitama = {
service = "onitama-svc.onitama.svc:8080"
enabled = false
}
opentrashmail = {
# service = "opentrashmail.opentrashmail.svc"
service = "1.1.1.1"
enabled = false
}
paperless = {
#service = "webserver.paperless.svc:8000"
service = "paperless-svc.paperless.svc:8000"
}
pihole = {
service = "172.16.0.60:8081"
enabled = false
}
portainer = {
service = "portainer.portainer.svc"
}
prowlarr = {
service = "prowlarr-svc.servarr.svc:9696"
geoip_allow = ["FR", "GB", "NL"]
}
proxmox = {
service = "192.168.6.2:8006"
enabled = false
}
qbittorrent = {
#enabled = false
service = "qbittorrent-svc.servarr.svc:8080"
geoip_allow = ["FR", "GB", "NL"]
}
radarr = {
service = "radarr-svc.servarr.svc:7878"
geoip_allow = ["FR", "GB", "NL"]
}
recommendarr = {
service = "recommendarr-svc.servarr.svc:3000"
enabled = false
}
#reverse = {
# service = "192.168.88.50:8888"
# enabled = false
#}
sickchill = {
service = "sickchill.servarr.svc"
enabled = false
}
transmission = {
service = "192.168.88.52:31091"
enabled = false
}
unifi = {
# service = "unifi.unifi.svc:8443"
service = "192.168.88.244:8443"
proxy_pass_https = true
}
unifi-inform = {
service = "192.168.88.50:8082"
}
dupeguru = {
service = "dupeguru.dupeguru.svc:5800"
enabled = false
authentication_required = true
}
immich = {
#service = "immich-server.immich.svc:2283"
service = "immich-svc.immich.svc:2283"
geoip_allow = ["FR", "GB", "NL"]
extra-value-location = <<EOT
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 60000s;
#adding websocket , usefull for reverse proxy
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_cache_bypass $http_upgrade;
#end of working
EOT
}
immicht = {
service = "immicht-svc.immicht.svc:2283"
enabled = false
}
netdata = {
enabled = false
service = "netdata-agent.netdata.svc:19999"
}
screeps = {
enabled = false
redirect_to_https_bool = false
listen_port_80_bool = true
service = "screeps-svc.screeps.svc:25565"
}
minecraft = {
enabled = false
redirect_to_https_bool = false
listen_port_80_bool = true
service = "minecraft-svc.minecraft.svc:21025"
}
stirling = {
enabled = false
service = "stirling-svc.stirling.svc:8080"
extra-value-location = <<EOT
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 60000s;
#working
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_cache_bypass $http_upgrade;
#end of working
EOT
}
vulcan = {
service = "vulcan.vulcan.svc:80"
enabled = false
}
nginx = {
enabled = false
service = "nginx-svc.nginx.svc"
}
openmediavault = {
service = "192.168.88.29"
# service = "192.168.88.42"
}
pihole = {
service = "web.piholenew.svc"
}
jellyfin = {
enabled = false
service = "jellyfin-svc.jellyfin.svc:8096"
}
gogs = {
enabled = false
service = "gogs-svc.gogs.svc:3000"
}
synology = {
enabled = true
service = "192.168.88.39:5000"
}
gitea = {
enabled = true
service = "webserver.gitea.svc:3000"
docker_service = "gitea:3000"
redirect_to_root_domain = false
}
spider = {
enabled = false
service = "spider-svc.spider.svc:8080"
}
nextcloud-terraform = {
enabled = false
service = "nextcloud-web-svc.nextcloud-terraform.svc:80"
}
paper = {
enabled = false
service = "paper-svc.paper.svc:8000"
}
next = {
enabled = false
service = "next-svc.next.svc"
proxy_cache = true
http2_bool = true
extra-value = <<EOT
location /.well-known/carddav {
return 301 $scheme://$host/remote.php/dav;
}
location /.well-known/caldav {
return 301 $scheme://$host/remote.php/dav;
}
location = /health {
default_type text/html;
return 200 "<!DOCTYPE html><h2>health check</h2>\n";
}
EOT
}
bookstack-terraform = {
enabled = false
service = "bookstack-svc.bookstack-terraform.svc"
}
stash = {
# enabled = false
service = "stash-svc.stash.svc:9999"
#geoip_blocking = false
#extra-value= <<EOT
# proxy_protocol on;
#EOT
extra-value-location = <<EOT
#don't use this as this needs to be run as root or have the CAP_NET_RAW capability) to bind to a non-local IP address.
#Because the backend thinks the request is coming directly from the client, it will try to send the response directly back to that client IP. To prevent this (which would break the connection), you must force the response back through the NGINX server.
#proxy_bind $remote_addr transparent;
##used to be working
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 60000s;
#working
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_cache_bypass $http_upgrade;
#end of working
EOT
geoip_allow = ["FR", "GB", "NL"]
}
neko = {
enabled = false
service = "neko-svc.neko.svc:8080"
http2_bool = true
extra-value-location = <<EOT
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_cache_bypass $http_upgrade;
EOT
}
pinchflat = {
enabled = false
service = "pinchflat-svc.pinchflat.svc:8945"
}
jobspy = {
enabled = false
service = "jobspy-svc.jobspy.svc:8000"
}
poste = {
enabled = false
service = "poste-svc.poste.svc:443"
proxy_pass_https = true
extra-value-location = <<EOT
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 60000s;
#working
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_cache_bypass $http_upgrade;
#end of working
EOT
}
wikijs = {
#enabled = false
geoip_blocking = false
service = "wikijs-svc.wikijs.svc:3000"
extra-value = <<EOT
client_max_body_size 20m;
proxy_request_buffering off;
EOT
}
keycloak = {
enabled = false
service = "keycloak-svc.keycloak.svc:8080"
extra-value = <<EOT
set_real_ip_from 0.0.0.0/0;
real_ip_header X-Real-IP;
real_ip_recursive on;
EOT
}
oauthn = {
enabled = false
service = "oauth2-proxy-svc.oauth2-proxy.svc:4180"
# extra-value = <<EOT
# location /oauth2/ {
# proxy_pass http://oauthn_backend;
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Scheme $scheme;
# }
# EOT
}
emailproxy = {
enabled = false
service = "emailproxy-svc.paper.svc:80"
}
tdarr = {
enabled = false
service = "tdarr-svc.servarr.svc:8265"
extra-value-location = <<EOT
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 60000s;
#working
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_cache_bypass $http_upgrade;
#end of working
EOT
}
opencloud = {
enabled = false
service = "opencloud-svc.opencloud.svc:9200"
proxy_pass_https = true
}
owncloud = {
enabled = false
service = "owncloud-svc.owncloud.svc:8080"
}
#overleaf = {
# service = "overleaf-svc.overleaf.svc:80"
#}
}
deny_ip = ["1.2.3.4"]