40 Commits
Author SHA1 Message Date
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
pierre.geeraert 9a5e82cb32 we don't use pvc.name anymore but pvc.key 2026-10-12 18:05:00 +01:00
pierre.geeraert 236a994bfa cleanup 2026-10-12 18:01:17 +01:00
pierre.geeraert 9257237fd1 importing all secrets 2026-10-12 18:00:49 +01:00
pierre.geeraert 04d6d19dde better way to import 2026-10-12 17:14:26 +01:00
pierre.geeraert bc1bee1074 plan for gluetun sound good 2026-10-12 16:54:42 +01:00
pierre.geeraert ec901f92df reformat 2026-10-12 16:53:38 +01:00
pierre.geeraert e538226182 infra restructure and adding lifecycle to the secret 2026-10-12 16:48:01 +01:00
pierre.geeraert c7c0941877 remove some bits as well 2026-10-12 12:11:16 +01:00
pierre.geeraert 69f4696faa fix backup sqlsserver 2026-10-12 10:58:21 +01:00
pierre.geeraert 307d4117ae enable all bitwarden 2026-10-12 10:48:37 +01:00
pi-ux-ce@ARES 37c93401f1 enable identity and remove un necessary svc file 2026-10-12 10:48:00 +01:00
pierre.geeraert 5f8bb25e76 fixing the pvcs 2026-10-12 10:46:04 +01:00
pi-ux-ce@ARES fe064cb7ea work on bitwarden 2026-10-12 10:40:13 +01:00
pi-ux-ce@ARES 002053c099 adding namepsace to gitea runner 2026-10-12 10:32:05 +01:00
pi-ux-ce 7962e91e3a gitea needed service port 2026-10-12 10:25:47 +01:00
pierre.geeraert 534958f828 adding database support 2026-10-12 09:54:26 +01:00
pierre geeraert b27bfe5714 not filling nodeport if the type is not nodeport 2026-10-12 00:16:07 +01:00
pierre geeraert 437891b2d4 work on the node port 2026-10-12 00:07:53 +01:00
pierre geeraert de81eb1e09 work on the node port 2026-10-12 00:04:24 +01:00
pierre geeraert d720f66322 cleaning unnecessary codee 2026-10-11 23:31:01 +01:00
pierre geeraert 4620270006 working destination file name 2026-10-11 23:20:57 +01:00
pierre geeraert ecaba98387 add comment 2026-10-11 13:02:17 +01:00
pi-ux-ce 85e853e9cb not working yet maybe we need the join function instead 2026-10-11 13:01:10 +01:00
pierre geeraert 64fdd22df8 disbale for our tests 2026-10-11 12:50:45 +01:00
pierre geeraert f8c89da4a1 fix bool error 2026-10-11 12:49:45 +01:00
pierre geeraert 79dbe3721e fix bool error 2026-10-11 12:44:27 +01:00
pierre geeraert a0cf0cebe4 another try for the hostpath 2026-10-11 12:42:29 +01:00
pi-ux-ce 6d9b7d792f testing with the shunt docker 2026-10-11 11:38:27 +01:00
pierre geeraert 51179673ce adding namespace 2026-10-11 11:32:54 +01:00
pierre.geeraert caac327b50 adding tfvars 2026-10-07 15:29:32 +01:00
pierre.geeraert 8c1b6cdef8 restructuring the code 2026-10-07 15:18:36 +01:00
33 changed files with 3234 additions and 54076 deletions
-1
View File
@@ -1 +0,0 @@
2.pYoQjnuN9ZB+IqEypWrFPw==|/nlBG5qPy/zIFwYjjNXMuNWLU8pSt3TLR1/q4L3AEzi5Semc2261DyelXIfVpOn21JOGOV7jiIV6P3CSuASCjvCH+lCZSbjHfcj/MIOl3IBZJWF3vnTBVl3yjYD+Jmf0/zaYXbUW881oiO3Pu5Obc2jiBKNlX2bx5H11Iyi/fOmvR+EgsdequGgRm0FiSkjkbyG8d9bR55XR9NtS5x9a8EOhKWu0yXFGAKkDGV/m+j45z20mVTlAuuNDtIOX/rDKdKJpzg6SF8EuRTGC5RWAHJ+V8BACe3xxHi43YFit5RjpQ83F6rUGc+hc7TTcKyLA0Go7vUnKQ2wljSihM+HgJbGI6Sgnc9/Ys9AyDI0Bfz4EntfUqSeMBoaatvGpe3LYZdGysUMtDUoQWAvEfKbnnTKQRJb6zTD0RjhJ1ZowrrUFXyU9s1kNu3Sx29Q6h926lIiZ7kNejLcBEIJm0NjifAT9E0dwWTC6/bM2NrQpAotQBQGKGOGGRPIQW8vM7EJ6pl3ZSM/RzRnvQEdmWLNTbLd5eUd0efTviQr4BTxhwj7m3UGBUI/ZQhd3UNTU2ZVpt93nY2QPW3EpNpPBdYMnAgqbc3iz9mGZKtUwYpCwEpHj2G0CxCjgoj8il3Ys+vpPbYqpx+/FbibQLsELAbvLtK/TnDT5tq2gCYIHNUYL+iO+rdm8uGVWcFeMUBvyC/sdHEJgnQ3Rf6Up8lhgP3NQu6QgWT5gkGRrJ4RoYYET9919FOas43imUfWLEAaL/iU+NliGj3B0gCnwi1Ljm4+k5MOVHJqgcBdh0LHhNgIQcBurV0Qk8ZkoVnkTBjTMduOGogn9+Ny7B5D28nk8VW4fHL9MsgvYTZXZmI0QKgS2YzTmkle916qGLWgo5hcp5V4MG1EBpchzu0JJUUdPrb06txBr+cCCYvGi1B2epw6nJAJ7OGB4vzcJM/kVQYRVQmV/kfWXxtROCkx3CAKG5oyKMiiPcUiiqIIYuhRUEZYPC9+w67nMANPG8VcyqylcEba/FMSn4ECj7ce2iHCnyAnk9wb78P/YZdNMGbgviJq1nZm+OaGmpMxEoZHpyOe3EmuEKNpuSgqXGygR6ltAqzFRNJJlHm1PLHWxp4n4n5E1VhbaFiN2urTn/Pt2hqh0YEHyRVYYDSJv5QL8Dqq7WVYD2V3waLwi5Q5o6jc2XkaGN3hLg0fH7yO9KMa+MGUIcx5TZX+QGwiB4n/rZijV2h9d7th/tn0+/Gxtz+JcZ9J+4j4/1MR89vGe1EFOl9ZpUYxQVTVNuLoPaql5dXJZf3LeLL3fq05yNyW38NzcT5fFjevSRyRyoTHTrePCr5Tk5D0BaNQDhgDvBtC1kdo72HKR0+y1x31TxzLmc3OMBj2iqMxt0V7snwUfuVYu43LY48YML3wxRe/EVDmP6h8H89JWkw1aCJsLInN7hDSpUJtGBIn30c5r2kSw/87iVskVnQAUsQFMPOzUmDm6E07fnysbPwuAECuha93aMljzQNF4mwd6Pey24Pkfl+K7wypOL94iK1GcM4FqsCpNfD/X1M3Z+AVQahXAtUt82wmaXfQUtQ6Dvt6mfwFnknmWpyI9Pbj3r8lh4M5rffMFucJac32eoq+KY9xdhyPyep0becLQxNog2LiWliSQlfKBoB3X9FSyDalwEasWagUvNdENqkL+GWCxlCZK7g+ibvO5keA0Baqt1ohRcBoigNfmcTsZUPRhq+dy2cvaiPaGRDgX2DKlJdC8LnPDb/qTvk+uP5yZaKSItjdFkYo7c+fbOXH+I93Kd9IK+LJVM+9cWnx6yKBW/TaaEuZCBholtxME8ZQDcnXIelp67IamsfuVb5QNouZuimzb9rP9vEDVTdyE3e5rYzl2AaljMdTIjB1ut5ZqGA8=|hem/6+QHhqSdcTgKycZLP9EDBT3JA8fLIUqETgTITNk=
+3
View File
@@ -41,3 +41,6 @@ terraform.tfstate*
.terraform.lock.hcl
.bw-provider-state
.claude
View File
@@ -191,80 +191,6 @@ kubernetes = {
}
gluetun = {
# enabled = false
dns_nameservers = "1.1.1.1"
replicas = 01
image = "qmcgaw/gluetun:latest"
service_port = [8888]
#extra_manifest = ["/opt/kubernetes/Terraform_kube/external_manifests/gluetun/gluetun-secret-netherlandNL-FREE-280.yaml"]
secret_import = ["5527ba11-07e3-415b-8d1f-b3ee0154eb56", "b0d22160-d81a-4702-a3dd-b40e0168d617", "643dbe99-ace0-4ef5-8a2e-b44f014dccb0"]
security_context = true
# requirements = {
# limits-cpu = "800Mi"
# limits-memory = "800Mi"
# requests-cpu = "800Mi"
# requests-memory = "800Mi"
# }
environment = {
WIREGUARD_PRIVATE_KEY = {
value_from = {
secret_key_ref = {
name = "gluetun-secret-nl-free-280"
key = "WIREGUARD_PRIVATE_KEY"
}
}
}
HTTPPROXY = {
value = "on"
}
HTTPPROXY_LOG = {
value = "on"
}
HTTPPROXY_LISTENING_ADDRESS = {
value = "0.0.0.0:8888"
}
# DNS_KEEP_NAMESERVER = {
# value = "on"
# }
VPN_SERVICE_PROVIDER = {
value = "protonvpn"
}
VPN_TYPE = {
value = "wireguard"
}
SERVER_COUNTRIES = {
value = "Netherlands"
}
HEALTH_TARGET_ADDRESS = {
value = "0.0.0.0:8888"
}
FREE_ONLY = {
value = "on"
}
# WIREGUARD_ADDRESSES = {
# value = "10.2.0.2/32"
# }
FIREWALL_INPUT_PORTS = {
value = "8081,7878,9696,9091,51413,8080,6881,8989,8191,8888,8000"
}
PUBLICIP_API = {
value = "ip2location"
}
# HEALTH_TARGET_ADDRESS = {
# value = "protonvpn.com:80"
# }
# FIREWALL_OUTBOUND_SUBNETS = {
# value = "10.0.0.0/24" }
}
}
onitama = {
enabled = false
@@ -368,19 +294,7 @@ kubernetes = {
pvc_size = "1Gi"
mount_path = "/data"
}
gitea = {
enabled = false
image = "gitea/gitea:1.22.3"
requirements = {
limits-cpu = "50m"
limits-memory = "50Mi"
requests-cpu = "50m"
requests-memory = "50Mi"
}
service_port = [3000]
pvc_size = "1Gi"
mount_path = "/data"
}
notmuch = {
enabled = false
@@ -673,7 +587,7 @@ kubernetes = {
nextcloud = {
enabled = false
enabled = false
namespace = "next"
#replicas = 0
image = "nextcloud:29.0.3-apache"
@@ -1500,200 +1414,6 @@ kubernetes = {
}
django = {
#enabled =false
namespace = "django"
image = "gitea.tryton.geeraert.eu/pi-ux-ce/django-python:latest"
service_port = [8000]
database = {
image = "docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0"
username = "django_username"
mountPath = "/var/lib/postgresql/data"
}
#redis = {}
secret_ref = ["django-bitwarden-credentials"]
secret_import = ["9fc5a725-75f5-4bab-b595-b474017146c3"]
requirements = {
limits-cpu = "800m"
limits-memory = "800Mi"
requests-cpu = "10m"
requests-memory = "300Mi"
}
extra_manifest = ["/opt/kubernetes/Terraform_kube/external_manifests/django/kubeconfig.secret.yaml", "/opt/kubernetes/Terraform_kube/external_manifests/django/django-db.secret.yaml"]
environment = {
ALLOWED_HOSTS = {
value = "django.geeraert.eu,admin.geeraert.eu,redirect.geeraert.eu,streaming.geeraert.eu,stash.geeraert.eu,simpsons.geeraert.eu,kubernetes.geeraert.eu,cloudmanager.geeraert.eu,podcast.geeraert.eu"
}
DEBUG = {
value = "False"
}
ENVIRONMENT = {
value = "PRODUCTION"
}
#CELERY_BROKER_URL = {
# value = "redis://django-redis-svc:6379"
#}
#HTTP_PROXY = {
#value = "http://gluetun-svc.gluetun.svc:8888" }
DB_PASSWORD = {
value_from = {
secret_key_ref = {
name = "django-db-credentials"
key = "DB_PASSWORD"
}
}
}
POSTGRES_DB = {
value_from = {
secret_key_ref = {
name = "django-db-credentials"
key = "DB_DATABASE_NAME"
}
}
}
POSTGRES_USER = {
value_from = {
secret_key_ref = {
name = "django-db-credentials"
key = "DB_USERNAME"
}
}
}
POSTGRES_PASSWORD = {
value_from = {
secret_key_ref = {
name = "django-db-credentials"
key = "DB_PASSWORD"
}
}
}
DB_HOSTNAME = {
value_from = {
secret_key_ref = {
name = "django-db-credentials"
key = "DB_HOST"
}
}
}
}
pvc = {
kubeconfig-secret = {
secret = true
name = "kubeconfig"
mount_path = "/kubeconfig"
}
stash-django-pvc = {
host_path = "/ssd/stash/data-pvc/"
name = "stash-django-pvc"
pvc_size = "2Mi"
mount_path = "/stash"
}
}
}
celery-worker = {
enabled = false
connected_namespace = "django"
image = "gitea.tryton.geeraert.eu/pi-ux-ce/django-python:latest"
command = ["celery", "--workdir=django_code/", "-A", "core", "worker"]
secret_ref = ["django-bitwarden-credentials"]
pvc = {
#kubeconfig-secret = {
# secret = true
# name = "kubeconfig"
# mount_path = "/kubeconfig"
#}
stash-django-pvc = {
host_path = "/ssd/stash/data-pvc/"
name = "stash-django-pvc"
pvc_size = "2Mi"
mount_path = "/stash"
}
}
environment = {
CELERY_BROKER_URL = {
value = "redis://django-redis-svc:6379"
}
CELERY_IMPORTS = {
value = "stash_management.apps" }
}
HTTP_PROXY = {
value = "http://gluetun-svc.gluetun.svc:8888" }
PYTHONPATH = {
value = "/code/django_code/" }
}
django-testing = {
#enabled =false
image = "gitea.tryton.geeraert.eu/pi-ux-ce/django-testing:latest"
service_port = [8000]
database = {}
#redis = {}
requirements = {
limits-cpu = "800m"
limits-memory = "800Mi"
requests-cpu = "10m"
requests-memory = "300Mi"
}
extra_manifest = ["/opt/kubernetes/Terraform_kube/external_manifests/django/kubeconfig-testing.secret.yaml"]
secret_ref = ["django-bitwarden-credentials"]
secret_import = ["68dce7aa-8e5f-4483-9083-b474016e34fc"]
environment = {
ALLOWED_HOSTS = {
value = "django-testing.geeraert.eu,admin-testing.geeraert.eu,redirect-testing.geeraert.eu,streaming-testing.geeraert.eu,stash-testing.geeraert.eu,simpsons-testing.geeraert.eu,kubernetes-testing.geeraert.eu,cloudmanager-testing.geeraert.eu,podcast-testing.geeraert.eu"
}
CELERY_BROKER_URL = {
value = "redis://django-testing-redis-svc:6379"
}
DEBUG = {
value = "true"
}
DB_PORT = {
value = 5432
}
CUSTOM_DB_DATABASE = {
value = "cloudmanager" }
}
pvc = {
kubeconfig-secret = {
secret = true
name = "kubeconfig"
mount_path = "/kubeconfig"
}
}
}
celery-worker-testing = {
enabled = false
connected_namespace = "django-testing"
image = "gitea.tryton.geeraert.eu/pi-ux-ce/django-python:latest"
command = ["celery", "--workdir=Django_kube/django_code/", "-A", "core", "worker"]
secret_ref = ["django-bitwarden-credentials"]
environment = {
CELERY_BROKER_URL = {
value = "redis://django-testing-redis-svc:6379"
}
CELERY_IMPORTS = {
value = "stash_management.apps" }
}
HTTP_PROXY = {
value = "http://gluetun-svc.gluetun.svc:8888" }
PYTHONPATH = {
value = "/code/Django_kube/django_code/" }
}
keycloak = {
enabled = false
name = "keycloak"
@@ -2146,351 +1866,6 @@ kubernetes = {
}
bitwarden-admin = {
#enabled = false
namespace = "bitwarden"
replicas = 1
name = "bitwarden-admin"
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", "/opt/kubernetes/Terraform_kube/external_manifests/bitwarden/identity-svc.svc.yaml"]
service_port = [5000]
config_map_ref = ["global.env", "uid.env", "global.override.env"]
environment = {}
pvc = {
bitwarden-ca-certificates = {
pvc = true
pvc_size = "2Mi"
mount_path = "/etc/bitwarden/ca-certificates"
name = "bitwarden-ca-certificates"
}
bitwarden-core = {
pvc = true
pvc_size = "2Mi"
mount_path = "/etc/bitwarden/core"
name = "bitwarden-core"
}
bitwarden-logs = {
pvc = true
pvc_size = "2Mi"
mount_path = "/etc/bitwarden/logs"
name = "bitwarden-logs"
sub_path = "admin"
}
}
}
bitwarden-api = {
#enabled = false
connected_namespace = "bitwarden"
replicas = 1
name = "bitwarden-api"
image = "gitea.tryton.geeraert.eu/pi-ux-ce/bitbetter_api:2026.1.0"
service_port = [5000]
config_map_ref = ["global.env", "uid.env", "global.override.env"]
environment = {}
pvc = {
bitwarden-ca-certificates = {
pvc = true
pvc_size = "2Mi"
mount_path = "/etc/bitwarden/ca-certificates"
name = "bitwarden-ca-certificates"
}
bitwarden-core = {
pvc = true
pvc_size = "2Mi"
mount_path = "/etc/bitwarden/core"
name = "bitwarden-core"
}
bitwarden-logs = {
pvc = true
pvc_size = "2Mi"
mount_path = "/etc/bitwarden/logs"
name = "bitwarden-logs"
sub_path = "api"
}
}
}
bitwarden-attachments = {
#enabled = false
connected_namespace = "bitwarden"
replicas = 1
name = "bitwarden-attachments"
image = "ghcr.io/bitwarden/attachments:2026.1.0"
service_port = [5000]
config_map_ref = ["global.env", "uid.env"]
environment = {}
pvc = {
bitwarden-core = {
pvc = true
pvc_size = "2Mi"
mount_path = "/etc/bitwarden/core/attachments"
name = "bitwarden-core"
sub_path = "attachments"
}
}
}
bitwarden-events = {
#enabled = false
connected_namespace = "bitwarden"
replicas = 1
name = "bitwarden-events"
image = "ghcr.io/bitwarden/events:2026.1.0"
service_port = [5000]
config_map_ref = ["global.env", "uid.env", "global.override.env"]
environment = {}
pvc = {
bitwarden-ca-certificates = {
pvc = true
pvc_size = "2Mi"
mount_path = "/etc/bitwarden/ca-certificates"
name = "bitwarden-ca-certificates"
}
bitwarden-logs = {
pvc = true
pvc_size = "2Mi"
mount_path = "/etc/bitwarden/logs"
name = "bitwarden-logs"
sub_path = "events"
}
}
}
bitwarden-icons = {
#enabled = false
connected_namespace = "bitwarden"
replicas = 1
name = "bitwarden-icons"
image = "ghcr.io/bitwarden/icons:2026.1.0"
service_port = [5000]
config_map_ref = ["global.env", "uid.env"]
environment = {}
pvc = {
bitwarden-ca-certificates = {
pvc = true
pvc_size = "2Mi"
mount_path = "/etc/bitwarden/ca-certificates"
name = "bitwarden-ca-certificates"
}
bitwarden-logs = {
pvc = true
pvc_size = "2Mi"
mount_path = "/etc/bitwarden/logs"
name = "bitwarden-logs"
sub_path = "icons"
}
}
}
bitwarden-identity = {
#enabled = false
connected_namespace = "bitwarden"
replicas = 1
name = "bitwarden-identity"
image = "gitea.tryton.geeraert.eu/pi-ux-ce/bitbetter_identity:2026.1.0"
service_port = [5000]
config_map_ref = ["global.env", "uid.env", "global.override.env"]
environment = {}
pvc = {
bitwarden-identity = {
pvc = true
pvc_size = "2Mi"
mount_path = "/etc/bitwarden/identity"
name = "bitwarden-identity"
}
bitwarden-ca-certificates = {
pvc = true
pvc_size = "2Mi"
mount_path = "/etc/bitwarden/ca-certificates"
name = "bitwarden-ca-certificates"
}
bitwarden-core = {
pvc = true
pvc_size = "2Mi"
mount_path = "/etc/bitwarden/core"
name = "bitwarden-core"
}
bitwarden-logs = {
pvc = true
pvc_size = "2Mi"
mount_path = "/etc/bitwarden/logs"
name = "bitwarden-logs"
sub_path = "identity"
}
}
}
bitwarden-mssql = {
#enabled = false
connected_namespace = "bitwarden"
replicas = 1
name = "bitwarden-mssql"
image = "ghcr.io/bitwarden/mssql:2026.1.0"
service_port = [1433, 5000]
config_map_ref = ["mssql.env", "uid.env", "mssql.override.env"]
environment = {}
database = {
shunt = "true"
engine = "sqlserver"
username = "sa"
host = "bitwarden-mssql-svc"
name = "bitwarden_vault"
}
pvc = {
bitwarden-mssql = {
pvc = true
pvc_size = "2Mi"
mount_path = "/var/opt/mssql/data"
name = "bitwarden-mssql"
sub_path = "data"
}
bitwarden-logs = {
pvc = true
pvc_size = "2Mi"
mount_path = "/etc/bitwarden/logs"
name = "bitwarden-logs"
sub_path = "mssql"
}
}
}
bitwarden-nginx = {
#enabled = false
connected_namespace = "bitwarden"
replicas = 1
name = "bitwarden-nginx"
image = "ghcr.io/bitwarden/nginx:2026.1.0"
service_port = [5000, 8080, 8443]
config_map_ref = ["uid.env"]
environment = {}
pvc = {
bitwarden-nginx = {
pvc = true
pvc_size = "2Mi"
mount_path = "/etc/bitwarden/nginx"
name = "bitwarden-nginx"
}
bitwarden-letsencrypt = {
pvc = true
pvc_size = "2Mi"
mount_path = "/etc/letsencrypt"
name = "bitwarden-letsencrypt"
}
bitwarden-ssl = {
pvc = true
pvc_size = "2Mi"
mount_path = "/etc/ssl"
name = "bitwarden-ssl"
}
bitwarden-logs = {
pvc = true
pvc_size = "2Mi"
mount_path = "/var/log/nginx"
name = "bitwarden-logs"
sub_path = "nginx"
}
}
}
bitwarden-notifications = {
#enabled = false
connected_namespace = "bitwarden"
replicas = 1
name = "bitwarden-notifications"
image = "ghcr.io/bitwarden/notifications:2026.1.0"
service_port = [5000]
config_map_ref = ["global.env", "uid.env", "global.override.env"]
environment = {}
pvc = {
bitwarden-ca-certificates = {
pvc = true
pvc_size = "2Mi"
mount_path = "/etc/bitwarden/ca-certificates"
name = "bitwarden-ca-certificates"
}
bitwarden-logs = {
pvc = true
pvc_size = "2Mi"
mount_path = "/etc/bitwarden/logs"
name = "bitwarden-logs"
sub_path = "notifications"
}
}
}
bitwarden-sso = {
#enabled = false
connected_namespace = "bitwarden"
replicas = 1
name = "bitwarden-sso"
image = "ghcr.io/bitwarden/sso:2026.1.0"
service_port = [5000]
config_map_ref = ["global.env", "uid.env", "global.override.env"]
environment = {}
pvc = {
bitwarden-identity = {
pvc = true
pvc_size = "2Mi"
mount_path = "/etc/bitwarden/identity"
name = "bitwarden-identity"
}
bitwarden-core = {
pvc = true
pvc_size = "2Mi"
mount_path = "/etc/bitwarden/core"
name = "bitwarden-core"
}
bitwarden-ca-certificates = {
pvc = true
pvc_size = "2Mi"
mount_path = "/etc/bitwarden/ca-certificates"
name = "bitwarden-ca-certificates"
}
bitwarden-logs = {
pvc = true
pvc_size = "2Mi"
mount_path = "/etc/bitwarden/logs"
name = "bitwarden-logs"
sub_path = "sso"
}
}
}
bitwarden-web = {
#enabled = false
connected_namespace = "bitwarden"
replicas = 1
name = "bitwarden-web"
image = "ghcr.io/bitwarden/web:2026.1.0"
service_port = [5000]
config_map_ref = ["global.env", "uid.env"]
environment = {}
pvc = {
bitwarden-web = {
pvc = true
pvc_size = "2Mi"
mount_path = "/etc/bitwarden/web"
name = "bitwarden-web"
}
}
}
overleaf = {
enabled = false
#image = "sharelatex/sharelatex:6.1.2"
@@ -2556,66 +1931,6 @@ kubernetes = {
}
fail2ban = {
enabled = false
#image = "lscr.io/linuxserver/fail2ban:latest"
image = "gitea.tryton.geeraert.eu/pi-ux-ce/fail2ban:latest"
extra_manifest = ["/opt/kubernetes/Terraform_kube/external_manifests/fail2ban/fail2ban.RoleBinding.yaml", "/opt/kubernetes/Terraform_kube/external_manifests/fail2ban/fail2ban.Role.yaml", "/opt/kubernetes/Terraform_kube/external_manifests/fail2ban/fail2ban.ServiceAccount.yaml"]
service_account_name = "kubectl-service-account"
config_map_import = ["9d8ef71a-de74-478b-aa86-b3ee0160dc43", "50814edb-d190-41cb-8950-b3ee01622dcf", "fb11452e-fec1-489f-9144-b3ee0162ccda"]
environment = {
PUID = {
value = "1000"
}
PGID = {
value = "1000"
}
TZ = {
value = "Etc/UTC"
}
VERBOSITY = {
value = "-vv" }
}
security_context = true
pvc = {
fail2ban-config = {
pvc = true
pvc_size = "2Mi"
mount_path = "/config"
name = "fail2ban-config"
}
fail2ban-log = {
pvc = true
pvc_size = "2Mi"
mount_path = "/var/log"
name = "fail2ban-log"
}
nginx-fail2ban-logs = {
host_path = "/data/kubernetes/reverse-proxy/reverse-proxy-log/"
name = "nginx-fail2ban-logs"
pvc_size = "2Mi"
mount_path = "/remotelogs/nginx/"
}
fail2ban-nginx-http-auth-jail = {
config_map = true
name = "fail2ban-nginx-http-auth-jail"
pvc_size = "2Mi"
mount_path = "/config/fail2ban/jail.d/"
}
fail2ban-nginx-unauthorized-filter = {
config_map = true
name = "fail2ban-nginx-unauthorized-filter"
pvc_size = "2Mi"
mount_path = "/config/fail2ban/filter.d/"
}
}
}
reactive = {
#disabled because it needs AI to import a pdf and AI integration is not working
enabled = false
@@ -2745,100 +2060,6 @@ kubernetes = {
}
}
netdatat = {
image = "debian"
enabled = false
service_port = [19999]
domain_name = "netdata"
command = ["sleep", "3600"]
security_context = true
environment = {
NETDATA_CLAIM_TOKEN = {
value = "wN6wJV1M5jvLbcpQTT78s0WRWiCkxz-s4l9tzeIqwA86upIkVSTk6TbaPbA5L6h_5HH9LoemluBqSPAGzi8DnJ2LBp4e8JGRVuWwOv8EWcKfrV0winCPce4xXtuD780KUW5CR6k"
}
NETDATA_CLAIM_URL = {
value = "https://app.netdata.cloud"
}
NETDATA_CLAIM_ROOMS = {
value = "28654d7b-4767-4b8e-bddc-8d134624bb3b"
}
}
pvc = {
netdata-config = {
name = "netdata-config"
pvc = true
pvc_size = "1Gi"
mount_path = "/etc/netdata"
}
netdata-lib = {
name = "netdata-lib"
pvc = true
pvc_size = "1Gi"
mount_path = "/var/lib/netdata"
}
netdata-cache = {
name = "netdata-cache"
pvc = true
pvc_size = "1Gi"
mount_path = "/var/cache/netdata"
}
netdata-host-root = {
host_path = "/"
name = "netdata-host-root"
mount_path = "/host/root"
}
netdata-host-passwd = {
host_path = "/etc/passwd"
name = "netdata-host-passwd"
mount_path = "/host/etc/passwd"
}
netdata-host-group = {
host_path = "/etc/group"
name = "netdata-host-group"
mount_path = "/host/etc/group"
}
netdata-host-localtime = {
host_path = "/etc/localtime"
name = "netdata-host-localtime"
mount_path = "/etc/localtime"
}
netdata-host-proc = {
host_path = "/proc"
name = "netdata-host-proc"
mount_path = "/host/proc"
}
netdata-host-sys = {
host_path = "/sys"
name = "netdata-host-sys"
mount_path = "/host/sys"
}
netdata-host-os-release = {
host_path = "/etc/os-release"
name = "netdata-host-os-release"
mount_path = "/host/etc/os-release"
}
netdata-host-var-log = {
host_path = "/var/log"
name = "netdata-host-var-log"
mount_path = "/host/var/log"
}
netdata-docker-sock = {
host_path = "/var/run/docker.sock"
name = "netdata-docker-sock"
mount_path = "/var/run/docker.sock"
}
netdata-host-dbus = {
host_path = "/run/dbus"
name = "netdata-host-dbus"
mount_path = "/run/dbus"
}
}
}
kopia = {
enabled = false
replicas = 01
+134
View File
@@ -0,0 +1,134 @@
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)) && value.docker != true }
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" {
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 "docker_container" "database-automatic" {
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 }
image = try(each.value.database.image, "docker.io/library/postgres:latest")
name = "${coalesce(each.value.name, each.key)}-db"
hostname = "${coalesce(each.value.name, each.key)}-db"
networks_advanced {
name = docker_network.terraform_network[0].name
}
#no ports as they should be able to speak within the same network
volumes {
container_path = try(each.value.database.mountPath, "/var/lib/postgresql/")
host_path = each.value.database.host_path
}
env = [
for key, value in(each.value.environment != null ? each.value.environment : {}) :
"${key}=${value.value != null ? value.value : ""}"
]
}
+250
View File
@@ -0,0 +1,250 @@
resource "kubernetes_deployment_v1" "automatic" {
for_each = { for key, value in var.kubernetes : key => value if value.enabled == true && value.docker != 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.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"])
}
}
}
}
}
}
}
resource "docker_container" "deployment-automatic" {
for_each = { for key, value in var.kubernetes : key => value if value.enabled == true && value.docker == true }
image = each.value.image
name = coalesce(each.value.name, each.key)
hostname = coalesce(each.value.name, each.key)
depends_on = [docker_container.database-automatic]
networks_advanced {
name = "deployment_network"
}
dynamic "ports" {
for_each = each.value.service_port != null ? each.value.service_port : []
content {
internal = ports.value
external = each.value.external_port ? ports.value : null
}
}
dynamic "volumes" {
for_each = each.value.pvc != null ? each.value.pvc : {}
content {
container_path = volumes.value.mount_path
host_path = volumes.value.host_path
}
}
env = [
for key, value in(each.value.environment != null ? each.value.environment : {}) :
"${key}=${value.value != null ? value.value : ""}"
]
# null keeps the image's default command; [] would differ from it in state and force replacement
command = each.value.command
}
+136
View File
@@ -0,0 +1,136 @@
terraform {
required_version = "> 0.8.0"
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "4.6.0"
}
}
}
provider "kubernetes" {
config_path = "~/.kube/config"
}
provider "docker" {
host = "unix:///var/run/docker.sock"
}
variable "kubernetes" {
type = map(object({
name = optional(string)
docker = optional(bool)
image = string
pvc = optional(map(object({
name = optional(string)
config_map = optional(bool, false)
secret = optional(bool, false)
local_path = optional(bool, false)
host_path = optional(string)
storage_class_name = optional(string, "nfs-storage-intelligent")
annotations_fileType = optional(string)
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))
external_port = optional(bool, false)
service_type = optional(string, "ClusterIP")
service_name = optional(string)
domain_name = optional(string)
liveness_tcp_socket = optional(number)
liveness_http_get = optional(string)
liveness_http_get_path = optional(string)
database = optional(map(string))
database_command = optional(list(string))
database_args = optional(list(string))
redis = optional(map(string))
enabled = optional(bool, true)
secret_ref = optional(list(string))
config_map_ref = optional(list(string))
config_map_import = optional(list(string))
secret_import = optional(list(string))
extra_manifest = optional(list(string))
requirements = optional(map(string))
dns_nameservers = optional(string)
service_account_name = optional(string)
environment_variables = optional(map(string), { name = "value" })
security_context = optional(bool, false)
}))
}
variable "shunt_docker" {
type = bool
default = true
}
variable "storage_path" {
type = map(string)
default = {
main_storage = "/data/kubernetes",
fast_access = "/ssd"
}
}
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 {
kubernetes_manifests = flatten([
for k, obj in var.kubernetes : [
for index, manifest in(obj.extra_manifest != null ? obj.extra_manifest : []) :
{
key = "${k}_${index}"
name = obj.name
manifest = manifest
enabled = obj.enabled
}
if obj.enabled == true
]
])
}
resource "kubernetes_manifest" "manifest" {
for_each = { for item in local.kubernetes_manifests : item.key => item }
manifest = yamldecode(file(each.value.manifest))
provider = kubernetes
}
resource "kubernetes_namespace_v1" "automatic" {
for_each = { for key, value in var.kubernetes : key => value if value.enabled == true && value.connected_namespace == "" }
metadata {
annotations = {
name = coalesce(each.value.namespace, each.key)
}
labels = {
deployment_method = "Terraform"
}
name = coalesce(each.value.namespace, each.key)
}
}
+125
View File
@@ -0,0 +1,125 @@
resource "kubernetes_deployment_v1" "redis-automatic" {
for_each = { for key, value in var.kubernetes : key => value if value.redis != null && value.enabled == true && value.docker != 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
# 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-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"])]))
}
}
}
}
}
}
+91
View File
@@ -0,0 +1,91 @@
resource "kubernetes_service_v1" "automatic_service" {
for_each = { for key, value in var.kubernetes : 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 : 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 : 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
}
}
}
resource "docker_network" "terraform_network" {
#avoiding this to create if the shunt_docker is on
count = var.shunt_docker ? 0 : 1
name = "deployment_network"
}
View File
+33
View File
@@ -0,0 +1,33 @@
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
+398
View File
@@ -0,0 +1,398 @@
kubernetes = {
reverse-proxy = {
#enabled = false
#docker = true
image = "nginx:latest"
service_port = [80, 443]
service_type = "NodePort"
external_port = true
pvc = {
sites-terraform = {
#requires to run the reverse proxy terraform with the kubernetes enabled
mount_path = "/etc/nginx/conf.d/"
host_path = "/data/kubernetes/reverse-proxy/reverse-proxy-sites"
config_map = sites-terraform
}
reverse-proxy-log = {
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"
}
}
}
gitea = {
#enabled = false
#docker = true
image = "gitea/gitea:1.27.0"
service_port = [3000]
# no service_port: nginx reaches http://gitea:3000 over deployment_network
database = {
image = "postgres:17"
mountPath = "/var/lib/postgresql/data"
host_path = "/data/kubernetes/gitea/gitea-db-data"
}
# shared by the gitea and gitea-db containers (the db ignores GITEA__*, gitea ignores POSTGRES_*)
environment = {
POSTGRES_USER = { value = "gitea-KY56Q" }
POSTGRES_PASSWORD = { value = "Modulator-Yearning-Gills3" }
POSTGRES_DB = { value = "gitea-database" }
GITEA__database__DB_TYPE = { value = "postgres" }
#GITEA__database__HOST = { value = "gitea-db:5432" } # for docker
GITEA__database__HOST = { value = "gitea-db-svc:5432" } # for k8s
GITEA__database__USER = { value = "gitea-KY56Q" }
GITEA__database__PASSWD = { value = "Modulator-Yearning-Gills3" }
GITEA__database__NAME = { value = "gitea-database" }
}
pvc = {
gitea-data = {
name = "gitea-data"
mount_path = "/data"
host_path = "/data/kubernetes/gitea/gitea-data"
}
gitea-documents-backup = {
name = "gitea-documents-backup"
mount_path = "/backup"
host_path = "/data/kubernetes/gitea/gitea-documents-backup"
}
}
}
gitea-runner = {
#enabled = false
#docker = true
image = "gitea/act_runner:latest"
connected_namespace = "gitea"
environment = {
GITEA_INSTANCE_URL = { value = "https://gitea.geeraert.eu/" }
GITEA_RUNNER_REGISTRATION_TOKEN = { value = "rqi4mFW8LXoc5MhIrUD1rjzdmKVY8n9X14BP6sWd" }
GITEA_RUNNER_NAME = { value = "runner" }
GITEA_RUNNER_LABELS = { value = "label" }
}
pvc = {
gitea-runner-data = {
name = "gitea-runner-data"
mount_path = "/data"
host_path = "/data/kubernetes/gitea/gitea-runner-data"
}
docker-sock = {
name = "docker-sock"
mount_path = "/var/run/docker.sock"
host_path = "/var/run/docker.sock"
}
}
}
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 = {
#enabled = false
namespace = "bitwarden"
replicas = 1
name = "bitwarden-admin"
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"]
service_port = [5000]
config_map_ref = ["global.env", "uid.env", "global.override.env"]
environment = {}
pvc = {
bitwarden-ca-certificates-pvc = {
mount_path = "/etc/bitwarden/ca-certificates"
}
bitwarden-core-pvc = {
mount_path = "/etc/bitwarden/core"
}
bitwarden-logs-pvc = {
mount_path = "/etc/bitwarden/logs"
sub_path = "admin"
}
}
}
bitwarden-api = {
#enabled = false
connected_namespace = "bitwarden"
replicas = 1
name = "bitwarden-api"
image = "gitea.tryton.geeraert.eu/pi-ux-ce/bitbetter_api:2026.1.0"
service_port = [5000]
config_map_ref = ["global.env", "uid.env", "global.override.env"]
environment = {}
pvc = {
bitwarden-ca-certificates-pvc = {
mount_path = "/etc/bitwarden/ca-certificates"
}
bitwarden-core-pvc = {
mount_path = "/etc/bitwarden/core"
}
bitwarden-logs-pvc = {
mount_path = "/etc/bitwarden/logs"
sub_path = "api"
}
}
}
bitwarden-attachments = {
#enabled = false
connected_namespace = "bitwarden"
replicas = 1
name = "bitwarden-attachments"
image = "ghcr.io/bitwarden/attachments:2026.1.0"
service_port = [5000]
config_map_ref = ["global.env", "uid.env"]
environment = {}
pvc = {
bitwarden-core-pvc = {
mount_path = "/etc/bitwarden/core/attachments"
sub_path = "attachments"
}
}
}
bitwarden-events = {
#enabled = false
connected_namespace = "bitwarden"
replicas = 1
name = "bitwarden-events"
image = "ghcr.io/bitwarden/events:2026.1.0"
service_port = [5000]
config_map_ref = ["global.env", "uid.env", "global.override.env"]
environment = {}
pvc = {
bitwarden-ca-certificates-pvc = {
mount_path = "/etc/bitwarden/ca-certificates"
}
bitwarden-logs-pvc = {
mount_path = "/etc/bitwarden/logs"
sub_path = "events"
}
}
}
bitwarden-icons = {
#enabled = false
connected_namespace = "bitwarden"
replicas = 1
name = "bitwarden-icons"
image = "ghcr.io/bitwarden/icons:2026.1.0"
service_port = [5000]
config_map_ref = ["global.env", "uid.env"]
environment = {}
pvc = {
bitwarden-ca-certificates-pvc = {
mount_path = "/etc/bitwarden/ca-certificates"
}
bitwarden-logs-pvc = {
mount_path = "/etc/bitwarden/logs"
sub_path = "icons"
}
}
}
bitwarden-identity = {
#enabled = false
connected_namespace = "bitwarden"
replicas = 1
name = "bitwarden-identity"
image = "gitea.tryton.geeraert.eu/pi-ux-ce/bitbetter_identity:2026.1.0"
service_port = [5000]
config_map_ref = ["global.env", "uid.env", "global.override.env"]
environment = {}
pvc = {
bitwarden-identity-pvc = {
mount_path = "/etc/bitwarden/identity"
}
bitwarden-ca-certificates-pvc = {
mount_path = "/etc/bitwarden/ca-certificates"
}
bitwarden-core-pvc = {
mount_path = "/etc/bitwarden/core"
}
bitwarden-logs-pvc = {
mount_path = "/etc/bitwarden/logs"
sub_path = "identity"
}
}
}
bitwarden-mssql = {
#enabled = false
connected_namespace = "bitwarden"
replicas = 1
name = "bitwarden-mssql"
image = "ghcr.io/bitwarden/mssql:2026.1.0"
service_port = [1433, 5000]
config_map_ref = ["mssql.env", "uid.env", "mssql.override.env"]
environment = {}
database = {
shunt = "true"
engine = "sqlserver"
username = "sa"
host = "bitwarden-mssql-svc"
name = "bitwarden_vault"
}
pvc = {
bitwarden-mssql-pvc = {
mount_path = "/var/opt/mssql/data"
sub_path = "data"
}
bitwarden-logs-pvc = {
mount_path = "/etc/bitwarden/logs"
sub_path = "mssql"
}
}
}
bitwarden-nginx = {
#enabled = false
connected_namespace = "bitwarden"
replicas = 1
name = "bitwarden-nginx"
image = "ghcr.io/bitwarden/nginx:2026.1.0"
service_port = [5000, 8080, 8443]
config_map_ref = ["uid.env"]
environment = {}
pvc = {
bitwarden-nginx-pvc = {
mount_path = "/etc/bitwarden/nginx"
}
bitwarden-letsencrypt-pvc = {
mount_path = "/etc/letsencrypt"
}
bitwarden-ssl-pvc = {
mount_path = "/etc/ssl"
}
bitwarden-logs-pvc = {
mount_path = "/var/log/nginx"
sub_path = "nginx"
}
}
}
bitwarden-notifications = {
#enabled = false
connected_namespace = "bitwarden"
replicas = 1
name = "bitwarden-notifications"
image = "ghcr.io/bitwarden/notifications:2026.1.0"
service_port = [5000]
config_map_ref = ["global.env", "uid.env", "global.override.env"]
environment = {}
pvc = {
bitwarden-ca-certificates-pvc = {
mount_path = "/etc/bitwarden/ca-certificates"
name = "bitwarden-ca-certificates-pvc"
}
bitwarden-logs-pvc = {
mount_path = "/etc/bitwarden/logs"
sub_path = "notifications"
}
}
}
bitwarden-sso = {
#enabled = false
connected_namespace = "bitwarden"
replicas = 1
name = "bitwarden-sso"
image = "ghcr.io/bitwarden/sso:2026.1.0"
service_port = [5000]
config_map_ref = ["global.env", "uid.env", "global.override.env"]
environment = {}
pvc = {
bitwarden-identity-pvc = {
mount_path = "/etc/bitwarden/identity"
}
bitwarden-core-pvc = {
mount_path = "/etc/bitwarden/core"
}
bitwarden-ca-certificates-pvc = {
mount_path = "/etc/bitwarden/ca-certificates"
}
bitwarden-logs-pvc = {
mount_path = "/etc/bitwarden/logs"
sub_path = "sso"
}
}
}
bitwarden-web = {
#enabled = false
connected_namespace = "bitwarden"
replicas = 1
name = "bitwarden-web"
image = "ghcr.io/bitwarden/web:2026.1.0"
service_port = [5000]
config_map_ref = ["global.env", "uid.env"]
environment = {}
pvc = {
bitwarden-web-pvc = {
mount_path = "/etc/bitwarden/web"
}
}
}
}
@@ -0,0 +1,9 @@
globalSettings__duo__aKey=p9jCHtnG4NZNZu4SThpVlCuOF1oePGhu53Wa4RJwuyeqRAWQ0aJN7GsKYrGbYIYO
globalSettings__hibpApiKey=REPLACE
globalSettings__identityServer__certificatePassword=test
globalSettings__installation__key=CtQE5U1tMJE4Dzk7N9DU
globalSettings__internalIdentityKey=I5TMbqmEjhw9uBNmFZ9rU6s1KN5xqAKXh7RSPfgyj2XQ4sjlP22SCupFn4IVhYX7
globalSettings__mail__smtp__password=vmxkiidikqwirpuh
globalSettings__oidcIdentityClientKey=w47pWOkPa6mrTkiPuKizitsiRTR6NH8ufI01u77zbZt3LUcKWJ4wchMn6ouiwN7V
globalSettings__sqlServer__connectionString=Data Source=tcp:bitwarden-mssql-svc,1433;Initial Catalog=bitwarden_vault;Persist Security Info=False;User ID=sa;Password=ChQKWDIW73eSHzX1UyvGDAv4pFw6DVKM;MultipleActiveResultSets=False;Connect Timeout=30;Encrypt=True;TrustServerCertificate=True
globalSettings__yubico__key=REPLACE
@@ -0,0 +1 @@
SA_PASSWORD=ChQKWDIW73eSHzX1UyvGDAv4pFw6DVKM
+195
View File
@@ -0,0 +1,195 @@
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_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-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 : 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"
}
}
}
}
}
}
}
}
+274
View File
@@ -0,0 +1,274 @@
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]
}
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.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"])
}
}
}
}
}
}
}
+203
View File
@@ -0,0 +1,203 @@
terraform {
required_version = "> 0.8.0"
required_providers {
bitwarden-secrets = {
source = "bitwarden/bitwarden-secrets"
version = "0.5.4-pre"
}
}
}
provider "kubernetes" {
config_path = "~/.kube/config"
}
provider "bitwarden-secrets" {
api_url = "https://bitwarden.tryton.geeraert.eu/api"
identity_url = "https://bitwarden.tryton.geeraert.eu/identity"
access_token = "0.9f4b7c5f-e6e7-4eff-929e-b474016a2b9c.bMRELajGGb7qMuXXvzgCCJdDfxfTCS:mFDT7tHSi43KJSnkwvTSYg=="
organization_id = "a6361589-badd-4bde-9cb4-af8901161c0d"
}
variable "kubernetes" {
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))
service_type = optional(string, "ClusterIP")
service_name = optional(string)
domain_name = optional(string)
liveness_tcp_socket = optional(number)
liveness_http_get = optional(string)
liveness_http_get_path = optional(string)
database = optional(map(string))
database_command = optional(list(string))
database_args = optional(list(string))
redis = optional(map(string))
enabled = optional(bool, true)
secret_ref = optional(list(string))
config_map_ref = optional(list(string))
config_map_import = optional(list(string))
secret_import = optional(list(string))
extra_manifest = optional(list(string))
requirements = optional(map(string))
# requirements = optional(map(string), {
# limits-cpu = "800m"
# limits-memory = "500Mi"
# requests-cpu = "200m"
# requests-memory = "200Mi"
# })
dns_nameservers = optional(string)
service_account_name = optional(string)
environment_variables = optional(map(string), { name = "value" })
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"
}
}
}
variable "storage_path" {
type = map(string)
default = {
main_storage = "/data/kubernetes",
fast_access = "/ssd"
}
}
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" {
for_each = { for key, value in var.kubernetes : key => value if value.enabled == true && value.connected_namespace == "" }
metadata {
annotations = {
name = coalesce(each.value.namespace, each.key)
}
labels = {
deployment_method = "Terraform"
}
name = coalesce(each.value.namespace, each.key)
}
}
locals {
kubernetes_manifests = flatten([
for k, obj in var.kubernetes : [
for index, manifest in(obj.extra_manifest != null ? obj.extra_manifest : []) :
{
key = "${k}_${index}"
name = obj.name
manifest = manifest
enabled = obj.enabled
}
if obj.enabled == true
]
])
}
resource "kubernetes_manifest" "manifest" {
for_each = { for item in local.kubernetes_manifests : item.key => item }
manifest = yamldecode(file(each.value.manifest))
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
# }
#
# }
+142
View File
@@ -0,0 +1,142 @@
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" "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-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
# 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-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"])]))
}
}
}
}
}
}
+198
View File
@@ -0,0 +1,198 @@
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"
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
+380
View File
@@ -0,0 +1,380 @@
kubernetes = {
gluetun = {
#enabled = false
dns_nameservers = "1.1.1.1"
replicas = 01
image = "qmcgaw/gluetun:latest"
service_port = [8888]
#extra_manifest = ["/opt/kubernetes/Terraform_kube/external_manifests/gluetun/gluetun-secret-netherlandNL-FREE-280.yaml"]
secret_import = ["5527ba11-07e3-415b-8d1f-b3ee0154eb56", "b0d22160-d81a-4702-a3dd-b40e0168d617", "643dbe99-ace0-4ef5-8a2e-b44f014dccb0"]
security_context = true
# requirements = {
# limits-cpu = "800Mi"
# limits-memory = "800Mi"
# requests-cpu = "800Mi"
# requests-memory = "800Mi"
# }
environment = {
WIREGUARD_PRIVATE_KEY = {
value_from = {
secret_key_ref = {
name = "gluetun-secret-nl-free-280"
key = "WIREGUARD_PRIVATE_KEY"
}
}
}
HTTPPROXY = {
value = "on"
}
HTTPPROXY_LOG = {
value = "on"
}
HTTPPROXY_LISTENING_ADDRESS = {
value = "0.0.0.0:8888"
}
# DNS_KEEP_NAMESERVER = {
# value = "on"
# }
VPN_SERVICE_PROVIDER = {
value = "protonvpn"
}
VPN_TYPE = {
value = "wireguard"
}
SERVER_COUNTRIES = {
value = "Netherlands"
}
HEALTH_TARGET_ADDRESS = {
value = "0.0.0.0:8888"
}
FREE_ONLY = {
value = "on"
}
# WIREGUARD_ADDRESSES = {
# value = "10.2.0.2/32"
# }
FIREWALL_INPUT_PORTS = {
value = "8081,7878,9696,9091,51413,8080,6881,8989,8191,8888,8000"
}
PUBLICIP_API = {
value = "ip2location"
}
# HEALTH_TARGET_ADDRESS = {
# value = "protonvpn.com:80"
# }
# FIREWALL_OUTBOUND_SUBNETS = {
# value = "10.0.0.0/24" }
}
}
django = {
enabled = false
namespace = "django"
image = "gitea.tryton.geeraert.eu/pi-ux-ce/django-python:latest"
service_port = [8000]
database = {
image = "docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0"
username = "django_username"
mountPath = "/var/lib/postgresql/data"
}
#redis = {}
secret_ref = ["django-bitwarden-credentials"]
secret_import = ["9fc5a725-75f5-4bab-b595-b474017146c3"]
requirements = {
limits-cpu = "800m"
limits-memory = "800Mi"
requests-cpu = "10m"
requests-memory = "300Mi"
}
extra_manifest = ["/opt/kubernetes/Terraform_kube/external_manifests/django/kubeconfig.secret.yaml", "/opt/kubernetes/Terraform_kube/external_manifests/django/django-db.secret.yaml"]
environment = {
ALLOWED_HOSTS = {
value = "django.geeraert.eu,admin.geeraert.eu,redirect.geeraert.eu,streaming.geeraert.eu,stash.geeraert.eu,simpsons.geeraert.eu,kubernetes.geeraert.eu,cloudmanager.geeraert.eu,podcast.geeraert.eu"
}
DEBUG = {
value = "False"
}
ENVIRONMENT = {
value = "PRODUCTION"
}
#CELERY_BROKER_URL = {
# value = "redis://django-redis-svc:6379"
#}
#HTTP_PROXY = {
#value = "http://gluetun-svc.gluetun.svc:8888" }
DB_PASSWORD = {
value_from = {
secret_key_ref = {
name = "django-db-credentials"
key = "DB_PASSWORD"
}
}
}
POSTGRES_DB = {
value_from = {
secret_key_ref = {
name = "django-db-credentials"
key = "DB_DATABASE_NAME"
}
}
}
POSTGRES_USER = {
value_from = {
secret_key_ref = {
name = "django-db-credentials"
key = "DB_USERNAME"
}
}
}
POSTGRES_PASSWORD = {
value_from = {
secret_key_ref = {
name = "django-db-credentials"
key = "DB_PASSWORD"
}
}
}
DB_HOSTNAME = {
value_from = {
secret_key_ref = {
name = "django-db-credentials"
key = "DB_HOST"
}
}
}
}
pvc = {
kubeconfig-secret = {
secret = true
name = "kubeconfig"
mount_path = "/kubeconfig"
}
stash-django-pvc = {
host_path = "/ssd/stash/data-pvc/"
name = "stash-django-pvc"
pvc_size = "2Mi"
mount_path = "/stash"
}
}
}
django-testing = {
#enabled = false
image = "gitea.tryton.geeraert.eu/pi-ux-ce/django-testing:latest"
service_port = [8000]
database = {}
#redis = {}
requirements = {
limits-cpu = "800m"
limits-memory = "800Mi"
requests-cpu = "10m"
requests-memory = "300Mi"
}
extra_manifest = ["../external_manifests/django/kubeconfig-testing.secret.yaml"]
secret_ref = ["django-bitwarden-credentials"]
secret_import = ["68dce7aa-8e5f-4483-9083-b474016e34fc"]
environment = {
ALLOWED_HOSTS = {
value = "django-testing.geeraert.eu,admin-testing.geeraert.eu,redirect-testing.geeraert.eu,streaming-testing.geeraert.eu,stash-testing.geeraert.eu,simpsons-testing.geeraert.eu,kubernetes-testing.geeraert.eu,cloudmanager-testing.geeraert.eu,podcast-testing.geeraert.eu"
}
CELERY_BROKER_URL = {
value = "redis://django-testing-redis-svc:6379"
}
DEBUG = {
value = "true"
}
DB_PORT = {
value = 5432
}
CUSTOM_DB_DATABASE = {
value = "cloudmanager" }
}
pvc = {
kubeconfig = {
secret = true
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"
}
}
fail2ban = {
enabled = false
#image = "lscr.io/linuxserver/fail2ban:latest"
image = "gitea.tryton.geeraert.eu/pi-ux-ce/fail2ban:latest"
extra_manifest = ["/opt/kubernetes/Terraform_kube/external_manifests/fail2ban/fail2ban.RoleBinding.yaml", "/opt/kubernetes/Terraform_kube/external_manifests/fail2ban/fail2ban.Role.yaml", "/opt/kubernetes/Terraform_kube/external_manifests/fail2ban/fail2ban.ServiceAccount.yaml"]
service_account_name = "kubectl-service-account"
config_map_import = ["9d8ef71a-de74-478b-aa86-b3ee0160dc43", "50814edb-d190-41cb-8950-b3ee01622dcf", "fb11452e-fec1-489f-9144-b3ee0162ccda"]
environment = {
PUID = {
value = "1000"
}
PGID = {
value = "1000"
}
TZ = {
value = "Etc/UTC"
}
VERBOSITY = {
value = "-vv" }
}
security_context = true
pvc = {
fail2ban-config = {
pvc = true
pvc_size = "2Mi"
mount_path = "/config"
name = "fail2ban-config"
}
fail2ban-log = {
pvc = true
pvc_size = "2Mi"
mount_path = "/var/log"
name = "fail2ban-log"
}
nginx-fail2ban-logs = {
host_path = "/data/kubernetes/reverse-proxy/reverse-proxy-log/"
name = "nginx-fail2ban-logs"
pvc_size = "2Mi"
mount_path = "/remotelogs/nginx/"
}
fail2ban-nginx-http-auth-jail = {
config_map = true
name = "fail2ban-nginx-http-auth-jail"
pvc_size = "2Mi"
mount_path = "/config/fail2ban/jail.d/"
}
fail2ban-nginx-unauthorized-filter = {
config_map = true
name = "fail2ban-nginx-unauthorized-filter"
pvc_size = "2Mi"
mount_path = "/config/fail2ban/filter.d/"
}
}
}
netdatat = {
image = "debian"
enabled = false
service_port = [19999]
domain_name = "netdata"
command = ["sleep", "3600"]
security_context = true
environment = {
NETDATA_CLAIM_TOKEN = {
value = "wN6wJV1M5jvLbcpQTT78s0WRWiCkxz-s4l9tzeIqwA86upIkVSTk6TbaPbA5L6h_5HH9LoemluBqSPAGzi8DnJ2LBp4e8JGRVuWwOv8EWcKfrV0winCPce4xXtuD780KUW5CR6k"
}
NETDATA_CLAIM_URL = {
value = "https://app.netdata.cloud"
}
NETDATA_CLAIM_ROOMS = {
value = "28654d7b-4767-4b8e-bddc-8d134624bb3b"
}
}
pvc = {
netdata-config = {
name = "netdata-config"
pvc = true
pvc_size = "1Gi"
mount_path = "/etc/netdata"
}
netdata-lib = {
name = "netdata-lib"
pvc = true
pvc_size = "1Gi"
mount_path = "/var/lib/netdata"
}
netdata-cache = {
name = "netdata-cache"
pvc = true
pvc_size = "1Gi"
mount_path = "/var/cache/netdata"
}
netdata-host-root = {
host_path = "/"
name = "netdata-host-root"
mount_path = "/host/root"
}
netdata-host-passwd = {
host_path = "/etc/passwd"
name = "netdata-host-passwd"
mount_path = "/host/etc/passwd"
}
netdata-host-group = {
host_path = "/etc/group"
name = "netdata-host-group"
mount_path = "/host/etc/group"
}
netdata-host-localtime = {
host_path = "/etc/localtime"
name = "netdata-host-localtime"
mount_path = "/etc/localtime"
}
netdata-host-proc = {
host_path = "/proc"
name = "netdata-host-proc"
mount_path = "/host/proc"
}
netdata-host-sys = {
host_path = "/sys"
name = "netdata-host-sys"
mount_path = "/host/sys"
}
netdata-host-os-release = {
host_path = "/etc/os-release"
name = "netdata-host-os-release"
mount_path = "/host/etc/os-release"
}
netdata-host-var-log = {
host_path = "/var/log"
name = "netdata-host-var-log"
mount_path = "/host/var/log"
}
netdata-docker-sock = {
host_path = "/var/run/docker.sock"
name = "netdata-docker-sock"
mount_path = "/var/run/docker.sock"
}
netdata-host-dbus = {
host_path = "/run/dbus"
name = "netdata-host-dbus"
mount_path = "/run/dbus"
}
}
}
}
-18
View File
@@ -1,18 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: screeps
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: screeps-storage
namespace: screeps
spec:
storageClassName: nfs-storage-intelligent
accessModes:
- ReadWriteMany
resources:
requests:
storage: 20Gi
+83
View File
@@ -0,0 +1,83 @@
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
@@ -0,0 +1,144 @@
############################################
# 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 ~}
+433
View File
@@ -0,0 +1,433 @@
nginx_sites = {
bitwarden = {
service = "bitwarden-nginx-svc.bitwarden.svc:8080"
http2_bool = true
redirect_to_root_domain = false
}
bookstack = {
enabled = false
service = "bookstack-svc.bookstack.svc"
proxy_cache = false
}
django = {
enabled = false
service = "django-svc.django:8000"
proxy_cache = true
http2_bool = true
}
admin = {
enabled = false
service = "django-svc.django:8000"
proxy_cache = true
http2_bool = true
}
redirect = {
enabled = false
service = "django-svc.django:8000"
proxy_cache = true
http2_bool = true
}
streaming = {
enabled = false
service = "django-svc.django:8000"
proxy_cache = true
http2_bool = true
}
stash = {
enabled = false
service = "django-svc.django:8000"
proxy_cache = true
http2_bool = true
}
simpsons = {
enabled = false
service = "django-svc.django:8000"
proxy_cache = true
http2_bool = true
}
kubernetes = {
enabled = false
service = "django-svc.django:8000"
proxy_cache = true
http2_bool = true
}
cloudmanager = {
enabled = false
service = "django-svc.django:8000"
proxy_cache = true
http2_bool = true
}
podcast = {
enabled = false
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-svc.echo.svc"
docker_service = "echo-svc.echo.svc"
proxy_cache = true
http2_bool = true
}
sonarr = {
enabled = false
service = "sonarr-svc.servarr.svc:8989"
geoip_allow = ["FR", "GB", "NL"]
}
nextcloud = {
enabled = false
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 = {
enabled = false
service = "192.168.88.1"
authentication_required = true
}
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
}
paperless = {
enabled = false
#service = "webserver.paperless.svc:8000"
service = "paperless-svc.paperless.svc:8000"
}
pihole = {
enabled = false
service = "172.16.0.60:8081"
enabled = false
}
prowlarr = {
enabled = false
service = "prowlarr-svc.servarr.svc:9696"
geoip_allow = ["FR", "GB", "NL"]
}
qbittorrent = {
enabled = false
service = "qbittorrent-svc.servarr.svc:8080"
geoip_allow = ["FR", "GB", "NL"]
}
radarr = {
enabled = false
service = "radarr-svc.servarr.svc:7878"
geoip_allow = ["FR", "GB", "NL"]
}
unifi = {
enabled = false
# service = "unifi.unifi.svc:8443"
service = "192.168.88.244:8443"
proxy_pass_https = true
}
unifi-inform = {
enabled = false
service = "192.168.88.50:8082"
}
immich = {
enabled = false
#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
}
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
}
openmediavault = {
service = "192.168.88.29"
}
pihole = {
enabled = false
service = "web.piholenew.svc"
}
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
}
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
}
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
}
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
}
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
}
}
deny_ip = ["1.2.3.4"]
-26638
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long