diff --git a/stacks/actualbudget/main.tf b/stacks/actualbudget/main.tf index b257e549..db6c5bff 100644 --- a/stacks/actualbudget/main.tf +++ b/stacks/actualbudget/main.tf @@ -2,12 +2,17 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "actualbudget_credentials" { - type = map(any) - sensitive = true -} variable "nfs_server" { type = string } +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "actualbudget" +} + +locals { + credentials = jsondecode(data.vault_kv_secret_v2.secrets.data["credentials"]) +} + # To create a new deployment: /** @@ -42,8 +47,8 @@ module "viktor" { nfs_server = var.nfs_server depends_on = [kubernetes_namespace.actualbudget] tier = local.tiers.edge - budget_encryption_password = lookup(var.actualbudget_credentials["viktor"], "password", null) - sync_id = lookup(var.actualbudget_credentials["viktor"], "sync_id", null) + budget_encryption_password = lookup(local.credentials["viktor"], "password", null) + sync_id = lookup(local.credentials["viktor"], "sync_id", null) homepage_annotations = { "gethomepage.dev/enabled" = "true" "gethomepage.dev/name" = "Budget Viktor" @@ -63,8 +68,8 @@ module "anca" { nfs_server = var.nfs_server depends_on = [kubernetes_namespace.actualbudget] tier = local.tiers.edge - budget_encryption_password = lookup(var.actualbudget_credentials["anca"], "password", null) - sync_id = lookup(var.actualbudget_credentials["anca"], "sync_id", null) + budget_encryption_password = lookup(local.credentials["anca"], "password", null) + sync_id = lookup(local.credentials["anca"], "sync_id", null) homepage_annotations = { "gethomepage.dev/enabled" = "true" "gethomepage.dev/name" = "Budget Anca" @@ -84,8 +89,8 @@ module "emo" { nfs_server = var.nfs_server depends_on = [kubernetes_namespace.actualbudget] tier = local.tiers.edge - budget_encryption_password = lookup(var.actualbudget_credentials["emo"], "password", null) - sync_id = lookup(var.actualbudget_credentials["emo"], "sync_id", null) + budget_encryption_password = lookup(local.credentials["emo"], "password", null) + sync_id = lookup(local.credentials["emo"], "sync_id", null) homepage_annotations = { "gethomepage.dev/enabled" = "true" "gethomepage.dev/name" = "Budget Emo" diff --git a/stacks/actualbudget/providers.tf b/stacks/actualbudget/providers.tf index 7b5cc7b8..4cd042f5 100644 --- a/stacks/actualbudget/providers.tf +++ b/stacks/actualbudget/providers.tf @@ -1,7 +1,7 @@ # Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa variable "kube_config_path" { - type = string - default = "~/.kube/config" + type = string + default = "~/.kube/config" sensitive = true } diff --git a/stacks/actualbudget/terragrunt.hcl b/stacks/actualbudget/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/actualbudget/terragrunt.hcl +++ b/stacks/actualbudget/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/affine/main.tf b/stacks/affine/main.tf index ba1087f1..cbc8dbdc 100644 --- a/stacks/affine/main.tf +++ b/stacks/affine/main.tf @@ -2,12 +2,16 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "affine_postgresql_password" { - type = string - sensitive = true -} -variable "mailserver_accounts" { type = map(any) } variable "nfs_server" { type = string } + +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "affine" +} + +locals { + mailserver_accounts = jsondecode(data.vault_kv_secret_v2.secrets.data["mailserver_accounts"]) +} variable "redis_host" { type = string } variable "postgresql_host" { type = string } variable "mail_host" { type = string } @@ -32,7 +36,7 @@ locals { common_env = [ { name = "DATABASE_URL" - value = "postgresql://affine:${var.affine_postgresql_password}@${var.postgresql_host}:5432/affine" + value = "postgresql://affine:${data.vault_kv_secret_v2.secrets.data["db_password"]}@${var.postgresql_host}:5432/affine" }, { name = "REDIS_SERVER_HOST" @@ -70,7 +74,7 @@ locals { }, { name = "MAILER_PASSWORD" - value = var.mailserver_accounts["info@viktorbarzin.me"] + value = local.mailserver_accounts["info@viktorbarzin.me"] }, { name = "MAILER_SENDER" diff --git a/stacks/affine/providers.tf b/stacks/affine/providers.tf index 7b5cc7b8..516f9fed 100644 --- a/stacks/affine/providers.tf +++ b/stacks/affine/providers.tf @@ -2,7 +2,6 @@ variable "kube_config_path" { type = string default = "~/.kube/config" - sensitive = true } provider "kubernetes" { diff --git a/stacks/affine/terragrunt.hcl b/stacks/affine/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/affine/terragrunt.hcl +++ b/stacks/affine/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/audiobookshelf/main.tf b/stacks/audiobookshelf/main.tf index fc2c0435..9bfe5a67 100644 --- a/stacks/audiobookshelf/main.tf +++ b/stacks/audiobookshelf/main.tf @@ -3,9 +3,13 @@ variable "tls_secret_name" { sensitive = true } variable "nfs_server" { type = string } -variable "homepage_credentials" { - type = map(any) - sensitive = true +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "audiobookshelf" +} + +locals { + homepage_credentials = jsondecode(data.vault_kv_secret_v2.secrets.data["homepage_credentials"]) } @@ -205,6 +209,6 @@ module "ingress" { "gethomepage.dev/pod-selector" = "" "gethomepage.dev/widget.type" = "audiobookshelf" "gethomepage.dev/widget.url" = "http://audiobookshelf.audiobookshelf.svc.cluster.local" - "gethomepage.dev/widget.key" = var.homepage_credentials["audiobookshelf"]["token"] + "gethomepage.dev/widget.key" = local.homepage_credentials["audiobookshelf"]["token"] } } diff --git a/stacks/audiobookshelf/providers.tf b/stacks/audiobookshelf/providers.tf index 7b5cc7b8..4cd042f5 100644 --- a/stacks/audiobookshelf/providers.tf +++ b/stacks/audiobookshelf/providers.tf @@ -1,7 +1,7 @@ # Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa variable "kube_config_path" { - type = string - default = "~/.kube/config" + type = string + default = "~/.kube/config" sensitive = true } diff --git a/stacks/audiobookshelf/terragrunt.hcl b/stacks/audiobookshelf/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/audiobookshelf/terragrunt.hcl +++ b/stacks/audiobookshelf/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/blog/providers.tf b/stacks/blog/providers.tf index 7b5cc7b8..4cd042f5 100644 --- a/stacks/blog/providers.tf +++ b/stacks/blog/providers.tf @@ -1,7 +1,7 @@ # Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa variable "kube_config_path" { - type = string - default = "~/.kube/config" + type = string + default = "~/.kube/config" sensitive = true } diff --git a/stacks/calibre/main.tf b/stacks/calibre/main.tf index 58d3273f..172dd9d1 100644 --- a/stacks/calibre/main.tf +++ b/stacks/calibre/main.tf @@ -2,12 +2,17 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "homepage_credentials" { - type = map(any) - sensitive = true -} variable "nfs_server" { type = string } +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "calibre" +} + +locals { + homepage_credentials = jsondecode(data.vault_kv_secret_v2.secrets.data["homepage_credentials"]) +} + resource "kubernetes_namespace" "calibre" { metadata { @@ -194,6 +199,24 @@ resource "kubernetes_deployment" "calibre-web-automated" { port { container_port = 8083 } + # Startup probe: allow up to 10 min for calibre binary install on first boot + startup_probe { + http_get { + path = "/" + port = 8083 + } + initial_delay_seconds = 30 + period_seconds = 10 + failure_threshold = 54 + } + liveness_probe { + http_get { + path = "/" + port = 8083 + } + period_seconds = 30 + failure_threshold = 3 + } resources { requests = { cpu = "50m" @@ -274,8 +297,8 @@ module "ingress" { "gethomepage.dev/name" = "Calibre" "gethomepage.dev/widget.type" = "calibreweb" "gethomepage.dev/widget.url" = "http://calibre.calibre.svc.cluster.local" - "gethomepage.dev/widget.username" = var.homepage_credentials["calibre-web"]["username"] - "gethomepage.dev/widget.password" = var.homepage_credentials["calibre-web"]["password"] + "gethomepage.dev/widget.username" = local.homepage_credentials["calibre-web"]["username"] + "gethomepage.dev/widget.password" = local.homepage_credentials["calibre-web"]["password"] "gethomepage.dev/pod-selector" = "" # gethomepage.dev/weight: 10 # optional # gethomepage.dev/instance: "public" # optional diff --git a/stacks/calibre/providers.tf b/stacks/calibre/providers.tf index 7b5cc7b8..f4845cc8 100644 --- a/stacks/calibre/providers.tf +++ b/stacks/calibre/providers.tf @@ -1,8 +1,22 @@ # Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa +terraform { + required_providers { + vault = { + source = "hashicorp/vault" + version = "~> 4.0" + } + } +} + variable "kube_config_path" { type = string default = "~/.kube/config" +} + +variable "vault_root_token" { + type = string sensitive = true + default = "" } provider "kubernetes" { @@ -14,3 +28,9 @@ provider "helm" { config_path = var.kube_config_path } } + +provider "vault" { + address = "https://vault.viktorbarzin.me" + token = var.vault_root_token + skip_child_token = true +} diff --git a/stacks/calibre/terragrunt.hcl b/stacks/calibre/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/calibre/terragrunt.hcl +++ b/stacks/calibre/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/changedetection/main.tf b/stacks/changedetection/main.tf index a93b2caf..ecb42bcf 100644 --- a/stacks/changedetection/main.tf +++ b/stacks/changedetection/main.tf @@ -3,9 +3,13 @@ variable "tls_secret_name" { sensitive = true } variable "nfs_server" { type = string } -variable "homepage_credentials" { - type = map(any) - sensitive = true +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "changedetection" +} + +locals { + homepage_credentials = jsondecode(data.vault_kv_secret_v2.secrets.data["homepage_credentials"]) } @@ -171,6 +175,6 @@ module "ingress" { "gethomepage.dev/pod-selector" = "" "gethomepage.dev/widget.type" = "changedetectionio" "gethomepage.dev/widget.url" = "http://changedetection.changedetection.svc.cluster.local" - "gethomepage.dev/widget.key" = var.homepage_credentials["changedetection"]["api_key"] + "gethomepage.dev/widget.key" = local.homepage_credentials["changedetection"]["api_key"] } } diff --git a/stacks/changedetection/providers.tf b/stacks/changedetection/providers.tf index 7b5cc7b8..4cd042f5 100644 --- a/stacks/changedetection/providers.tf +++ b/stacks/changedetection/providers.tf @@ -1,7 +1,7 @@ # Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa variable "kube_config_path" { - type = string - default = "~/.kube/config" + type = string + default = "~/.kube/config" sensitive = true } diff --git a/stacks/changedetection/terragrunt.hcl b/stacks/changedetection/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/changedetection/terragrunt.hcl +++ b/stacks/changedetection/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/city-guesser/providers.tf b/stacks/city-guesser/providers.tf index 7b5cc7b8..4cd042f5 100644 --- a/stacks/city-guesser/providers.tf +++ b/stacks/city-guesser/providers.tf @@ -1,7 +1,7 @@ # Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa variable "kube_config_path" { - type = string - default = "~/.kube/config" + type = string + default = "~/.kube/config" sensitive = true } diff --git a/stacks/claude-memory/main.tf b/stacks/claude-memory/main.tf index e23ce4c8..dd098abd 100644 --- a/stacks/claude-memory/main.tf +++ b/stacks/claude-memory/main.tf @@ -3,17 +3,14 @@ variable "tls_secret_name" { sensitive = true } variable "postgresql_host" { type = string } -variable "dbaas_postgresql_root_password" { - type = string - sensitive = true -} variable "claude_memory_db_password" { type = string sensitive = true } -variable "claude_memory_api_key" { - type = string - sensitive = true + +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "claude-memory" } resource "kubernetes_namespace" "claude-memory" { @@ -48,11 +45,11 @@ resource "kubernetes_job" "db_init" { "sh", "-c", <<-EOT set -e - PGPASSWORD='${var.dbaas_postgresql_root_password}' psql -h ${var.postgresql_host} -U root -tc "SELECT 1 FROM pg_roles WHERE rolname='claude_memory'" | grep -q 1 || \ - PGPASSWORD='${var.dbaas_postgresql_root_password}' psql -h ${var.postgresql_host} -U root -c "CREATE ROLE claude_memory WITH LOGIN PASSWORD '${var.claude_memory_db_password}'" - PGPASSWORD='${var.dbaas_postgresql_root_password}' psql -h ${var.postgresql_host} -U root -tc "SELECT 1 FROM pg_database WHERE datname='claude_memory'" | grep -q 1 || \ - PGPASSWORD='${var.dbaas_postgresql_root_password}' psql -h ${var.postgresql_host} -U root -c "CREATE DATABASE claude_memory OWNER claude_memory" - PGPASSWORD='${var.dbaas_postgresql_root_password}' psql -h ${var.postgresql_host} -U root -c "GRANT ALL PRIVILEGES ON DATABASE claude_memory TO claude_memory" + PGPASSWORD='${data.vault_kv_secret_v2.secrets.data["dbaas_root_password"]}' psql -h ${var.postgresql_host} -U root -tc "SELECT 1 FROM pg_roles WHERE rolname='claude_memory'" | grep -q 1 || \ + PGPASSWORD='${data.vault_kv_secret_v2.secrets.data["dbaas_root_password"]}' psql -h ${var.postgresql_host} -U root -c "CREATE ROLE claude_memory WITH LOGIN PASSWORD '${var.claude_memory_db_password}'" + PGPASSWORD='${data.vault_kv_secret_v2.secrets.data["dbaas_root_password"]}' psql -h ${var.postgresql_host} -U root -tc "SELECT 1 FROM pg_database WHERE datname='claude_memory'" | grep -q 1 || \ + PGPASSWORD='${data.vault_kv_secret_v2.secrets.data["dbaas_root_password"]}' psql -h ${var.postgresql_host} -U root -c "CREATE DATABASE claude_memory OWNER claude_memory" + PGPASSWORD='${data.vault_kv_secret_v2.secrets.data["dbaas_root_password"]}' psql -h ${var.postgresql_host} -U root -c "GRANT ALL PRIVILEGES ON DATABASE claude_memory TO claude_memory" echo "Database init complete" EOT ] @@ -79,7 +76,7 @@ resource "kubernetes_deployment" "claude-memory" { } } spec { - replicas = 1 + replicas = 2 selector { match_labels = { app = "claude-memory" @@ -92,6 +89,18 @@ resource "kubernetes_deployment" "claude-memory" { } } spec { + affinity { + pod_anti_affinity { + required_during_scheduling_ignored_during_execution { + label_selector { + match_labels = { + app = "claude-memory" + } + } + topology_key = "kubernetes.io/hostname" + } + } + } container { name = "claude-memory" image = "viktorbarzin/claude-memory-mcp:latest" @@ -106,9 +115,17 @@ resource "kubernetes_deployment" "claude-memory" { } env { name = "API_KEY" - value = var.claude_memory_api_key + value = data.vault_kv_secret_v2.secrets.data["api_key"] } + startup_probe { + http_get { + path = "/health" + port = 8000 + } + failure_threshold = 30 + period_seconds = 2 + } liveness_probe { http_get { path = "/health" @@ -146,6 +163,21 @@ resource "kubernetes_deployment" "claude-memory" { } } +resource "kubernetes_pod_disruption_budget_v1" "claude-memory" { + metadata { + name = "claude-memory" + namespace = kubernetes_namespace.claude-memory.metadata[0].name + } + spec { + min_available = "1" + selector { + match_labels = { + app = "claude-memory" + } + } + } +} + resource "kubernetes_service" "claude-memory" { metadata { name = "claude-memory" diff --git a/stacks/claude-memory/terragrunt.hcl b/stacks/claude-memory/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/claude-memory/terragrunt.hcl +++ b/stacks/claude-memory/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/coturn/main.tf b/stacks/coturn/main.tf index 09d88d7d..b1f21d46 100644 --- a/stacks/coturn/main.tf +++ b/stacks/coturn/main.tf @@ -2,12 +2,12 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "coturn_turn_secret" { - type = string - sensitive = true -} variable "public_ip" { type = string } +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "coturn" +} locals { turn_realm = "viktorbarzin.me" @@ -45,7 +45,7 @@ resource "kubernetes_config_map" "coturn_config" { fingerprint lt-cred-mech use-auth-secret - static-auth-secret=${var.coturn_turn_secret} + static-auth-secret=${data.vault_kv_secret_v2.secrets.data["turn_secret"]} realm=${local.turn_realm} server-name=turn.${local.turn_realm} diff --git a/stacks/coturn/providers.tf b/stacks/coturn/providers.tf index 7b5cc7b8..4cd042f5 100644 --- a/stacks/coturn/providers.tf +++ b/stacks/coturn/providers.tf @@ -1,7 +1,7 @@ # Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa variable "kube_config_path" { - type = string - default = "~/.kube/config" + type = string + default = "~/.kube/config" sensitive = true } diff --git a/stacks/coturn/terragrunt.hcl b/stacks/coturn/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/coturn/terragrunt.hcl +++ b/stacks/coturn/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/cyberchef/providers.tf b/stacks/cyberchef/providers.tf index 7b5cc7b8..4cd042f5 100644 --- a/stacks/cyberchef/providers.tf +++ b/stacks/cyberchef/providers.tf @@ -1,7 +1,7 @@ # Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa variable "kube_config_path" { - type = string - default = "~/.kube/config" + type = string + default = "~/.kube/config" sensitive = true } diff --git a/stacks/dawarich/main.tf b/stacks/dawarich/main.tf index 12011d15..89ae8674 100644 --- a/stacks/dawarich/main.tf +++ b/stacks/dawarich/main.tf @@ -2,15 +2,6 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "dawarich_database_password" { - type = string - sensitive = true -} -variable "geoapify_api_key" { - type = string - sensitive = true -} - variable "image_version" { type = string @@ -20,6 +11,11 @@ variable "nfs_server" { type = string } variable "redis_host" { type = string } variable "postgresql_host" { type = string } +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "dawarich" +} + resource "kubernetes_namespace" "dawarich" { metadata { name = "dawarich" @@ -97,7 +93,7 @@ resource "kubernetes_deployment" "dawarich" { } env { name = "DATABASE_PASSWORD" - value = var.dawarich_database_password + value = data.vault_kv_secret_v2.secrets.data["db_password"] } env { name = "DATABASE_NAME" @@ -178,7 +174,7 @@ resource "kubernetes_deployment" "dawarich" { # } # env { # name = "DATABASE_PASSWORD" - # value = var.dawarich_database_password + # value = data.vault_kv_secret_v2.secrets.data["db_password"] # } # env { # name = "DATABASE_NAME" @@ -219,7 +215,7 @@ resource "kubernetes_deployment" "dawarich" { # # } # env { # name = "GEOAPIFY_API_KEY" - # value = var.geoapify_api_key + # value = data.vault_kv_secret_v2.secrets.data["geoapify_api_key"] # } # env { # name = "SELF_HOSTED" diff --git a/stacks/dawarich/providers.tf b/stacks/dawarich/providers.tf index 7b5cc7b8..4cd042f5 100644 --- a/stacks/dawarich/providers.tf +++ b/stacks/dawarich/providers.tf @@ -1,7 +1,7 @@ # Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa variable "kube_config_path" { - type = string - default = "~/.kube/config" + type = string + default = "~/.kube/config" sensitive = true } diff --git a/stacks/dawarich/terragrunt.hcl b/stacks/dawarich/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/dawarich/terragrunt.hcl +++ b/stacks/dawarich/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/descheduler/providers.tf b/stacks/descheduler/providers.tf index 7b5cc7b8..4cd042f5 100644 --- a/stacks/descheduler/providers.tf +++ b/stacks/descheduler/providers.tf @@ -1,7 +1,7 @@ # Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa variable "kube_config_path" { - type = string - default = "~/.kube/config" + type = string + default = "~/.kube/config" sensitive = true } diff --git a/stacks/diun/main.tf b/stacks/diun/main.tf index 8a6ff4b1..3f18f507 100644 --- a/stacks/diun/main.tf +++ b/stacks/diun/main.tf @@ -2,13 +2,12 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "diun_nfty_token" { - type = string - sensitive = true -} -variable "diun_slack_url" { type = string } variable "nfs_server" { type = string } +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "diun" +} resource "kubernetes_namespace" "diun" { metadata { @@ -154,11 +153,11 @@ resource "kubernetes_deployment" "diun" { # } # env { # name = "DIUN_NOTIF_NTFY_TOKEN" - # value = var.diun_nfty_token + # value = data.vault_kv_secret_v2.secrets.data["nfty_token"] # } env { name = "DIUN_NOTIF_SLACK_WEBHOOKURL" - value = var.diun_slack_url + value = data.vault_kv_secret_v2.secrets.data["slack_url"] } env { name = "LOG_LEVEL" diff --git a/stacks/diun/providers.tf b/stacks/diun/providers.tf index 7b5cc7b8..4cd042f5 100644 --- a/stacks/diun/providers.tf +++ b/stacks/diun/providers.tf @@ -1,7 +1,7 @@ # Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa variable "kube_config_path" { - type = string - default = "~/.kube/config" + type = string + default = "~/.kube/config" sensitive = true } diff --git a/stacks/diun/terragrunt.hcl b/stacks/diun/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/diun/terragrunt.hcl +++ b/stacks/diun/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/ebook2audiobook/providers.tf b/stacks/ebook2audiobook/providers.tf index 7b5cc7b8..4cd042f5 100644 --- a/stacks/ebook2audiobook/providers.tf +++ b/stacks/ebook2audiobook/providers.tf @@ -1,7 +1,7 @@ # Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa variable "kube_config_path" { - type = string - default = "~/.kube/config" + type = string + default = "~/.kube/config" sensitive = true } diff --git a/stacks/echo/providers.tf b/stacks/echo/providers.tf index 7b5cc7b8..4cd042f5 100644 --- a/stacks/echo/providers.tf +++ b/stacks/echo/providers.tf @@ -1,7 +1,7 @@ # Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa variable "kube_config_path" { - type = string - default = "~/.kube/config" + type = string + default = "~/.kube/config" sensitive = true } diff --git a/stacks/excalidraw/providers.tf b/stacks/excalidraw/providers.tf index 7b5cc7b8..4cd042f5 100644 --- a/stacks/excalidraw/providers.tf +++ b/stacks/excalidraw/providers.tf @@ -1,7 +1,7 @@ # Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa variable "kube_config_path" { - type = string - default = "~/.kube/config" + type = string + default = "~/.kube/config" sensitive = true } diff --git a/stacks/f1-stream/main.tf b/stacks/f1-stream/main.tf index 67176d4f..6111d78b 100644 --- a/stacks/f1-stream/main.tf +++ b/stacks/f1-stream/main.tf @@ -3,13 +3,13 @@ variable "tls_secret_name" { sensitive = true } variable "nfs_server" { type = string } -variable "discord_user_token" { - type = string - sensitive = true -} variable "discord_f1_guild_id" { type = string } variable "discord_f1_channel_ids" { type = string } +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "f1-stream" +} resource "kubernetes_namespace" "f1-stream" { metadata { @@ -70,7 +70,7 @@ resource "kubernetes_deployment" "f1-stream" { } env { name = "DISCORD_TOKEN" - value = var.discord_user_token + value = data.vault_kv_secret_v2.secrets.data["discord_user_token"] } env { name = "DISCORD_CHANNELS" diff --git a/stacks/f1-stream/providers.tf b/stacks/f1-stream/providers.tf index 7b5cc7b8..4cd042f5 100644 --- a/stacks/f1-stream/providers.tf +++ b/stacks/f1-stream/providers.tf @@ -1,7 +1,7 @@ # Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa variable "kube_config_path" { - type = string - default = "~/.kube/config" + type = string + default = "~/.kube/config" sensitive = true } diff --git a/stacks/f1-stream/terragrunt.hcl b/stacks/f1-stream/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/f1-stream/terragrunt.hcl +++ b/stacks/f1-stream/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/forgejo/main.tf b/stacks/forgejo/main.tf index 21caedfb..b5d517b9 100644 --- a/stacks/forgejo/main.tf +++ b/stacks/forgejo/main.tf @@ -3,12 +3,11 @@ variable "tls_secret_name" { sensitive = true } variable "nfs_server" { type = string } -variable "forgejo_authentik_client_id" { type = string } -variable "forgejo_authentik_client_secret" { - type = string - sensitive = true -} +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "forgejo" +} resource "kubernetes_namespace" "forgejo" { metadata { diff --git a/stacks/forgejo/providers.tf b/stacks/forgejo/providers.tf index 7b5cc7b8..4cd042f5 100644 --- a/stacks/forgejo/providers.tf +++ b/stacks/forgejo/providers.tf @@ -1,7 +1,7 @@ # Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa variable "kube_config_path" { - type = string - default = "~/.kube/config" + type = string + default = "~/.kube/config" sensitive = true } diff --git a/stacks/forgejo/terragrunt.hcl b/stacks/forgejo/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/forgejo/terragrunt.hcl +++ b/stacks/forgejo/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/freedify/main.tf b/stacks/freedify/main.tf index 5c0a1bc1..7ce7e4f0 100644 --- a/stacks/freedify/main.tf +++ b/stacks/freedify/main.tf @@ -2,9 +2,13 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "freedify_credentials" { - type = map(any) - sensitive = true +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "freedify" +} + +locals { + credentials = jsondecode(data.vault_kv_secret_v2.secrets.data["credentials"]) } @@ -40,11 +44,11 @@ module "viktor" { depends_on = [kubernetes_namespace.freedify] tier = local.tiers.aux protected = true - listenbrainz_token = lookup(var.freedify_credentials["viktor"], "listenbrainz_token", null) - genius_token = lookup(var.freedify_credentials["viktor"], "genius_token", null) - dab_session = lookup(var.freedify_credentials["viktor"], "dab_session", null) - dab_visitor_id = lookup(var.freedify_credentials["viktor"], "dab_visitor_id", null) - gemini_api_key = lookup(var.freedify_credentials["viktor"], "gemini_api_key", null) + listenbrainz_token = lookup(local.credentials["viktor"], "listenbrainz_token", null) + genius_token = lookup(local.credentials["viktor"], "genius_token", null) + dab_session = lookup(local.credentials["viktor"], "dab_session", null) + dab_visitor_id = lookup(local.credentials["viktor"], "dab_visitor_id", null) + gemini_api_key = lookup(local.credentials["viktor"], "gemini_api_key", null) extra_annotations = { "gethomepage.dev/enabled" = "true" "gethomepage.dev/name" = "Freedify (Viktor)" @@ -64,8 +68,8 @@ module "emo" { depends_on = [kubernetes_namespace.freedify] tier = local.tiers.aux protected = true - genius_token = lookup(var.freedify_credentials["emo"], "genius_token", null) - gemini_api_key = lookup(var.freedify_credentials["emo"], "gemini_api_key", null) + genius_token = lookup(local.credentials["emo"], "genius_token", null) + gemini_api_key = lookup(local.credentials["emo"], "gemini_api_key", null) extra_annotations = { "gethomepage.dev/enabled" = "true" "gethomepage.dev/name" = "Freedify (Emo)" diff --git a/stacks/freedify/providers.tf b/stacks/freedify/providers.tf index 7b5cc7b8..4cd042f5 100644 --- a/stacks/freedify/providers.tf +++ b/stacks/freedify/providers.tf @@ -1,7 +1,7 @@ # Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa variable "kube_config_path" { - type = string - default = "~/.kube/config" + type = string + default = "~/.kube/config" sensitive = true } diff --git a/stacks/freedify/terragrunt.hcl b/stacks/freedify/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/freedify/terragrunt.hcl +++ b/stacks/freedify/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/freshrss/main.tf b/stacks/freshrss/main.tf index 31d82af0..633c1333 100644 --- a/stacks/freshrss/main.tf +++ b/stacks/freshrss/main.tf @@ -3,9 +3,13 @@ variable "tls_secret_name" { sensitive = true } variable "nfs_server" { type = string } -variable "homepage_credentials" { - type = map(any) - sensitive = true +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "freshrss" +} + +locals { + homepage_credentials = jsondecode(data.vault_kv_secret_v2.secrets.data["homepage_credentials"]) } @@ -159,7 +163,7 @@ module "ingress" { "gethomepage.dev/pod-selector" = "" "gethomepage.dev/widget.type" = "freshrss" "gethomepage.dev/widget.url" = "http://freshrss.freshrss.svc.cluster.local" - "gethomepage.dev/widget.username" = var.homepage_credentials["freshrss"]["username"] - "gethomepage.dev/widget.password" = var.homepage_credentials["freshrss"]["password"] + "gethomepage.dev/widget.username" = local.homepage_credentials["freshrss"]["username"] + "gethomepage.dev/widget.password" = local.homepage_credentials["freshrss"]["password"] } } diff --git a/stacks/freshrss/providers.tf b/stacks/freshrss/providers.tf index 7b5cc7b8..4cd042f5 100644 --- a/stacks/freshrss/providers.tf +++ b/stacks/freshrss/providers.tf @@ -1,7 +1,7 @@ # Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa variable "kube_config_path" { - type = string - default = "~/.kube/config" + type = string + default = "~/.kube/config" sensitive = true } diff --git a/stacks/freshrss/terragrunt.hcl b/stacks/freshrss/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/freshrss/terragrunt.hcl +++ b/stacks/freshrss/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/frigate/providers.tf b/stacks/frigate/providers.tf index 7b5cc7b8..4cd042f5 100644 --- a/stacks/frigate/providers.tf +++ b/stacks/frigate/providers.tf @@ -1,7 +1,7 @@ # Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa variable "kube_config_path" { - type = string - default = "~/.kube/config" + type = string + default = "~/.kube/config" sensitive = true } diff --git a/stacks/grampsweb/main.tf b/stacks/grampsweb/main.tf index b8918b1f..dc8138dc 100644 --- a/stacks/grampsweb/main.tf +++ b/stacks/grampsweb/main.tf @@ -2,8 +2,16 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "mailserver_accounts" { type = map(any) } variable "nfs_server" { type = string } + +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "grampsweb" +} + +locals { + mailserver_accounts = jsondecode(data.vault_kv_secret_v2.secrets.data["mailserver_accounts"]) +} variable "redis_host" { type = string } variable "ollama_host" { type = string } variable "mail_host" { type = string } @@ -81,7 +89,7 @@ locals { }, { name = "GRAMPSWEB_EMAIL_HOST_PASSWORD" - value = var.mailserver_accounts["info@viktorbarzin.me"] + value = local.mailserver_accounts["info@viktorbarzin.me"] }, { name = "GRAMPSWEB_EMAIL_USE_SSL" diff --git a/stacks/grampsweb/providers.tf b/stacks/grampsweb/providers.tf index 7b5cc7b8..4cd042f5 100644 --- a/stacks/grampsweb/providers.tf +++ b/stacks/grampsweb/providers.tf @@ -1,7 +1,7 @@ # Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa variable "kube_config_path" { - type = string - default = "~/.kube/config" + type = string + default = "~/.kube/config" sensitive = true } diff --git a/stacks/grampsweb/terragrunt.hcl b/stacks/grampsweb/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/grampsweb/terragrunt.hcl +++ b/stacks/grampsweb/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/hackmd/main.tf b/stacks/hackmd/main.tf index 9b028b9f..a5ac7a32 100644 --- a/stacks/hackmd/main.tf +++ b/stacks/hackmd/main.tf @@ -1,13 +1,13 @@ -variable "hackmd_db_password" { - type = string - sensitive = true -} variable "tls_secret_name" { type = string } variable "nfs_server" { type = string } variable "mysql_host" { type = string } +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "hackmd" +} resource "kubernetes_namespace" "hackmd" { metadata { @@ -103,7 +103,7 @@ resource "kubernetes_deployment" "hackmd" { env { name = "CMD_DB_URL" # value = format("%s%s%s", "postgres://codimd:", var.hackmd_db_password, "@localhost/codimd") - value = format("%s%s%s", "mysql://codimd:", var.hackmd_db_password, "@${var.mysql_host}/codimd") + value = format("%s%s%s", "mysql://codimd:", data.vault_kv_secret_v2.secrets.data["db_password"], "@${var.mysql_host}/codimd") } env { name = "CMD_USECDN" diff --git a/stacks/hackmd/providers.tf b/stacks/hackmd/providers.tf index 7b5cc7b8..4cd042f5 100644 --- a/stacks/hackmd/providers.tf +++ b/stacks/hackmd/providers.tf @@ -1,7 +1,7 @@ # Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa variable "kube_config_path" { - type = string - default = "~/.kube/config" + type = string + default = "~/.kube/config" sensitive = true } diff --git a/stacks/hackmd/terragrunt.hcl b/stacks/hackmd/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/hackmd/terragrunt.hcl +++ b/stacks/hackmd/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/health/main.tf b/stacks/health/main.tf index 35309038..fd06d156 100644 --- a/stacks/health/main.tf +++ b/stacks/health/main.tf @@ -2,17 +2,13 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "health_postgresql_password" { - type = string - sensitive = true -} -variable "health_secret_key" { - type = string - sensitive = true -} variable "nfs_server" { type = string } variable "postgresql_host" { type = string } +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "health" +} resource "kubernetes_namespace" "health" { metadata { @@ -70,11 +66,11 @@ resource "kubernetes_deployment" "health" { env { name = "DATABASE_URL" - value = "postgresql+asyncpg://health:${var.health_postgresql_password}@${var.postgresql_host}:5432/health" + value = "postgresql+asyncpg://health:${data.vault_kv_secret_v2.secrets.data["db_password"]}@${var.postgresql_host}:5432/health" } env { name = "SECRET_KEY" - value = var.health_secret_key + value = data.vault_kv_secret_v2.secrets.data["secret_key"] } env { name = "UPLOAD_DIR" diff --git a/stacks/health/providers.tf b/stacks/health/providers.tf index 7b5cc7b8..4cd042f5 100644 --- a/stacks/health/providers.tf +++ b/stacks/health/providers.tf @@ -1,7 +1,7 @@ # Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa variable "kube_config_path" { - type = string - default = "~/.kube/config" + type = string + default = "~/.kube/config" sensitive = true } diff --git a/stacks/health/terragrunt.hcl b/stacks/health/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/health/terragrunt.hcl +++ b/stacks/health/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/homepage/providers.tf b/stacks/homepage/providers.tf index 7b5cc7b8..4cd042f5 100644 --- a/stacks/homepage/providers.tf +++ b/stacks/homepage/providers.tf @@ -1,7 +1,7 @@ # Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa variable "kube_config_path" { - type = string - default = "~/.kube/config" + type = string + default = "~/.kube/config" sensitive = true } diff --git a/stacks/immich/frame.tf b/stacks/immich/frame.tf index 4ab61bbc..3a0e60ed 100644 --- a/stacks/immich/frame.tf +++ b/stacks/immich/frame.tf @@ -23,7 +23,7 @@ resource "kubernetes_config_map" "mailserver_config" { ShowProgressBar: false Accounts: - ImmichServerUrl: http://immich.viktorbarzin.me - ApiKey: ${var.immich_frame_api_key} + ApiKey: ${data.vault_kv_secret_v2.secrets.data["frame_api_key"]} Albums: - 1aa98849-bbd5-452b-aac0-310b210a8597 # china EOF diff --git a/stacks/immich/main.tf b/stacks/immich/main.tf index b01939b8..1a9ed6b8 100644 --- a/stacks/immich/main.tf +++ b/stacks/immich/main.tf @@ -2,17 +2,13 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "immich_postgresql_password" { - type = string - sensitive = true +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "immich" } -variable "immich_frame_api_key" { - type = string - sensitive = true -} -variable "homepage_credentials" { - type = map(any) - sensitive = true + +locals { + homepage_credentials = jsondecode(data.vault_kv_secret_v2.secrets.data["homepage_credentials"]) } @@ -168,7 +164,7 @@ resource "kubernetes_deployment" "immich_server" { } env { name = "DB_PASSWORD" - value = var.immich_postgresql_password + value = data.vault_kv_secret_v2.secrets.data["db_password"] } env { name = "IMMICH_MACHINE_LEARNING_URL" @@ -357,7 +353,7 @@ resource "kubernetes_deployment" "immich-postgres" { } env { name = "POSTGRES_PASSWORD" - value = var.immich_postgresql_password + value = data.vault_kv_secret_v2.secrets.data["db_password"] } env { name = "POSTGRES_USER" @@ -428,7 +424,7 @@ resource "kubernetes_service" "immich-postgresql" { # version = "0.9.3" # timeout = 6000 -# values = [templatefile("${path.module}/chart_values.tpl", { postgresql_password = var.immich_postgresql_password, version = var.immich_version })] +# values = [templatefile("${path.module}/chart_values.tpl", { postgresql_password = data.vault_kv_secret_v2.secrets.data["db_password"], version = var.immich_version })] # } # The helm one cannot be customized to use affinity settings to use the gpu node @@ -595,7 +591,7 @@ module "ingress-immich" { "gethomepage.dev/widget.url" = "http://immich-server.immich.svc.cluster.local:2283" "gethomepage.dev/widget.version" = "2" "gethomepage.dev/pod-selector" = "" - "gethomepage.dev/widget.key" = var.homepage_credentials["immich"]["token"] + "gethomepage.dev/widget.key" = local.homepage_credentials["immich"]["token"] } } @@ -625,7 +621,7 @@ resource "kubernetes_cron_job_v1" "postgresql-backup" { image = "postgres:16.4-bullseye" command = ["/bin/sh", "-c", <<-EOT export now=$(date +"%Y_%m_%d_%H_%M") - PGPASSWORD=${var.immich_postgresql_password} pg_dumpall -h immich-postgresql -U immich > /backup/dump_$now.sql + PGPASSWORD=${data.vault_kv_secret_v2.secrets.data["db_password"]} pg_dumpall -h immich-postgresql -U immich > /backup/dump_$now.sql # Rotate - delete last log file cd /backup @@ -710,7 +706,7 @@ resource "kubernetes_cron_job_v1" "postgresql-backup" { # } # env { # name = "DB_PASSWORD" -# value = var.immich_postgresql_password +# value = data.vault_kv_secret_v2.secrets.data["db_password"] # } # env { # name = "DB_HOST" diff --git a/stacks/immich/providers.tf b/stacks/immich/providers.tf index 7b5cc7b8..516f9fed 100644 --- a/stacks/immich/providers.tf +++ b/stacks/immich/providers.tf @@ -2,7 +2,6 @@ variable "kube_config_path" { type = string default = "~/.kube/config" - sensitive = true } provider "kubernetes" { diff --git a/stacks/immich/terragrunt.hcl b/stacks/immich/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/immich/terragrunt.hcl +++ b/stacks/immich/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/infra/providers.tf b/stacks/infra/providers.tf index 0fddad19..ab80455b 100644 --- a/stacks/infra/providers.tf +++ b/stacks/infra/providers.tf @@ -9,18 +9,18 @@ terraform { } variable "kube_config_path" { - type = string - default = "~/.kube/config" + type = string + default = "~/.kube/config" sensitive = true } variable "proxmox_pm_api_url" { type = string } variable "proxmox_pm_api_token_id" { - type = string + type = string sensitive = true } variable "proxmox_pm_api_token_secret" { - type = string + type = string sensitive = true } diff --git a/stacks/isponsorblocktv/providers.tf b/stacks/isponsorblocktv/providers.tf index 7b5cc7b8..4cd042f5 100644 --- a/stacks/isponsorblocktv/providers.tf +++ b/stacks/isponsorblocktv/providers.tf @@ -1,7 +1,7 @@ # Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa variable "kube_config_path" { - type = string - default = "~/.kube/config" + type = string + default = "~/.kube/config" sensitive = true } diff --git a/stacks/jsoncrack/providers.tf b/stacks/jsoncrack/providers.tf index 7b5cc7b8..4cd042f5 100644 --- a/stacks/jsoncrack/providers.tf +++ b/stacks/jsoncrack/providers.tf @@ -1,7 +1,7 @@ # Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa variable "kube_config_path" { - type = string - default = "~/.kube/config" + type = string + default = "~/.kube/config" sensitive = true } diff --git a/stacks/k8s-dashboard/providers.tf b/stacks/k8s-dashboard/providers.tf index 7b5cc7b8..4cd042f5 100644 --- a/stacks/k8s-dashboard/providers.tf +++ b/stacks/k8s-dashboard/providers.tf @@ -1,7 +1,7 @@ # Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa variable "kube_config_path" { - type = string - default = "~/.kube/config" + type = string + default = "~/.kube/config" sensitive = true } diff --git a/stacks/kms/providers.tf b/stacks/kms/providers.tf index 7b5cc7b8..4cd042f5 100644 --- a/stacks/kms/providers.tf +++ b/stacks/kms/providers.tf @@ -1,7 +1,7 @@ # Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa variable "kube_config_path" { - type = string - default = "~/.kube/config" + type = string + default = "~/.kube/config" sensitive = true } diff --git a/stacks/linkwarden/main.tf b/stacks/linkwarden/main.tf index 5f0eca70..906b2567 100644 --- a/stacks/linkwarden/main.tf +++ b/stacks/linkwarden/main.tf @@ -2,19 +2,15 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "linkwarden_postgresql_password" { - type = string - sensitive = true -} -variable "linkwarden_authentik_client_id" { type = string } -variable "linkwarden_authentik_client_secret" { - type = string - sensitive = true -} variable "postgresql_host" { type = string } -variable "homepage_credentials" { - type = map(any) - sensitive = true + +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "linkwarden" +} + +locals { + homepage_credentials = jsondecode(data.vault_kv_secret_v2.secrets.data["homepage_credentials"]) } @@ -78,7 +74,7 @@ resource "kubernetes_deployment" "linkwarden" { } env { name = "DATABASE_URL" - value = "postgresql://linkwarden:${var.linkwarden_postgresql_password}@${var.postgresql_host}:5432/linkwarden" + value = "postgresql://linkwarden:${data.vault_kv_secret_v2.secrets.data["db_password"]}@${var.postgresql_host}:5432/linkwarden" } env { name = "NEXT_PUBLIC_AUTHENTIK_ENABLED" @@ -98,11 +94,11 @@ resource "kubernetes_deployment" "linkwarden" { } env { name = "AUTHENTIK_CLIENT_ID" - value = var.linkwarden_authentik_client_id + value = data.vault_kv_secret_v2.secrets.data["authentik_client_id"] } env { name = "AUTHENTIK_CLIENT_SECRET" - value = var.linkwarden_authentik_client_secret + value = data.vault_kv_secret_v2.secrets.data["authentik_client_secret"] } resources { requests = { @@ -153,6 +149,6 @@ module "ingress" { "gethomepage.dev/pod-selector" = "" "gethomepage.dev/widget.type" = "linkwarden" "gethomepage.dev/widget.url" = "http://linkwarden.linkwarden.svc.cluster.local" - "gethomepage.dev/widget.key" = var.homepage_credentials["linkwarden"]["api_key"] + "gethomepage.dev/widget.key" = local.homepage_credentials["linkwarden"]["api_key"] } } diff --git a/stacks/linkwarden/providers.tf b/stacks/linkwarden/providers.tf index 7b5cc7b8..516f9fed 100644 --- a/stacks/linkwarden/providers.tf +++ b/stacks/linkwarden/providers.tf @@ -2,7 +2,6 @@ variable "kube_config_path" { type = string default = "~/.kube/config" - sensitive = true } provider "kubernetes" { diff --git a/stacks/linkwarden/terragrunt.hcl b/stacks/linkwarden/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/linkwarden/terragrunt.hcl +++ b/stacks/linkwarden/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/n8n/main.tf b/stacks/n8n/main.tf index d615134e..1fa94cdb 100644 --- a/stacks/n8n/main.tf +++ b/stacks/n8n/main.tf @@ -2,13 +2,13 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "n8n_postgresql_password" { - type = string - sensitive = true -} variable "nfs_server" { type = string } variable "postgresql_host" { type = string } +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "n8n" +} module "tls_secret" { source = "../../modules/kubernetes/setup_tls_secret" @@ -125,7 +125,7 @@ resource "kubernetes_deployment" "n8n" { } env { name = "DB_POSTGRESDB_PASSWORD" - value = var.n8n_postgresql_password + value = data.vault_kv_secret_v2.secrets.data["db_password"] } env { name = "GENERIC_TIMEZONE" diff --git a/stacks/n8n/providers.tf b/stacks/n8n/providers.tf index 7b5cc7b8..516f9fed 100644 --- a/stacks/n8n/providers.tf +++ b/stacks/n8n/providers.tf @@ -2,7 +2,6 @@ variable "kube_config_path" { type = string default = "~/.kube/config" - sensitive = true } provider "kubernetes" { diff --git a/stacks/n8n/terragrunt.hcl b/stacks/n8n/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/n8n/terragrunt.hcl +++ b/stacks/n8n/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/navidrome/main.tf b/stacks/navidrome/main.tf index 595a5747..441cb482 100644 --- a/stacks/navidrome/main.tf +++ b/stacks/navidrome/main.tf @@ -3,9 +3,13 @@ variable "tls_secret_name" { sensitive = true } variable "nfs_server" { type = string } -variable "homepage_credentials" { - type = map(any) - sensitive = true +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "navidrome" +} + +locals { + homepage_credentials = jsondecode(data.vault_kv_secret_v2.secrets.data["homepage_credentials"]) } @@ -164,8 +168,8 @@ module "ingress" { "gethomepage.dev/pod-selector" = "" "gethomepage.dev/widget.type" = "navidrome" "gethomepage.dev/widget.url" = "http://navidrome.navidrome.svc.cluster.local" - "gethomepage.dev/widget.user" = var.homepage_credentials["navidrome"]["user"] - "gethomepage.dev/widget.token" = var.homepage_credentials["navidrome"]["token"] - "gethomepage.dev/widget.salt" = var.homepage_credentials["navidrome"]["salt"] + "gethomepage.dev/widget.user" = local.homepage_credentials["navidrome"]["user"] + "gethomepage.dev/widget.token" = local.homepage_credentials["navidrome"]["token"] + "gethomepage.dev/widget.salt" = local.homepage_credentials["navidrome"]["salt"] } } diff --git a/stacks/navidrome/terragrunt.hcl b/stacks/navidrome/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/navidrome/terragrunt.hcl +++ b/stacks/navidrome/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/netbox/main.tf b/stacks/netbox/main.tf index d7394d28..9ce1d559 100644 --- a/stacks/netbox/main.tf +++ b/stacks/netbox/main.tf @@ -2,18 +2,14 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "netbox_db_password" { - type = string - sensitive = true -} -variable "netbox_superuser_password" { - type = string - sensitive = true -} variable "nfs_server" { type = string } variable "redis_host" { type = string } variable "postgresql_host" { type = string } +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "netbox" +} resource "kubernetes_namespace" "netbox" { metadata { @@ -81,7 +77,7 @@ resource "kubernetes_deployment" "netbox" { } env { name = "DB_PASSWORD" - value = var.netbox_db_password + value = data.vault_kv_secret_v2.secrets.data["db_password"] } env { name = "DB_HOST" @@ -117,7 +113,7 @@ resource "kubernetes_deployment" "netbox" { } env { name = "SUPERUSER_PASSWORD" - value = var.netbox_superuser_password + value = data.vault_kv_secret_v2.secrets.data["superuser_password"] } env { name = "REMOTE_AUTH_ENABLED" diff --git a/stacks/netbox/providers.tf b/stacks/netbox/providers.tf index 7b5cc7b8..516f9fed 100644 --- a/stacks/netbox/providers.tf +++ b/stacks/netbox/providers.tf @@ -2,7 +2,6 @@ variable "kube_config_path" { type = string default = "~/.kube/config" - sensitive = true } provider "kubernetes" { diff --git a/stacks/netbox/terragrunt.hcl b/stacks/netbox/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/netbox/terragrunt.hcl +++ b/stacks/netbox/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/nextcloud/main.tf b/stacks/nextcloud/main.tf index 0d4444c3..73c861fd 100644 --- a/stacks/nextcloud/main.tf +++ b/stacks/nextcloud/main.tf @@ -2,16 +2,17 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "nextcloud_db_password" { - type = string - sensitive = true -} variable "nfs_server" { type = string } variable "redis_host" { type = string } variable "mysql_host" { type = string } -variable "homepage_credentials" { - type = map(any) - sensitive = true + +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "nextcloud" +} + +locals { + homepage_credentials = jsondecode(data.vault_kv_secret_v2.secrets.data["homepage_credentials"]) } @@ -79,7 +80,7 @@ resource "helm_release" "nextcloud" { atomic = true version = "8.8.1" - values = [templatefile("${path.module}/chart_values.yaml", { tls_secret_name = var.tls_secret_name, db_password = var.nextcloud_db_password, redis_host = var.redis_host, mysql_host = var.mysql_host })] + values = [templatefile("${path.module}/chart_values.yaml", { tls_secret_name = var.tls_secret_name, db_password = data.vault_kv_secret_v2.secrets.data["db_password"], redis_host = var.redis_host, mysql_host = var.mysql_host })] timeout = 6000 } @@ -182,7 +183,7 @@ resource "kubernetes_deployment" "whiteboard" { } env { name = "JWT_SECRET_KEY" - value = var.nextcloud_db_password # anything secret is fine + value = data.vault_kv_secret_v2.secrets.data["db_password"] # anything secret is fine } } } @@ -227,8 +228,8 @@ module "ingress" { "gethomepage.dev/pod-selector" = "" "gethomepage.dev/widget.type" = "nextcloud" "gethomepage.dev/widget.url" = "https://nextcloud.viktorbarzin.me" - "gethomepage.dev/widget.username" = var.homepage_credentials["nextcloud"]["username"] - "gethomepage.dev/widget.password" = var.homepage_credentials["nextcloud"]["password"] + "gethomepage.dev/widget.username" = local.homepage_credentials["nextcloud"]["username"] + "gethomepage.dev/widget.password" = local.homepage_credentials["nextcloud"]["password"] } } diff --git a/stacks/nextcloud/terragrunt.hcl b/stacks/nextcloud/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/nextcloud/terragrunt.hcl +++ b/stacks/nextcloud/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/ollama/main.tf b/stacks/ollama/main.tf index 1a1be2bf..6677bbcf 100644 --- a/stacks/ollama/main.tf +++ b/stacks/ollama/main.tf @@ -2,13 +2,18 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "ollama_api_credentials" { - type = map(string) - sensitive = true -} variable "nfs_server" { type = string } variable "ollama_host" { type = string } +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "ollama" +} + +locals { + api_credentials = jsondecode(data.vault_kv_secret_v2.secrets.data["api_credentials"]) +} + resource "kubernetes_namespace" "ollama" { metadata { @@ -167,11 +172,11 @@ module "ollama-ingress" { # Ollama API ingress for external access (basicAuth protected) locals { - ollama_api_htpasswd = join("\n", [for name, pass in var.ollama_api_credentials : "${name}:${bcrypt(pass, 10)}"]) + ollama_api_htpasswd = join("\n", [for name, pass in local.api_credentials : "${name}:${bcrypt(pass, 10)}"]) } resource "kubernetes_secret" "ollama_api_basic_auth" { - count = length(var.ollama_api_credentials) > 0 ? 1 : 0 + count = length(local.api_credentials) > 0 ? 1 : 0 metadata { name = "ollama-api-basic-auth-secret" namespace = kubernetes_namespace.ollama.metadata[0].name @@ -188,7 +193,7 @@ resource "kubernetes_secret" "ollama_api_basic_auth" { } resource "kubernetes_manifest" "ollama_api_basic_auth_middleware" { - count = length(var.ollama_api_credentials) > 0 ? 1 : 0 + count = length(local.api_credentials) > 0 ? 1 : 0 manifest = { apiVersion = "traefik.io/v1alpha1" kind = "Middleware" diff --git a/stacks/ollama/providers.tf b/stacks/ollama/providers.tf index 7b5cc7b8..516f9fed 100644 --- a/stacks/ollama/providers.tf +++ b/stacks/ollama/providers.tf @@ -2,7 +2,6 @@ variable "kube_config_path" { type = string default = "~/.kube/config" - sensitive = true } provider "kubernetes" { diff --git a/stacks/ollama/terragrunt.hcl b/stacks/ollama/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/ollama/terragrunt.hcl +++ b/stacks/ollama/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/onlyoffice/main.tf b/stacks/onlyoffice/main.tf index 8c1f754e..611e39ea 100644 --- a/stacks/onlyoffice/main.tf +++ b/stacks/onlyoffice/main.tf @@ -2,18 +2,14 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "onlyoffice_db_password" { - type = string - sensitive = true -} -variable "onlyoffice_jwt_token" { - type = string - sensitive = true -} variable "nfs_server" { type = string } variable "redis_host" { type = string } variable "mysql_host" { type = string } +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "onlyoffice" +} resource "kubernetes_namespace" "onlyoffice" { metadata { @@ -140,7 +136,7 @@ resource "kubernetes_deployment" "onlyoffice-document-server" { } env { name = "DB_PWD" - value = var.onlyoffice_db_password + value = data.vault_kv_secret_v2.secrets.data["db_password"] } env { name = "REDIS_SERVER_HOST" @@ -152,7 +148,7 @@ resource "kubernetes_deployment" "onlyoffice-document-server" { } env { name = "JWT_SECRET" - value = var.onlyoffice_jwt_token + value = data.vault_kv_secret_v2.secrets.data["jwt_token"] } volume_mount { diff --git a/stacks/onlyoffice/terragrunt.hcl b/stacks/onlyoffice/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/onlyoffice/terragrunt.hcl +++ b/stacks/onlyoffice/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/openclaw/main.tf b/stacks/openclaw/main.tf index 6f26efe7..45b808cb 100644 --- a/stacks/openclaw/main.tf +++ b/stacks/openclaw/main.tf @@ -2,48 +2,17 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "openclaw_ssh_key" { - type = string - sensitive = true -} -variable "openclaw_skill_secrets" { - type = map(string) - sensitive = true -} -variable "llama_api_key" { - type = string - sensitive = true -} -variable "brave_api_key" { - type = string - sensitive = true -} -variable "openrouter_api_key" { - type = string - sensitive = true -} -variable "nvidia_api_key" { - type = string - sensitive = true -} -variable "anthropic_api_key" { - type = string - sensitive = true -} -variable "openclaw_telegram_bot_token" { - type = string - sensitive = true -} -variable "forgejo_api_token" { - type = string - sensitive = true -} -variable "claude_memory_api_key" { - type = string - sensitive = true -} variable "nfs_server" { type = string } +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "openclaw" +} + +locals { + skill_secrets = jsondecode(data.vault_kv_secret_v2.secrets.data["skill_secrets"]) +} + resource "kubernetes_namespace" "openclaw" { metadata { @@ -89,7 +58,7 @@ resource "kubernetes_secret" "ssh_key" { namespace = kubernetes_namespace.openclaw.metadata[0].name } data = { - "id_rsa" = var.openclaw_ssh_key + "id_rsa" = data.vault_kv_secret_v2.secrets.data["ssh_key"] } type = "generic" } @@ -166,7 +135,7 @@ resource "kubernetes_config_map" "openclaw_config" { search = { enabled = true provider = "brave" - apiKey = var.brave_api_key + apiKey = data.vault_kv_secret_v2.secrets.data["brave_api_key"] maxResults = 5 } fetch = { @@ -192,7 +161,7 @@ resource "kubernetes_config_map" "openclaw_config" { channels = { telegram = { enabled = true - botToken = var.openclaw_telegram_bot_token + botToken = data.vault_kv_secret_v2.secrets.data["telegram_bot_token"] dmPolicy = "allowlist" allowFrom = ["tg:8281953845"] groupPolicy = "allowlist" @@ -213,7 +182,7 @@ resource "kubernetes_config_map" "openclaw_config" { anthropic = { baseUrl = "https://api.anthropic.com/v1" api = "anthropic-messages" - apiKey = var.anthropic_api_key + apiKey = data.vault_kv_secret_v2.secrets.data["anthropic_api_key"] models = [ { id = "claude-sonnet-4-20250514", name = "Claude Sonnet 4", reasoning = true, input = ["text", "image"], contextWindow = 200000, maxTokens = 16384, cost = { input = 0.003, output = 0.015, cacheRead = 0.0003, cacheWrite = 0.00375 } }, { id = "claude-opus-4-20250514", name = "Claude Opus 4", reasoning = true, input = ["text", "image"], contextWindow = 200000, maxTokens = 16384, cost = { input = 0.015, output = 0.075, cacheRead = 0.0015, cacheWrite = 0.01875 } }, @@ -223,7 +192,7 @@ resource "kubernetes_config_map" "openclaw_config" { nim = { baseUrl = "https://integrate.api.nvidia.com/v1" api = "openai-completions" - apiKey = var.nvidia_api_key + apiKey = data.vault_kv_secret_v2.secrets.data["nvidia_api_key"] models = [ { id = "deepseek-ai/deepseek-v3.2", name = "DeepSeek V3.2", reasoning = false, input = ["text"], contextWindow = 164000, maxTokens = 16384, cost = { input = 0, output = 0, cacheRead = 0, cacheWrite = 0 } }, { id = "qwen/qwen3.5-397b-a17b", name = "Qwen 3.5", reasoning = true, input = ["text"], contextWindow = 262000, maxTokens = 16384, cost = { input = 0, output = 0, cacheRead = 0, cacheWrite = 0 } }, @@ -236,7 +205,7 @@ resource "kubernetes_config_map" "openclaw_config" { openrouter = { baseUrl = "https://openrouter.ai/api/v1" api = "openai-completions" - apiKey = var.openrouter_api_key + apiKey = data.vault_kv_secret_v2.secrets.data["openrouter_api_key"] models = [ { id = "stepfun/step-3.5-flash:free", name = "Step 3.5 Flash", reasoning = true, input = ["text"], contextWindow = 256000, maxTokens = 16384, cost = { input = 0, output = 0, cacheRead = 0, cacheWrite = 0 } }, { id = "arcee-ai/trinity-large-preview:free", name = "Trinity Large", reasoning = false, input = ["text"], contextWindow = 131000, maxTokens = 16384, cost = { input = 0, output = 0, cacheRead = 0, cacheWrite = 0 } }, @@ -244,7 +213,7 @@ resource "kubernetes_config_map" "openclaw_config" { } llama-as-openai = { baseUrl = "https://api.llama.com/compat/v1" - apiKey = var.llama_api_key + apiKey = data.vault_kv_secret_v2.secrets.data["llama_api_key"] api = "openai-completions" models = [ { id = "Llama-4-Maverick-17B-128E-Instruct-FP8", name = "Llama 4 Maverick", reasoning = false, input = ["text"], contextWindow = 200000, maxTokens = 16384, cost = { input = 0, output = 0, cacheRead = 0, cacheWrite = 0 } }, @@ -574,7 +543,7 @@ resource "kubernetes_deployment" "openclaw" { } env { name = "HOME_ASSISTANT_TOKEN" - value = var.openclaw_skill_secrets["home_assistant_token"] + value = local.skill_secrets["home_assistant_token"] } env { name = "HOME_ASSISTANT_SOFIA_URL" @@ -582,17 +551,17 @@ resource "kubernetes_deployment" "openclaw" { } env { name = "HOME_ASSISTANT_SOFIA_TOKEN" - value = var.openclaw_skill_secrets["home_assistant_sofia_token"] + value = local.skill_secrets["home_assistant_sofia_token"] } # Skill secrets - Uptime Kuma env { name = "UPTIME_KUMA_PASSWORD" - value = var.openclaw_skill_secrets["uptime_kuma_password"] + value = local.skill_secrets["uptime_kuma_password"] } # Skill secrets - Slack env { name = "SLACK_WEBHOOK_URL" - value = var.openclaw_skill_secrets["slack_webhook"] + value = local.skill_secrets["slack_webhook"] } # Memory API env { @@ -601,7 +570,7 @@ resource "kubernetes_deployment" "openclaw" { } env { name = "MEMORY_API_KEY" - value = var.claude_memory_api_key + value = data.vault_kv_secret_v2.secrets.data["claude_memory_api_key"] } # Python packages path for skills env { @@ -659,11 +628,11 @@ resource "kubernetes_deployment" "openclaw" { } env { name = "NVIDIA_API_KEY" - value = var.nvidia_api_key + value = data.vault_kv_secret_v2.secrets.data["nvidia_api_key"] } env { name = "OPENROUTER_API_KEY" - value = var.openrouter_api_key + value = data.vault_kv_secret_v2.secrets.data["openrouter_api_key"] } volume_mount { name = "tools" @@ -1122,11 +1091,11 @@ resource "kubernetes_cron_job_v1" "task_processor" { env { name = "FORGEJO_TOKEN" - value = var.forgejo_api_token + value = data.vault_kv_secret_v2.secrets.data["forgejo_api_token"] } env { name = "OPENCLAW_TOKEN" - value = var.nvidia_api_key + value = data.vault_kv_secret_v2.secrets.data["nvidia_api_key"] } resources { diff --git a/stacks/openclaw/providers.tf b/stacks/openclaw/providers.tf index 7b5cc7b8..516f9fed 100644 --- a/stacks/openclaw/providers.tf +++ b/stacks/openclaw/providers.tf @@ -2,7 +2,6 @@ variable "kube_config_path" { type = string default = "~/.kube/config" - sensitive = true } provider "kubernetes" { diff --git a/stacks/openclaw/terragrunt.hcl b/stacks/openclaw/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/openclaw/terragrunt.hcl +++ b/stacks/openclaw/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/owntracks/main.tf b/stacks/owntracks/main.tf index 3c767543..44e61c64 100644 --- a/stacks/owntracks/main.tf +++ b/stacks/owntracks/main.tf @@ -2,12 +2,17 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "owntracks_credentials" { - type = map(string) - sensitive = true -} variable "nfs_server" { type = string } +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "owntracks" +} + +locals { + credentials = jsondecode(data.vault_kv_secret_v2.secrets.data["credentials"]) +} + resource "kubernetes_namespace" "owntracks" { metadata { @@ -27,7 +32,7 @@ module "tls_secret" { locals { username = "owntracks" - htpasswd = join("\n", [for name, pass in var.owntracks_credentials : "${name}:${bcrypt(pass, 10)}"]) + htpasswd = join("\n", [for name, pass in local.credentials : "${name}:${bcrypt(pass, 10)}"]) } resource "kubernetes_secret" "basic_auth" { diff --git a/stacks/owntracks/terragrunt.hcl b/stacks/owntracks/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/owntracks/terragrunt.hcl +++ b/stacks/owntracks/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/paperless-ngx/main.tf b/stacks/paperless-ngx/main.tf index 6eaa79da..0ac6716c 100644 --- a/stacks/paperless-ngx/main.tf +++ b/stacks/paperless-ngx/main.tf @@ -2,18 +2,19 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "paperless_db_password" { - type = string - sensitive = true -} -variable "homepage_credentials" { - type = map(any) - sensitive = true -} variable "nfs_server" { type = string } variable "redis_host" { type = string } variable "mysql_host" { type = string } +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "paperless-ngx" +} + +locals { + homepage_credentials = jsondecode(data.vault_kv_secret_v2.secrets.data["homepage_credentials"]) +} + resource "kubernetes_namespace" "paperless-ngx" { metadata { @@ -104,7 +105,7 @@ resource "kubernetes_deployment" "paperless-ngx" { } env { name = "PAPERLESS_DBPASS" - value = var.paperless_db_password + value = data.vault_kv_secret_v2.secrets.data["db_password"] } env { name = "PAPERLESS_CSRF_TRUSTED_ORIGINS" @@ -191,8 +192,8 @@ module "ingress" { "gethomepage.dev/widget.type" = "paperlessngx" "gethomepage.dev/widget.url" = "http://paperless-ngx.paperless-ngx.svc.cluster.local" # "gethomepage.dev/widget.token" = var.homepage_token - "gethomepage.dev/widget.username" = var.homepage_credentials["paperless-ngx"]["username"] - "gethomepage.dev/widget.password" = var.homepage_credentials["paperless-ngx"]["password"] + "gethomepage.dev/widget.username" = local.homepage_credentials["paperless-ngx"]["username"] + "gethomepage.dev/widget.password" = local.homepage_credentials["paperless-ngx"]["password"] "gethomepage.dev/widget.fields" = "[\"total\"]" "gethomepage.dev/pod-selector" = "" # gethomepage.dev/weight: 10 # optional diff --git a/stacks/paperless-ngx/terragrunt.hcl b/stacks/paperless-ngx/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/paperless-ngx/terragrunt.hcl +++ b/stacks/paperless-ngx/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/platform/main.tf b/stacks/platform/main.tf index d2fb5018..4b792389 100644 --- a/stacks/platform/main.tf +++ b/stacks/platform/main.tf @@ -21,7 +21,7 @@ # Variable Declarations # ============================================================================= -# --- Core --- +# --- Core (non-secret, from config.tfvars) --- variable "tls_secret_name" { type = string } @@ -35,91 +35,15 @@ variable "prod" { type = bool default = false } - -# --- dbaas --- -variable "dbaas_root_password" { - type = string - sensitive = true -} -variable "dbaas_postgresql_root_password" { - type = string - sensitive = true -} -variable "dbaas_pgadmin_password" { - type = string - sensitive = true -} - -# --- traefik --- -variable "ingress_crowdsec_api_key" { - type = string - sensitive = true -} -variable "auth_fallback_htpasswd" { - type = string - sensitive = true - default = "" -} - -# --- technitium --- -variable "technitium_db_password" { - type = string - sensitive = true -} -variable "homepage_credentials" { - type = map(any) - sensitive = true -} - -# --- headscale --- -variable "headscale_config" { type = string } -variable "headscale_acl" { type = string } variable "k8s_ca_cert" { type = string default = "" } - -# --- authentik / rbac / k8s-portal --- -variable "authentik_secret_key" { - type = string - sensitive = true -} -variable "authentik_postgres_password" { - type = string - sensitive = true -} -variable "k8s_users" { - type = map(any) - default = {} -} variable "ssh_private_key" { type = string default = "" sensitive = true } - -# --- crowdsec --- -variable "crowdsec_enroll_key" { type = string } -variable "crowdsec_db_password" { - type = string - sensitive = true -} -variable "crowdsec_dash_api_key" { - type = string - sensitive = true -} -variable "crowdsec_dash_machine_id" { type = string } -variable "crowdsec_dash_machine_password" { - type = string - sensitive = true -} -variable "alertmanager_slack_api_url" { type = string } - -# --- cloudflared --- -variable "cloudflare_api_key" { - type = string - sensitive = true -} variable "cloudflare_email" { type = string } variable "cloudflare_account_id" { type = string } variable "cloudflare_zone_id" { type = string } @@ -127,91 +51,23 @@ variable "cloudflare_tunnel_id" { type = string } variable "public_ip" { type = string } variable "cloudflare_proxied_names" {} variable "cloudflare_non_proxied_names" {} -variable "cloudflare_tunnel_token" { - type = string - sensitive = true -} - -# --- monitoring --- -variable "alertmanager_account_password" { - type = string - sensitive = true -} variable "monitoring_idrac_username" { type = string } -variable "monitoring_idrac_password" { - type = string - sensitive = true -} -variable "tiny_tuya_service_secret" { - type = string - sensitive = true -} -variable "haos_api_token" { - type = string - sensitive = true -} -variable "pve_password" { - type = string - sensitive = true -} -variable "grafana_db_password" { - type = string - sensitive = true -} -variable "grafana_admin_password" { - type = string - sensitive = true + +# --- Vault KV secrets --- +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "platform" } -# --- vaultwarden --- -variable "vaultwarden_smtp_password" { - type = string - sensitive = true -} - -# --- wireguard --- -variable "wireguard_wg_0_conf" { type = string } -variable "wireguard_wg_0_key" { type = string } -variable "wireguard_firewall_sh" { type = string } - -# --- xray --- -variable "xray_reality_clients" { type = list(map(string)) } -variable "xray_reality_private_key" { - type = string - sensitive = true -} -variable "xray_reality_short_ids" { type = list(string) } - -# --- mailserver --- -variable "mailserver_accounts" {} -variable "mailserver_aliases" {} -variable "mailserver_opendkim_key" {} -variable "mailserver_sasl_passwd" {} -variable "mailserver_roundcubemail_db_password" { - type = string - sensitive = true -} - -# --- infra-maintenance --- -variable "webhook_handler_git_user" { type = string } -variable "webhook_handler_git_token" { - type = string - sensitive = true -} -variable "technitium_username" { type = string } -variable "technitium_password" { - type = string - sensitive = true -} - -# --- iscsi-csi --- -variable "truenas_api_key" { - type = string - sensitive = true -} -variable "truenas_ssh_private_key" { - type = string - sensitive = true +locals { + homepage_credentials = jsondecode(data.vault_kv_secret_v2.secrets.data["homepage_credentials"]) + k8s_users = jsondecode(data.vault_kv_secret_v2.secrets.data["k8s_users"]) + xray_reality_clients = jsondecode(data.vault_kv_secret_v2.secrets.data["xray_reality_clients"]) + xray_reality_short_ids = jsondecode(data.vault_kv_secret_v2.secrets.data["xray_reality_short_ids"]) + mailserver_accounts = jsondecode(data.vault_kv_secret_v2.secrets.data["mailserver_accounts"]) + mailserver_aliases = jsondecode(data.vault_kv_secret_v2.secrets.data["mailserver_aliases"]) + mailserver_opendkim_key = jsondecode(data.vault_kv_secret_v2.secrets.data["mailserver_opendkim_key"]) + mailserver_sasl_passwd = jsondecode(data.vault_kv_secret_v2.secrets.data["mailserver_sasl_passwd"]) } # ============================================================================= @@ -234,9 +90,9 @@ module "dbaas" { prod = var.prod tls_secret_name = var.tls_secret_name nfs_server = var.nfs_server - dbaas_root_password = var.dbaas_root_password - postgresql_root_password = var.dbaas_postgresql_root_password - pgadmin_password = var.dbaas_pgadmin_password + dbaas_root_password = data.vault_kv_secret_v2.secrets.data["dbaas_root_password"] + postgresql_root_password = data.vault_kv_secret_v2.secrets.data["dbaas_postgresql_root_password"] + pgadmin_password = data.vault_kv_secret_v2.secrets.data["dbaas_pgadmin_password"] kube_config_path = var.kube_config_path tier = local.tiers.cluster } @@ -257,10 +113,10 @@ module "redis" { module "traefik" { source = "./modules/traefik" tier = local.tiers.core - crowdsec_api_key = var.ingress_crowdsec_api_key + crowdsec_api_key = data.vault_kv_secret_v2.secrets.data["ingress_crowdsec_api_key"] redis_host = var.redis_host tls_secret_name = var.tls_secret_name - auth_fallback_htpasswd = var.auth_fallback_htpasswd + auth_fallback_htpasswd = data.vault_kv_secret_v2.secrets.data["auth_fallback_htpasswd"] } # ----------------------------------------------------------------------------- @@ -271,10 +127,10 @@ module "technitium" { tls_secret_name = var.tls_secret_name nfs_server = var.nfs_server mysql_host = var.mysql_host - homepage_token = var.homepage_credentials["technitium"]["token"] - technitium_db_password = var.technitium_db_password - technitium_username = var.technitium_username - technitium_password = var.technitium_password + homepage_token = local.homepage_credentials["technitium"]["token"] + technitium_db_password = data.vault_kv_secret_v2.secrets.data["technitium_db_password"] + technitium_username = data.vault_kv_secret_v2.secrets.data["technitium_username"] + technitium_password = data.vault_kv_secret_v2.secrets.data["technitium_password"] tier = local.tiers.core } @@ -285,9 +141,9 @@ module "headscale" { source = "./modules/headscale" tls_secret_name = var.tls_secret_name nfs_server = var.nfs_server - headscale_config = var.headscale_config - headscale_acl = var.headscale_acl - homepage_token = try(var.homepage_credentials["headscale"]["api_key"], "") + headscale_config = data.vault_kv_secret_v2.secrets.data["headscale_config"] + headscale_acl = data.vault_kv_secret_v2.secrets.data["headscale_acl"] + homepage_token = try(local.homepage_credentials["headscale"]["api_key"], "") tier = local.tiers.core } @@ -298,10 +154,10 @@ module "authentik" { source = "./modules/authentik" tier = local.tiers.cluster tls_secret_name = var.tls_secret_name - secret_key = var.authentik_secret_key - postgres_password = var.authentik_postgres_password + secret_key = data.vault_kv_secret_v2.secrets.data["authentik_secret_key"] + postgres_password = data.vault_kv_secret_v2.secrets.data["authentik_postgres_password"] redis_host = var.redis_host - homepage_token = try(var.homepage_credentials["authentik"]["token"], "") + homepage_token = try(local.homepage_credentials["authentik"]["token"], "") } # ----------------------------------------------------------------------------- @@ -311,7 +167,7 @@ module "rbac" { source = "./modules/rbac" tier = local.tiers.cluster tls_secret_name = var.tls_secret_name - k8s_users = var.k8s_users + k8s_users = local.k8s_users ssh_private_key = var.ssh_private_key } @@ -333,14 +189,14 @@ module "crowdsec" { tier = local.tiers.cluster tls_secret_name = var.tls_secret_name mysql_host = var.mysql_host - homepage_username = var.homepage_credentials["crowdsec"]["username"] - homepage_password = var.homepage_credentials["crowdsec"]["password"] - enroll_key = var.crowdsec_enroll_key - db_password = var.crowdsec_db_password - crowdsec_dash_api_key = var.crowdsec_dash_api_key - crowdsec_dash_machine_id = var.crowdsec_dash_machine_id - crowdsec_dash_machine_password = var.crowdsec_dash_machine_password - slack_webhook_url = var.alertmanager_slack_api_url + homepage_username = local.homepage_credentials["crowdsec"]["username"] + homepage_password = local.homepage_credentials["crowdsec"]["password"] + enroll_key = data.vault_kv_secret_v2.secrets.data["crowdsec_enroll_key"] + db_password = data.vault_kv_secret_v2.secrets.data["crowdsec_db_password"] + crowdsec_dash_api_key = data.vault_kv_secret_v2.secrets.data["crowdsec_dash_api_key"] + crowdsec_dash_machine_id = data.vault_kv_secret_v2.secrets.data["crowdsec_dash_machine_id"] + crowdsec_dash_machine_password = data.vault_kv_secret_v2.secrets.data["crowdsec_dash_machine_password"] + slack_webhook_url = data.vault_kv_secret_v2.secrets.data["alertmanager_slack_api_url"] } # ----------------------------------------------------------------------------- @@ -351,15 +207,15 @@ module "monitoring" { tls_secret_name = var.tls_secret_name nfs_server = var.nfs_server mysql_host = var.mysql_host - alertmanager_account_password = var.alertmanager_account_password + alertmanager_account_password = data.vault_kv_secret_v2.secrets.data["alertmanager_account_password"] idrac_username = var.monitoring_idrac_username - idrac_password = var.monitoring_idrac_password - alertmanager_slack_api_url = var.alertmanager_slack_api_url - tiny_tuya_service_secret = var.tiny_tuya_service_secret - haos_api_token = var.haos_api_token - pve_password = var.pve_password - grafana_db_password = var.grafana_db_password - grafana_admin_password = var.grafana_admin_password + idrac_password = data.vault_kv_secret_v2.secrets.data["monitoring_idrac_password"] + alertmanager_slack_api_url = data.vault_kv_secret_v2.secrets.data["alertmanager_slack_api_url"] + tiny_tuya_service_secret = data.vault_kv_secret_v2.secrets.data["tiny_tuya_service_secret"] + haos_api_token = data.vault_kv_secret_v2.secrets.data["haos_api_token"] + pve_password = data.vault_kv_secret_v2.secrets.data["pve_password"] + grafana_db_password = data.vault_kv_secret_v2.secrets.data["grafana_db_password"] + grafana_admin_password = data.vault_kv_secret_v2.secrets.data["grafana_admin_password"] tier = local.tiers.cluster } @@ -371,7 +227,7 @@ module "vaultwarden" { tls_secret_name = var.tls_secret_name nfs_server = var.nfs_server mail_host = var.mail_host - smtp_password = var.vaultwarden_smtp_password + smtp_password = data.vault_kv_secret_v2.secrets.data["vaultwarden_smtp_password"] tier = local.tiers.edge } @@ -381,9 +237,9 @@ module "vaultwarden" { module "reverse-proxy" { source = "./modules/reverse_proxy" tls_secret_name = var.tls_secret_name - truenas_homepage_token = var.homepage_credentials["reverse_proxy"]["truenas_token"] - pfsense_homepage_token = var.homepage_credentials["reverse_proxy"]["pfsense_token"] - haos_homepage_token = try(var.homepage_credentials["home_assistant"]["token"], "") + truenas_homepage_token = local.homepage_credentials["reverse_proxy"]["truenas_token"] + pfsense_homepage_token = local.homepage_credentials["reverse_proxy"]["pfsense_token"] + haos_homepage_token = try(local.homepage_credentials["home_assistant"]["token"], "") } # ----------------------------------------------------------------------------- @@ -420,8 +276,8 @@ module "iscsi-csi" { source = "./modules/iscsi-csi" tier = local.tiers.cluster truenas_host = var.nfs_server # Same TrueNAS host - truenas_api_key = var.truenas_api_key - truenas_ssh_private_key = var.truenas_ssh_private_key + truenas_api_key = data.vault_kv_secret_v2.secrets.data["truenas_api_key"] + truenas_ssh_private_key = data.vault_kv_secret_v2.secrets.data["truenas_ssh_private_key"] } # ----------------------------------------------------------------------------- @@ -472,9 +328,9 @@ module "uptime-kuma" { module "wireguard" { source = "./modules/wireguard" tls_secret_name = var.tls_secret_name - wg_0_conf = var.wireguard_wg_0_conf - wg_0_key = var.wireguard_wg_0_key - firewall_sh = var.wireguard_firewall_sh + wg_0_conf = data.vault_kv_secret_v2.secrets.data["wireguard_wg_0_conf"] + wg_0_key = data.vault_kv_secret_v2.secrets.data["wireguard_wg_0_key"] + firewall_sh = data.vault_kv_secret_v2.secrets.data["wireguard_firewall_sh"] tier = local.tiers.core } @@ -486,9 +342,9 @@ module "xray" { tls_secret_name = var.tls_secret_name tier = local.tiers.core - xray_reality_clients = var.xray_reality_clients - xray_reality_private_key = var.xray_reality_private_key - xray_reality_short_ids = var.xray_reality_short_ids + xray_reality_clients = local.xray_reality_clients + xray_reality_private_key = data.vault_kv_secret_v2.secrets.data["xray_reality_private_key"] + xray_reality_short_ids = local.xray_reality_short_ids } # ----------------------------------------------------------------------------- @@ -499,11 +355,11 @@ module "mailserver" { tls_secret_name = var.tls_secret_name nfs_server = var.nfs_server mysql_host = var.mysql_host - mailserver_accounts = var.mailserver_accounts - postfix_account_aliases = var.mailserver_aliases - opendkim_key = var.mailserver_opendkim_key - sasl_passwd = var.mailserver_sasl_passwd - roundcube_db_password = var.mailserver_roundcubemail_db_password + mailserver_accounts = local.mailserver_accounts + postfix_account_aliases = local.mailserver_aliases + opendkim_key = local.mailserver_opendkim_key + sasl_passwd = local.mailserver_sasl_passwd + roundcube_db_password = data.vault_kv_secret_v2.secrets.data["mailserver_roundcubemail_db_password"] tier = local.tiers.edge } @@ -515,7 +371,7 @@ module "cloudflared" { tier = local.tiers.core tls_secret_name = var.tls_secret_name - cloudflare_api_key = var.cloudflare_api_key + cloudflare_api_key = data.vault_kv_secret_v2.secrets.data["cloudflare_api_key"] cloudflare_email = var.cloudflare_email cloudflare_account_id = var.cloudflare_account_id cloudflare_zone_id = var.cloudflare_zone_id @@ -523,7 +379,7 @@ module "cloudflared" { public_ip = var.public_ip cloudflare_proxied_names = var.cloudflare_proxied_names cloudflare_non_proxied_names = var.cloudflare_non_proxied_names - cloudflare_tunnel_token = var.cloudflare_tunnel_token + cloudflare_tunnel_token = data.vault_kv_secret_v2.secrets.data["cloudflare_tunnel_token"] } # ----------------------------------------------------------------------------- @@ -532,10 +388,10 @@ module "cloudflared" { module "infra-maintenance" { source = "./modules/infra-maintenance" nfs_server = var.nfs_server - git_user = var.webhook_handler_git_user - git_token = var.webhook_handler_git_token - technitium_username = var.technitium_username - technitium_password = var.technitium_password + git_user = data.vault_kv_secret_v2.secrets.data["webhook_handler_git_user"] + git_token = data.vault_kv_secret_v2.secrets.data["webhook_handler_git_token"] + technitium_username = data.vault_kv_secret_v2.secrets.data["technitium_username"] + technitium_password = data.vault_kv_secret_v2.secrets.data["technitium_password"] } # ============================================================================= diff --git a/stacks/platform/terragrunt.hcl b/stacks/platform/terragrunt.hcl index b81cbabd..1654d3a9 100644 --- a/stacks/platform/terragrunt.hcl +++ b/stacks/platform/terragrunt.hcl @@ -7,3 +7,8 @@ dependency "infra" { config_path = "../infra" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/plotting-book/main.tf b/stacks/plotting-book/main.tf index 6110ea5f..1d1ae8a6 100644 --- a/stacks/plotting-book/main.tf +++ b/stacks/plotting-book/main.tf @@ -2,10 +2,6 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "plotting_book_session_secret" { - type = string - sensitive = true -} variable "plotting_book_google_client_id" { type = string sensitive = true @@ -15,6 +11,10 @@ variable "plotting_book_google_client_secret" { sensitive = true } +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "plotting-book" +} resource "kubernetes_namespace" "plotting-book" { metadata { @@ -92,7 +92,7 @@ resource "kubernetes_deployment" "plotting-book" { image_pull_policy = "Always" env { name = "SESSION_SECRET" - value = var.plotting_book_session_secret + value = data.vault_kv_secret_v2.secrets.data["session_secret"] } env { name = "GOOGLE_CLIENT_ID" diff --git a/stacks/plotting-book/terragrunt.hcl b/stacks/plotting-book/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/plotting-book/terragrunt.hcl +++ b/stacks/plotting-book/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/real-estate-crawler/main.tf b/stacks/real-estate-crawler/main.tf index b891e973..13b85787 100644 --- a/stacks/real-estate-crawler/main.tf +++ b/stacks/real-estate-crawler/main.tf @@ -2,15 +2,19 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "realestate_crawler_db_password" { - type = string - sensitive = true -} -variable "realestate_crawler_notification_settings" { type = map(string) } variable "nfs_server" { type = string } variable "redis_host" { type = string } variable "mysql_host" { type = string } +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "real-estate-crawler" +} + +locals { + notification_settings = jsondecode(data.vault_kv_secret_v2.secrets.data["notification_settings"]) +} + resource "kubernetes_namespace" "realestate-crawler" { metadata { @@ -150,7 +154,7 @@ resource "kubernetes_deployment" "realestate-crawler-api" { } env { name = "DB_CONNECTION_STRING" - value = "mysql://wrongmove:${var.realestate_crawler_db_password}@${var.mysql_host}:3306/wrongmove" + value = "mysql://wrongmove:${data.vault_kv_secret_v2.secrets.data["db_password"]}@${var.mysql_host}:3306/wrongmove" } # env { @@ -188,7 +192,7 @@ resource "kubernetes_deployment" "realestate-crawler-api" { } env { name = "SLACK_WEBHOOK_URL" - value = var.realestate_crawler_notification_settings["slack"] + value = local.notification_settings["slack"] } env { name = "WEBAUTHN_RP_ID" @@ -339,7 +343,7 @@ resource "kubernetes_deployment" "realestate-crawler-celery" { } env { name = "DB_CONNECTION_STRING" - value = "mysql://wrongmove:${var.realestate_crawler_db_password}@${var.mysql_host}:3306/wrongmove" + value = "mysql://wrongmove:${data.vault_kv_secret_v2.secrets.data["db_password"]}@${var.mysql_host}:3306/wrongmove" } env { name = "CELERY_BROKER_URL" @@ -351,7 +355,7 @@ resource "kubernetes_deployment" "realestate-crawler-celery" { } env { name = "SLACK_WEBHOOK_URL" - value = lookup(var.realestate_crawler_notification_settings, "slack", "") + value = lookup(local.notification_settings, "slack", "") } env { name = "OSRM_FOOT_URL" @@ -447,7 +451,7 @@ resource "kubernetes_deployment" "realestate-crawler-celery-beat" { } env { name = "DB_CONNECTION_STRING" - value = "mysql://wrongmove:${var.realestate_crawler_db_password}@${var.mysql_host}:3306/wrongmove" + value = "mysql://wrongmove:${data.vault_kv_secret_v2.secrets.data["db_password"]}@${var.mysql_host}:3306/wrongmove" } env { name = "CELERY_BROKER_URL" @@ -459,7 +463,7 @@ resource "kubernetes_deployment" "realestate-crawler-celery-beat" { } env { name = "SCRAPE_SCHEDULES" - value = lookup(var.realestate_crawler_notification_settings, "scrape_schedules", "") + value = lookup(local.notification_settings, "scrape_schedules", "") } volume_mount { name = "data" diff --git a/stacks/real-estate-crawler/terragrunt.hcl b/stacks/real-estate-crawler/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/real-estate-crawler/terragrunt.hcl +++ b/stacks/real-estate-crawler/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/resume/main.tf b/stacks/resume/main.tf index b9cc933a..0c14fd0a 100644 --- a/stacks/resume/main.tf +++ b/stacks/resume/main.tf @@ -3,18 +3,18 @@ variable "tls_secret_name" { sensitive = true } variable "resume_database_url" { type = string } -variable "resume_auth_secret" { - type = string - sensitive = true -} -variable "mailserver_accounts" { type = map(any) } variable "nfs_server" { type = string } variable "mail_host" { type = string } +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "resume" +} locals { - namespace = "resume" - app_url = "https://resume.viktorbarzin.me" + namespace = "resume" + app_url = "https://resume.viktorbarzin.me" + mailserver_accounts = jsondecode(data.vault_kv_secret_v2.secrets.data["mailserver_accounts"]) } resource "kubernetes_namespace" "resume" { @@ -186,7 +186,7 @@ resource "kubernetes_deployment" "resume" { } env { name = "AUTH_SECRET" - value = var.resume_auth_secret + value = data.vault_kv_secret_v2.secrets.data["auth_secret"] } # Server config @@ -210,7 +210,7 @@ resource "kubernetes_deployment" "resume" { } env { name = "SMTP_PASS" - value = var.mailserver_accounts["info@viktorbarzin.me"] + value = local.mailserver_accounts["info@viktorbarzin.me"] } env { name = "SMTP_FROM" diff --git a/stacks/resume/terragrunt.hcl b/stacks/resume/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/resume/terragrunt.hcl +++ b/stacks/resume/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/rybbit/main.tf b/stacks/rybbit/main.tf index b300c8cd..713e663b 100644 --- a/stacks/rybbit/main.tf +++ b/stacks/rybbit/main.tf @@ -2,17 +2,13 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "clickhouse_password" { - type = string - sensitive = true -} -variable "clickhouse_postgres_password" { - type = string - sensitive = true -} variable "nfs_server" { type = string } variable "postgresql_host" { type = string } +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "rybbit" +} resource "kubernetes_namespace" "rybbit" { metadata { @@ -82,7 +78,7 @@ resource "kubernetes_deployment" "clickhouse" { } env { name = "CLICKHOUSE_PASSWORD" - value = var.clickhouse_password + value = data.vault_kv_secret_v2.secrets.data["clickhouse_password"] } port { name = "clickhouse" @@ -180,12 +176,12 @@ resource "kubernetes_cron_job_v1" "clickhouse_truncate_logs" { command = [ "sh", "-c", join(" && ", [ - "curl -s 'http://clickhouse.rybbit.svc.cluster.local:8123/?user=default&password=${var.clickhouse_password}' -d 'TRUNCATE TABLE IF EXISTS system.metric_log'", - "curl -s 'http://clickhouse.rybbit.svc.cluster.local:8123/?user=default&password=${var.clickhouse_password}' -d 'TRUNCATE TABLE IF EXISTS system.trace_log'", - "curl -s 'http://clickhouse.rybbit.svc.cluster.local:8123/?user=default&password=${var.clickhouse_password}' -d 'TRUNCATE TABLE IF EXISTS system.text_log'", - "curl -s 'http://clickhouse.rybbit.svc.cluster.local:8123/?user=default&password=${var.clickhouse_password}' -d 'TRUNCATE TABLE IF EXISTS system.asynchronous_metric_log'", - "curl -s 'http://clickhouse.rybbit.svc.cluster.local:8123/?user=default&password=${var.clickhouse_password}' -d 'TRUNCATE TABLE IF EXISTS system.query_log'", - "curl -s 'http://clickhouse.rybbit.svc.cluster.local:8123/?user=default&password=${var.clickhouse_password}' -d 'TRUNCATE TABLE IF EXISTS system.part_log'", + "curl -s 'http://clickhouse.rybbit.svc.cluster.local:8123/?user=default&password=${data.vault_kv_secret_v2.secrets.data["clickhouse_password"]}' -d 'TRUNCATE TABLE IF EXISTS system.metric_log'", + "curl -s 'http://clickhouse.rybbit.svc.cluster.local:8123/?user=default&password=${data.vault_kv_secret_v2.secrets.data["clickhouse_password"]}' -d 'TRUNCATE TABLE IF EXISTS system.trace_log'", + "curl -s 'http://clickhouse.rybbit.svc.cluster.local:8123/?user=default&password=${data.vault_kv_secret_v2.secrets.data["clickhouse_password"]}' -d 'TRUNCATE TABLE IF EXISTS system.text_log'", + "curl -s 'http://clickhouse.rybbit.svc.cluster.local:8123/?user=default&password=${data.vault_kv_secret_v2.secrets.data["clickhouse_password"]}' -d 'TRUNCATE TABLE IF EXISTS system.asynchronous_metric_log'", + "curl -s 'http://clickhouse.rybbit.svc.cluster.local:8123/?user=default&password=${data.vault_kv_secret_v2.secrets.data["clickhouse_password"]}' -d 'TRUNCATE TABLE IF EXISTS system.query_log'", + "curl -s 'http://clickhouse.rybbit.svc.cluster.local:8123/?user=default&password=${data.vault_kv_secret_v2.secrets.data["clickhouse_password"]}' -d 'TRUNCATE TABLE IF EXISTS system.part_log'", "echo 'System logs truncated'" ]) ] @@ -242,7 +238,7 @@ resource "kubernetes_deployment" "rybbit" { } env { name = "CLICKHOUSE_PASSWORD" - value = var.clickhouse_password + value = data.vault_kv_secret_v2.secrets.data["clickhouse_password"] } env { name = "POSTGRES_HOST" @@ -262,7 +258,7 @@ resource "kubernetes_deployment" "rybbit" { } env { name = "POSTGRES_PASSWORD" - value = var.clickhouse_postgres_password + value = data.vault_kv_secret_v2.secrets.data["postgres_password"] } env { name = "BASE_URL" diff --git a/stacks/rybbit/terragrunt.hcl b/stacks/rybbit/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/rybbit/terragrunt.hcl +++ b/stacks/rybbit/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/servarr/main.tf b/stacks/servarr/main.tf index 615e43f3..2f7e5c86 100644 --- a/stacks/servarr/main.tf +++ b/stacks/servarr/main.tf @@ -2,11 +2,15 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "aiostreams_database_connection_string" { type = string } variable "nfs_server" { type = string } -variable "homepage_credentials" { - type = map(any) - sensitive = true + +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "servarr" +} + +locals { + homepage_credentials = jsondecode(data.vault_kv_secret_v2.secrets.data["homepage_credentials"]) } @@ -37,7 +41,7 @@ module "prowlarr" { tls_secret_name = var.tls_secret_name tier = local.tiers.aux nfs_server = var.nfs_server - homepage_credentials = var.homepage_credentials + homepage_credentials = local.homepage_credentials } module "qbittorrent" { @@ -45,7 +49,7 @@ module "qbittorrent" { tls_secret_name = var.tls_secret_name tier = local.tiers.aux nfs_server = var.nfs_server - homepage_credentials = var.homepage_credentials + homepage_credentials = local.homepage_credentials } module "flaresolverr" { @@ -76,7 +80,7 @@ module "listenarr" { module "aiostreams" { source = "./aiostreams" tls_secret_name = var.tls_secret_name - aiostreams_database_connection_string = var.aiostreams_database_connection_string + aiostreams_database_connection_string = data.vault_kv_secret_v2.secrets.data["aiostreams_database_connection_string"] tier = local.tiers.aux nfs_server = var.nfs_server } diff --git a/stacks/servarr/terragrunt.hcl b/stacks/servarr/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/servarr/terragrunt.hcl +++ b/stacks/servarr/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/shadowsocks/main.tf b/stacks/shadowsocks/main.tf index 098cd727..1a71a5db 100644 --- a/stacks/shadowsocks/main.tf +++ b/stacks/shadowsocks/main.tf @@ -1,9 +1,8 @@ -variable "shadowsocks_password" { - type = string - sensitive = true +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "shadowsocks" } - variable "method" { default = "chacha20-ietf-poly1305" } @@ -57,7 +56,7 @@ resource "kubernetes_deployment" "shadowsocks" { } env { name = "PASSWORD" - value = var.shadowsocks_password + value = data.vault_kv_secret_v2.secrets.data["password"] } port { container_port = 8388 diff --git a/stacks/shadowsocks/terragrunt.hcl b/stacks/shadowsocks/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/shadowsocks/terragrunt.hcl +++ b/stacks/shadowsocks/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/speedtest/main.tf b/stacks/speedtest/main.tf index 5a07a66c..ace7d218 100644 --- a/stacks/speedtest/main.tf +++ b/stacks/speedtest/main.tf @@ -2,13 +2,13 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "speedtest_db_password" { - type = string - sensitive = true -} variable "nfs_server" { type = string } variable "mysql_host" { type = string } +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "speedtest" +} resource "kubernetes_namespace" "speedtest" { metadata { @@ -109,7 +109,7 @@ resource "kubernetes_deployment" "speedtest" { } env { name = "DB_PASSWORD" - value = var.speedtest_db_password + value = data.vault_kv_secret_v2.secrets.data["db_password"] } env { name = "APP_TIMEZONE" diff --git a/stacks/speedtest/terragrunt.hcl b/stacks/speedtest/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/speedtest/terragrunt.hcl +++ b/stacks/speedtest/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/tandoor/main.tf b/stacks/tandoor/main.tf index 6882a306..e94c143c 100644 --- a/stacks/tandoor/main.tf +++ b/stacks/tandoor/main.tf @@ -2,10 +2,6 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "tandoor_database_password" { - type = string - sensitive = true -} variable "tandoor_email_password" { type = string default = "" @@ -15,6 +11,10 @@ variable "nfs_server" { type = string } variable "postgresql_host" { type = string } variable "mail_host" { type = string } +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "tandoor" +} resource "kubernetes_namespace" "tandoor" { metadata { @@ -97,7 +97,7 @@ resource "kubernetes_deployment" "tandoor" { } env { name = "POSTGRES_PASSWORD" - value = var.tandoor_database_password + value = data.vault_kv_secret_v2.secrets.data["db_password"] } env { name = "TANDOOR_PORT" diff --git a/stacks/tandoor/providers.tf b/stacks/tandoor/providers.tf index 7b5cc7b8..516f9fed 100644 --- a/stacks/tandoor/providers.tf +++ b/stacks/tandoor/providers.tf @@ -2,7 +2,6 @@ variable "kube_config_path" { type = string default = "~/.kube/config" - sensitive = true } provider "kubernetes" { diff --git a/stacks/tandoor/terragrunt.hcl b/stacks/tandoor/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/tandoor/terragrunt.hcl +++ b/stacks/tandoor/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/trading-bot/main.tf b/stacks/trading-bot/main.tf index c5dea873..be40d2a9 100644 --- a/stacks/trading-bot/main.tf +++ b/stacks/trading-bot/main.tf @@ -6,52 +6,23 @@ variable "nfs_server" { type = string } variable "postgresql_host" { type = string } variable "redis_host" { type = string } variable "ollama_host" { type = string } -variable "dbaas_postgresql_root_password" { - type = string - sensitive = true -} -variable "trading_bot_db_password" { - type = string - sensitive = true -} -variable "trading_bot_alpaca_api_key" { - type = string - sensitive = true -} -variable "trading_bot_alpaca_secret_key" { - type = string - sensitive = true -} -variable "trading_bot_jwt_secret" { - type = string - sensitive = true -} -variable "trading_bot_reddit_client_id" { type = string } -variable "trading_bot_reddit_client_secret" { - type = string - sensitive = true -} -variable "trading_bot_alpha_vantage_api_key" { - type = string - sensitive = true -} -variable "trading_bot_fmp_api_key" { - type = string - sensitive = true +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "trading-bot" } locals { common_env = { - TRADING_DATABASE_URL = "postgresql+asyncpg://trading:${var.trading_bot_db_password}@${var.postgresql_host}:5432/trading" + TRADING_DATABASE_URL = "postgresql+asyncpg://trading:${data.vault_kv_secret_v2.secrets.data["db_password"]}@${var.postgresql_host}:5432/trading" TRADING_REDIS_URL = "redis://${var.redis_host}:6379/4" TRADING_LOG_LEVEL = "INFO" - TRADING_ALPACA_API_KEY = var.trading_bot_alpaca_api_key - TRADING_ALPACA_SECRET_KEY = var.trading_bot_alpaca_secret_key + TRADING_ALPACA_API_KEY = data.vault_kv_secret_v2.secrets.data["alpaca_api_key"] + TRADING_ALPACA_SECRET_KEY = data.vault_kv_secret_v2.secrets.data["alpaca_secret_key"] TRADING_ALPACA_BASE_URL = "https://paper-api.alpaca.markets" TRADING_PAPER_TRADING = "true" - TRADING_JWT_SECRET_KEY = var.trading_bot_jwt_secret - TRADING_REDDIT_CLIENT_ID = var.trading_bot_reddit_client_id - TRADING_REDDIT_CLIENT_SECRET = var.trading_bot_reddit_client_secret + TRADING_JWT_SECRET_KEY = data.vault_kv_secret_v2.secrets.data["jwt_secret"] + TRADING_REDDIT_CLIENT_ID = data.vault_kv_secret_v2.secrets.data["reddit_client_id"] + TRADING_REDDIT_CLIENT_SECRET = data.vault_kv_secret_v2.secrets.data["reddit_client_secret"] TRADING_REDDIT_USER_AGENT = "trading-bot/0.1" TRADING_OLLAMA_HOST = "http://${var.ollama_host}:11434" TRADING_OLLAMA_MODEL = "gemma3" @@ -60,8 +31,8 @@ locals { TRADING_POLL_INTERVAL_SECONDS = "60" TRADING_HISTORICAL_BARS = "100" TRADING_SNAPSHOT_INTERVAL_SECONDS = "60" - TRADING_ALPHA_VANTAGE_API_KEY = var.trading_bot_alpha_vantage_api_key - TRADING_FMP_API_KEY = var.trading_bot_fmp_api_key + TRADING_ALPHA_VANTAGE_API_KEY = data.vault_kv_secret_v2.secrets.data["alpha_vantage_api_key"] + TRADING_FMP_API_KEY = data.vault_kv_secret_v2.secrets.data["fmp_api_key"] TRADING_FUNDAMENTALS_CACHE_TTL_HOURS = "24" TRADING_RP_ID = "trading.viktorbarzin.me" TRADING_RP_NAME = "Trading Bot" @@ -103,15 +74,15 @@ resource "kubernetes_job" "db_init" { <<-EOT set -e # Create role if not exists - PGPASSWORD='${var.dbaas_postgresql_root_password}' psql -h ${var.postgresql_host} -U root -tc "SELECT 1 FROM pg_roles WHERE rolname='trading'" | grep -q 1 || \ - PGPASSWORD='${var.dbaas_postgresql_root_password}' psql -h ${var.postgresql_host} -U root -c "CREATE ROLE trading WITH LOGIN PASSWORD '${var.trading_bot_db_password}'" + PGPASSWORD='${data.vault_kv_secret_v2.secrets.data["dbaas_root_password"]}' psql -h ${var.postgresql_host} -U root -tc "SELECT 1 FROM pg_roles WHERE rolname='trading'" | grep -q 1 || \ + PGPASSWORD='${data.vault_kv_secret_v2.secrets.data["dbaas_root_password"]}' psql -h ${var.postgresql_host} -U root -c "CREATE ROLE trading WITH LOGIN PASSWORD '${data.vault_kv_secret_v2.secrets.data["db_password"]}'" # Create database if not exists - PGPASSWORD='${var.dbaas_postgresql_root_password}' psql -h ${var.postgresql_host} -U root -tc "SELECT 1 FROM pg_database WHERE datname='trading'" | grep -q 1 || \ - PGPASSWORD='${var.dbaas_postgresql_root_password}' psql -h ${var.postgresql_host} -U root -c "CREATE DATABASE trading OWNER trading" + PGPASSWORD='${data.vault_kv_secret_v2.secrets.data["dbaas_root_password"]}' psql -h ${var.postgresql_host} -U root -tc "SELECT 1 FROM pg_database WHERE datname='trading'" | grep -q 1 || \ + PGPASSWORD='${data.vault_kv_secret_v2.secrets.data["dbaas_root_password"]}' psql -h ${var.postgresql_host} -U root -c "CREATE DATABASE trading OWNER trading" # Grant privileges - PGPASSWORD='${var.dbaas_postgresql_root_password}' psql -h ${var.postgresql_host} -U root -c "GRANT ALL PRIVILEGES ON DATABASE trading TO trading" + PGPASSWORD='${data.vault_kv_secret_v2.secrets.data["dbaas_root_password"]}' psql -h ${var.postgresql_host} -U root -c "GRANT ALL PRIVILEGES ON DATABASE trading TO trading" # Try to enable timescaledb (allow failure) - PGPASSWORD='${var.dbaas_postgresql_root_password}' psql -h ${var.postgresql_host} -U root -d trading -c "CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE" || true + PGPASSWORD='${data.vault_kv_secret_v2.secrets.data["dbaas_root_password"]}' psql -h ${var.postgresql_host} -U root -d trading -c "CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE" || true echo "Database init complete" EOT ] @@ -144,7 +115,7 @@ resource "kubernetes_job" "migrations" { command = ["python", "-m", "alembic", "upgrade", "head"] env { name = "TRADING_DATABASE_URL" - value = "postgresql+asyncpg://trading:${var.trading_bot_db_password}@${var.postgresql_host}:5432/trading" + value = "postgresql+asyncpg://trading:${data.vault_kv_secret_v2.secrets.data["db_password"]}@${var.postgresql_host}:5432/trading" } env { name = "TRADING_REDIS_URL" diff --git a/stacks/trading-bot/terragrunt.hcl b/stacks/trading-bot/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/trading-bot/terragrunt.hcl +++ b/stacks/trading-bot/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/tuya-bridge/main.tf b/stacks/tuya-bridge/main.tf index 4a8c4114..3d96dbf9 100644 --- a/stacks/tuya-bridge/main.tf +++ b/stacks/tuya-bridge/main.tf @@ -2,20 +2,11 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "tiny_tuya_api_key" { - type = string - sensitive = true -} -variable "tiny_tuya_api_secret" { - type = string - sensitive = true -} -variable "tiny_tuya_service_secret" { - type = string - sensitive = true -} -variable "tiny_tuya_slack_url" { type = string } +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "tuya-bridge" +} resource "kubernetes_namespace" "tuya-bridge" { metadata { @@ -64,19 +55,19 @@ resource "kubernetes_deployment" "tuya-bridge" { } env { name = "TINYTUYA_API_KEY" - value = var.tiny_tuya_api_key + value = data.vault_kv_secret_v2.secrets.data["api_key"] } env { name = "TINYTUYA_API_SECRET" - value = var.tiny_tuya_api_secret + value = data.vault_kv_secret_v2.secrets.data["api_secret"] } env { name = "SERVICE_API_KEY" # used for auth the API endpoint - value = var.tiny_tuya_service_secret + value = data.vault_kv_secret_v2.secrets.data["service_secret"] } env { name = "SLACK_URL" - value = var.tiny_tuya_slack_url + value = data.vault_kv_secret_v2.secrets.data["slack_url"] } resources { requests = { diff --git a/stacks/tuya-bridge/terragrunt.hcl b/stacks/tuya-bridge/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/tuya-bridge/terragrunt.hcl +++ b/stacks/tuya-bridge/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/url/main.tf b/stacks/url/main.tf index c2110a20..90bed7e1 100644 --- a/stacks/url/main.tf +++ b/stacks/url/main.tf @@ -2,17 +2,12 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "url_shortener_geolite_license_key" { type = string } -variable "url_shortener_api_key" { - type = string - sensitive = true -} -variable "url_shortener_mysql_password" { - type = string - sensitive = true -} variable "mysql_host" { type = string } +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "url" +} ## Setup ## Need to manually add @@ -50,7 +45,7 @@ resource "kubernetes_secret" "mysql_config" { } data = { "DB_USER" = "shlink" - "DB_PASSWORD" = var.url_shortener_mysql_password + "DB_PASSWORD" = data.vault_kv_secret_v2.secrets.data["db_password"] } } @@ -120,7 +115,7 @@ resource "kubernetes_deployment" "shlink" { } env { name = "GEOLITE_LICENSE_KEY" - value = var.url_shortener_geolite_license_key + value = data.vault_kv_secret_v2.secrets.data["geolite_license_key"] } # DB config env { @@ -142,7 +137,7 @@ resource "kubernetes_deployment" "shlink" { } # env { # name = "DB_PASSWORD" - # value = var.url_shortener_mysql_password + # value = data.vault_kv_secret_v2.secrets.data["db_password"] # } resources { limits = { @@ -218,7 +213,7 @@ module "ingress" { "gethomepage.dev/pod-selector" = "" "gethomepage.dev/widget.type" = "shlink" "gethomepage.dev/widget.url" = "http://shlink.shlink.svc.cluster.local:8080" - "gethomepage.dev/widget.key" = var.url_shortener_api_key + "gethomepage.dev/widget.key" = data.vault_kv_secret_v2.secrets.data["api_key"] } } @@ -239,7 +234,7 @@ resource "kubernetes_config_map" "shlink-web" { "servers.json" = jsonencode([{ name = "Main" url = "https://url.viktorbarzin.me" - apiKey = var.url_shortener_api_key + apiKey = data.vault_kv_secret_v2.secrets.data["api_key"] }]) } } diff --git a/stacks/url/terragrunt.hcl b/stacks/url/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/url/terragrunt.hcl +++ b/stacks/url/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/vault/main.tf b/stacks/vault/main.tf index d8058c5b..fdfc95cf 100644 --- a/stacks/vault/main.tf +++ b/stacks/vault/main.tf @@ -8,6 +8,10 @@ variable "vault_authentik_client_secret" { type = string sensitive = true } + +variable "nfs_server" { + type = string +} resource "kubernetes_namespace" "vault" { metadata { name = "vault" @@ -30,61 +34,111 @@ resource "helm_release" "vault" { repository = "https://helm.releases.hashicorp.com" chart = "vault" version = "0.29.1" - atomic = true - timeout = 300 + atomic = false # HA pods start sealed — readiness probes fail until unsealed + timeout = 600 values = [yamlencode({ - global = { - enabled = true - } + global = { enabled = true } server = { enabled = true resources = { - requests = { memory = "64Mi", cpu = "50m" } - limits = { memory = "256Mi" } + requests = { memory = "128Mi", cpu = "100m" } + limits = { memory = "512Mi" } } + # Allow scheduling on GPU node (node1) + tolerations = [{ + key = "nvidia.com/gpu" + operator = "Exists" + effect = "NoSchedule" + }] + dataStorage = { enabled = true - size = "1Gi" - storageClass = "nfs-truenas" + size = "2Gi" + storageClass = "nfs-truenas" # NFS — iSCSI CSI driver not available on all nodes } - standalone = { - enabled = true - config = <<-EOT - ui = true - - listener "tcp" { - tls_disable = 1 - address = "[::]:8200" - cluster_address = "[::]:8201" - } - - storage "file" { - path = "/vault/data" - } - EOT + auditStorage = { + enabled = true + size = "2Gi" + storageClass = "nfs-truenas" # NFS fine for append-only audit logs } + standalone = { enabled = false } + ha = { - enabled = false + enabled = true + replicas = 3 + + raft = { + enabled = true + setNodeId = true + config = <<-EOT + ui = true + + listener "tcp" { + tls_disable = 1 + address = "[::]:8200" + cluster_address = "[::]:8201" + } + + storage "raft" { + path = "/vault/data" + retry_join { + leader_api_addr = "http://vault-0.vault-internal:8200" + } + retry_join { + leader_api_addr = "http://vault-1.vault-internal:8200" + } + retry_join { + leader_api_addr = "http://vault-2.vault-internal:8200" + } + } + + service_registration "kubernetes" {} + EOT + } } + + # Mount unseal key secret + extraVolumes = [{ + type = "secret" + name = "vault-unseal-key" + }] + + # Auto-unseal sidecar — polls every 10s, unseals if sealed + extraContainers = [{ + name = "auto-unseal" + image = "hashicorp/vault:1.18.1" + command = ["/bin/sh", "-c"] + args = [join("", [ + "while true; do ", + "sealed=$(VAULT_ADDR=http://127.0.0.1:8200 vault status -format=json 2>/dev/null | grep '\"sealed\"' | grep -o 'true\\|false'); ", + "if [ \"$sealed\" = \"true\" ]; then ", + "echo \"$(date): Vault is sealed, unsealing...\"; ", + "VAULT_ADDR=http://127.0.0.1:8200 vault operator unseal $(cat /vault/unseal-key/unseal-key); ", + "fi; ", + "sleep 10; ", + "done" + ])] + volumeMounts = [{ + name = "userconfig-vault-unseal-key" # Helm chart prefixes extraVolumes with "userconfig-" + mountPath = "/vault/unseal-key" + readOnly = true + }] + resources = { + requests = { cpu = "10m", memory = "32Mi" } + limits = { memory = "64Mi" } + } + }] } - ui = { - enabled = true - } - - injector = { - enabled = false - } - - csi = { - enabled = false - } + ui = { enabled = true } + injector = { enabled = false } + csi = { enabled = false } })] } @@ -155,3 +209,715 @@ module "ingress" { "gethomepage.dev/pod-selector" = "" } } + +# --- Audit Logging --- + +resource "vault_audit" "file" { + type = "file" + options = { + file_path = "/vault/audit/vault-audit.log" + } + depends_on = [helm_release.vault] +} + +# --- Raft Snapshot Backups --- + +module "vault_backup_nfs" { + source = "../../modules/kubernetes/nfs_volume" + name = "vault-backup" + namespace = kubernetes_namespace.vault.metadata[0].name + nfs_server = var.nfs_server + nfs_path = "/mnt/main/vault-backup" + storage = "5Gi" +} + +resource "kubernetes_cron_job_v1" "vault_backup" { + metadata { + name = "vault-raft-backup" + namespace = kubernetes_namespace.vault.metadata[0].name + } + spec { + schedule = "0 2 * * *" + successful_jobs_history_limit = 3 + failed_jobs_history_limit = 3 + concurrency_policy = "Forbid" + job_template { + metadata {} + spec { + template { + metadata {} + spec { + container { + name = "backup" + image = "hashicorp/vault:1.18.1" + command = ["/bin/sh", "-c"] + args = [join("", [ + "export VAULT_ADDR=http://vault-active.vault.svc.cluster.local:8200 && ", + "export VAULT_TOKEN=$(cat /vault/token/vault-root-token) && ", + "TIMESTAMP=$(date +%Y%m%d-%H%M%S) && ", + "vault operator raft snapshot save /backup/vault-raft-$TIMESTAMP.db && ", + "find /backup -name '*.db' -mtime +30 -delete && ", + "echo \"Backup done: vault-raft-$TIMESTAMP.db\" && ls -lh /backup/" + ])] + volume_mount { + mount_path = "/backup" + name = "backup-storage" + } + volume_mount { + mount_path = "/vault/token" + name = "vault-token" + read_only = true + } + } + restart_policy = "OnFailure" + volume { + name = "backup-storage" + persistent_volume_claim { + claim_name = module.vault_backup_nfs.claim_name + } + } + volume { + name = "vault-token" + secret { + secret_name = "vault-root-token" + } + } + } + } + } + } + } +} + +# ============================================================================= +# Vault KV Secret Population +# ============================================================================= +# Reads secrets from SOPS (-var-file) and writes them to Vault KV v2 at +# secret/. Consuming stacks read from Vault instead of SOPS. +# ============================================================================= + +# --- Variable Declarations (secrets consumed by other stacks) --- + +# Simple string secrets +variable "speedtest_db_password" { type = string; sensitive = true } +variable "hackmd_db_password" { type = string; sensitive = true } +variable "n8n_postgresql_password" { type = string; sensitive = true } +variable "tandoor_database_password" { type = string; sensitive = true } +variable "shadowsocks_password" { type = string; sensitive = true } +variable "coturn_turn_secret" { type = string; sensitive = true } +variable "wealthfolio_password_hash" { type = string; sensitive = true } +variable "plotting_book_session_secret" { type = string; sensitive = true } +variable "discord_user_token" { type = string; sensitive = true } +variable "health_postgresql_password" { type = string; sensitive = true } +variable "health_secret_key" { type = string; sensitive = true } +variable "onlyoffice_db_password" { type = string; sensitive = true } +variable "onlyoffice_jwt_token" { type = string; sensitive = true } +variable "netbox_db_password" { type = string; sensitive = true } +variable "netbox_superuser_password" { type = string; sensitive = true } +variable "clickhouse_password" { type = string; sensitive = true } +variable "clickhouse_postgres_password" { type = string; sensitive = true } +variable "diun_nfty_token" { type = string; sensitive = true } +variable "diun_slack_url" { type = string; sensitive = true } +variable "forgejo_authentik_client_id" { type = string; sensitive = true } +variable "forgejo_authentik_client_secret" { type = string; sensitive = true } +variable "dawarich_database_password" { type = string; sensitive = true } +variable "geoapify_api_key" { type = string; sensitive = true } +variable "resume_auth_secret" { type = string; sensitive = true } +variable "url_shortener_api_key" { type = string; sensitive = true } +variable "url_shortener_geolite_license_key" { type = string; sensitive = true } +variable "url_shortener_mysql_password" { type = string; sensitive = true } +variable "linkwarden_authentik_client_id" { type = string; sensitive = true } +variable "linkwarden_authentik_client_secret" { type = string; sensitive = true } +variable "linkwarden_postgresql_password" { type = string; sensitive = true } +variable "tiny_tuya_api_key" { type = string; sensitive = true } +variable "tiny_tuya_api_secret" { type = string; sensitive = true } +variable "tiny_tuya_service_secret" { type = string; sensitive = true } +variable "tiny_tuya_slack_url" { type = string; sensitive = true } +variable "claude_memory_api_key" { type = string; sensitive = true } +variable "dbaas_postgresql_root_password" { type = string; sensitive = true } +variable "openrouter_api_key" { type = string; sensitive = true } +variable "slack_bot_token" { type = string; sensitive = true } +variable "woodpecker_agent_secret" { type = string; sensitive = true } +variable "woodpecker_db_password" { type = string; sensitive = true } +variable "woodpecker_forgejo_client_id" { type = string; sensitive = true } +variable "woodpecker_forgejo_client_secret" { type = string; sensitive = true } +variable "woodpecker_github_client_id" { type = string; sensitive = true } +variable "woodpecker_github_client_secret" { type = string; sensitive = true } +variable "webhook_handler_secret" { type = string; sensitive = true } +variable "webhook_handler_fb_verify_token" { type = string; sensitive = true } +variable "webhook_handler_fb_page_token" { type = string; sensitive = true } +variable "webhook_handler_fb_app_secret" { type = string; sensitive = true } +variable "webhook_handler_git_user" { type = string; sensitive = true } +variable "webhook_handler_git_token" { type = string; sensitive = true } +variable "webhook_handler_ssh_key" { type = string; sensitive = true } +variable "trading_bot_db_password" { type = string; sensitive = true } +variable "trading_bot_alpaca_api_key" { type = string; sensitive = true } +variable "trading_bot_alpaca_secret_key" { type = string; sensitive = true } +variable "trading_bot_jwt_secret" { type = string; sensitive = true } +variable "trading_bot_reddit_client_id" { type = string; sensitive = true } +variable "trading_bot_reddit_client_secret" { type = string; sensitive = true } +variable "trading_bot_alpha_vantage_api_key" { type = string; sensitive = true } +variable "trading_bot_fmp_api_key" { type = string; sensitive = true } +variable "openclaw_ssh_key" { type = string; sensitive = true } +variable "llama_api_key" { type = string; sensitive = true } +variable "brave_api_key" { type = string; sensitive = true } +variable "nvidia_api_key" { type = string; sensitive = true } +variable "anthropic_api_key" { type = string; sensitive = true } +variable "openclaw_telegram_bot_token" { type = string; sensitive = true } +variable "forgejo_api_token" { type = string; sensitive = true } +variable "affine_postgresql_password" { type = string; sensitive = true } +variable "immich_postgresql_password" { type = string; sensitive = true } +variable "immich_frame_api_key" { type = string; sensitive = true } +variable "nextcloud_db_password" { type = string; sensitive = true } +variable "paperless_db_password" { type = string; sensitive = true } +variable "realestate_crawler_db_password" { type = string; sensitive = true } +variable "aiostreams_database_connection_string" { type = string; sensitive = true } + +# Platform-specific secrets +variable "dbaas_root_password" { type = string; sensitive = true } +variable "dbaas_pgadmin_password" { type = string; sensitive = true } +variable "ingress_crowdsec_api_key" { type = string; sensitive = true } +variable "auth_fallback_htpasswd" { type = string; sensitive = true; default = "" } +variable "technitium_db_password" { type = string; sensitive = true } +variable "authentik_secret_key" { type = string; sensitive = true } +variable "authentik_postgres_password" { type = string; sensitive = true } +variable "crowdsec_enroll_key" { type = string; sensitive = true } +variable "crowdsec_db_password" { type = string; sensitive = true } +variable "crowdsec_dash_api_key" { type = string; sensitive = true } +variable "crowdsec_dash_machine_id" { type = string; sensitive = true } +variable "crowdsec_dash_machine_password" { type = string; sensitive = true } +variable "alertmanager_slack_api_url" { type = string; sensitive = true } +variable "cloudflare_api_key" { type = string; sensitive = true } +variable "cloudflare_tunnel_token" { type = string; sensitive = true } +variable "alertmanager_account_password" { type = string; sensitive = true } +variable "monitoring_idrac_password" { type = string; sensitive = true } +variable "haos_api_token" { type = string; sensitive = true } +variable "pve_password" { type = string; sensitive = true } +variable "grafana_db_password" { type = string; sensitive = true } +variable "grafana_admin_password" { type = string; sensitive = true } +variable "vaultwarden_smtp_password" { type = string; sensitive = true } +variable "technitium_username" { type = string; sensitive = true } +variable "technitium_password" { type = string; sensitive = true } +variable "truenas_api_key" { type = string; sensitive = true } +variable "truenas_ssh_private_key" { type = string; sensitive = true } +variable "xray_reality_private_key" { type = string; sensitive = true } +variable "mailserver_roundcubemail_db_password" { type = string; sensitive = true } +variable "headscale_config" { type = string; sensitive = true } +variable "headscale_acl" { type = string; sensitive = true } +variable "wireguard_wg_0_conf" { type = string; sensitive = true } +variable "wireguard_wg_0_key" { type = string; sensitive = true } +variable "wireguard_firewall_sh" { type = string; sensitive = true } + +# Complex type secrets +variable "homepage_credentials" { type = map(any); sensitive = true } +variable "mailserver_accounts" { sensitive = true } +variable "mailserver_aliases" { sensitive = true } +variable "mailserver_opendkim_key" { sensitive = true } +variable "mailserver_sasl_passwd" { sensitive = true } +variable "actualbudget_credentials" { type = map(any); sensitive = true } +variable "freedify_credentials" { type = map(any); sensitive = true } +variable "ollama_api_credentials" { type = map(string); sensitive = true } +variable "owntracks_credentials" { type = map(string); sensitive = true } +variable "realestate_crawler_notification_settings" { type = map(string); sensitive = true } +variable "openclaw_skill_secrets" { type = map(string); sensitive = true } +variable "k8s_users" { type = map(any); sensitive = true; default = {} } +variable "xray_reality_clients" { type = list(map(string)); sensitive = true } +variable "xray_reality_short_ids" { type = list(string); sensitive = true } + +# ============================================================================= +# KV Secret Resources — one per consuming stack +# ============================================================================= + +resource "vault_kv_secret_v2" "speedtest" { + mount = "secret" + name = "speedtest" + data_json = jsonencode({ + db_password = var.speedtest_db_password + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "hackmd" { + mount = "secret" + name = "hackmd" + data_json = jsonencode({ + db_password = var.hackmd_db_password + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "n8n" { + mount = "secret" + name = "n8n" + data_json = jsonencode({ + db_password = var.n8n_postgresql_password + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "tandoor" { + mount = "secret" + name = "tandoor" + data_json = jsonencode({ + db_password = var.tandoor_database_password + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "shadowsocks" { + mount = "secret" + name = "shadowsocks" + data_json = jsonencode({ + password = var.shadowsocks_password + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "coturn" { + mount = "secret" + name = "coturn" + data_json = jsonencode({ + turn_secret = var.coturn_turn_secret + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "wealthfolio" { + mount = "secret" + name = "wealthfolio" + data_json = jsonencode({ + password_hash = var.wealthfolio_password_hash + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "plotting-book" { + mount = "secret" + name = "plotting-book" + data_json = jsonencode({ + session_secret = var.plotting_book_session_secret + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "f1-stream" { + mount = "secret" + name = "f1-stream" + data_json = jsonencode({ + discord_user_token = var.discord_user_token + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "health" { + mount = "secret" + name = "health" + data_json = jsonencode({ + db_password = var.health_postgresql_password + secret_key = var.health_secret_key + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "onlyoffice" { + mount = "secret" + name = "onlyoffice" + data_json = jsonencode({ + db_password = var.onlyoffice_db_password + jwt_token = var.onlyoffice_jwt_token + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "netbox" { + mount = "secret" + name = "netbox" + data_json = jsonencode({ + db_password = var.netbox_db_password + superuser_password = var.netbox_superuser_password + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "rybbit" { + mount = "secret" + name = "rybbit" + data_json = jsonencode({ + clickhouse_password = var.clickhouse_password + postgres_password = var.clickhouse_postgres_password + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "diun" { + mount = "secret" + name = "diun" + data_json = jsonencode({ + nfty_token = var.diun_nfty_token + slack_url = var.diun_slack_url + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "forgejo" { + mount = "secret" + name = "forgejo" + data_json = jsonencode({ + authentik_client_id = var.forgejo_authentik_client_id + authentik_client_secret = var.forgejo_authentik_client_secret + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "dawarich" { + mount = "secret" + name = "dawarich" + data_json = jsonencode({ + db_password = var.dawarich_database_password + geoapify_api_key = var.geoapify_api_key + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "resume" { + mount = "secret" + name = "resume" + data_json = jsonencode({ + auth_secret = var.resume_auth_secret + mailserver_accounts = jsonencode(var.mailserver_accounts) + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "url" { + mount = "secret" + name = "url" + data_json = jsonencode({ + api_key = var.url_shortener_api_key + geolite_license_key = var.url_shortener_geolite_license_key + db_password = var.url_shortener_mysql_password + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "linkwarden" { + mount = "secret" + name = "linkwarden" + data_json = jsonencode({ + authentik_client_id = var.linkwarden_authentik_client_id + authentik_client_secret = var.linkwarden_authentik_client_secret + db_password = var.linkwarden_postgresql_password + homepage_credentials = jsonencode(var.homepage_credentials) + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "tuya-bridge" { + mount = "secret" + name = "tuya-bridge" + data_json = jsonencode({ + api_key = var.tiny_tuya_api_key + api_secret = var.tiny_tuya_api_secret + service_secret = var.tiny_tuya_service_secret + slack_url = var.tiny_tuya_slack_url + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "claude-memory" { + mount = "secret" + name = "claude-memory" + data_json = jsonencode({ + api_key = var.claude_memory_api_key + dbaas_root_password = var.dbaas_postgresql_root_password + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "ytdlp" { + mount = "secret" + name = "ytdlp" + data_json = jsonencode({ + openrouter_api_key = var.openrouter_api_key + slack_bot_token = var.slack_bot_token + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "woodpecker" { + mount = "secret" + name = "woodpecker" + data_json = jsonencode({ + dbaas_root_password = var.dbaas_postgresql_root_password + agent_secret = var.woodpecker_agent_secret + db_password = var.woodpecker_db_password + forgejo_client_id = var.woodpecker_forgejo_client_id + forgejo_client_secret = var.woodpecker_forgejo_client_secret + github_client_id = var.woodpecker_github_client_id + github_client_secret = var.woodpecker_github_client_secret + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "webhook_handler" { + mount = "secret" + name = "webhook-handler" + data_json = jsonencode({ + secret = var.webhook_handler_secret + fb_verify_token = var.webhook_handler_fb_verify_token + fb_page_token = var.webhook_handler_fb_page_token + fb_app_secret = var.webhook_handler_fb_app_secret + git_user = var.webhook_handler_git_user + git_token = var.webhook_handler_git_token + ssh_key = var.webhook_handler_ssh_key + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "trading-bot" { + mount = "secret" + name = "trading-bot" + data_json = jsonencode({ + dbaas_root_password = var.dbaas_postgresql_root_password + db_password = var.trading_bot_db_password + alpaca_api_key = var.trading_bot_alpaca_api_key + alpaca_secret_key = var.trading_bot_alpaca_secret_key + jwt_secret = var.trading_bot_jwt_secret + reddit_client_id = var.trading_bot_reddit_client_id + reddit_client_secret = var.trading_bot_reddit_client_secret + alpha_vantage_api_key = var.trading_bot_alpha_vantage_api_key + fmp_api_key = var.trading_bot_fmp_api_key + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "openclaw" { + mount = "secret" + name = "openclaw" + data_json = jsonencode({ + ssh_key = var.openclaw_ssh_key + skill_secrets = jsonencode(var.openclaw_skill_secrets) + llama_api_key = var.llama_api_key + brave_api_key = var.brave_api_key + openrouter_api_key = var.openrouter_api_key + nvidia_api_key = var.nvidia_api_key + anthropic_api_key = var.anthropic_api_key + telegram_bot_token = var.openclaw_telegram_bot_token + forgejo_api_token = var.forgejo_api_token + claude_memory_api_key = var.claude_memory_api_key + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "affine" { + mount = "secret" + name = "affine" + data_json = jsonencode({ + db_password = var.affine_postgresql_password + mailserver_accounts = jsonencode(var.mailserver_accounts) + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "grampsweb" { + mount = "secret" + name = "grampsweb" + data_json = jsonencode({ + mailserver_accounts = jsonencode(var.mailserver_accounts) + }) + depends_on = [helm_release.vault] +} + +# --- Homepage-only stacks --- + +resource "vault_kv_secret_v2" "audiobookshelf" { + mount = "secret" + name = "audiobookshelf" + data_json = jsonencode({ + homepage_credentials = jsonencode(var.homepage_credentials) + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "calibre" { + mount = "secret" + name = "calibre" + data_json = jsonencode({ + homepage_credentials = jsonencode(var.homepage_credentials) + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "changedetection" { + mount = "secret" + name = "changedetection" + data_json = jsonencode({ + homepage_credentials = jsonencode(var.homepage_credentials) + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "freshrss" { + mount = "secret" + name = "freshrss" + data_json = jsonencode({ + homepage_credentials = jsonencode(var.homepage_credentials) + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "navidrome" { + mount = "secret" + name = "navidrome" + data_json = jsonencode({ + homepage_credentials = jsonencode(var.homepage_credentials) + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "servarr" { + mount = "secret" + name = "servarr" + data_json = jsonencode({ + homepage_credentials = jsonencode(var.homepage_credentials) + aiostreams_database_connection_string = var.aiostreams_database_connection_string + }) + depends_on = [helm_release.vault] +} + +# --- Complex stacks (map secrets) --- + +resource "vault_kv_secret_v2" "actualbudget" { + mount = "secret" + name = "actualbudget" + data_json = jsonencode({ + credentials = jsonencode(var.actualbudget_credentials) + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "freedify" { + mount = "secret" + name = "freedify" + data_json = jsonencode({ + credentials = jsonencode(var.freedify_credentials) + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "ollama" { + mount = "secret" + name = "ollama" + data_json = jsonencode({ + api_credentials = jsonencode(var.ollama_api_credentials) + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "owntracks" { + mount = "secret" + name = "owntracks" + data_json = jsonencode({ + credentials = jsonencode(var.owntracks_credentials) + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "real-estate-crawler" { + mount = "secret" + name = "real-estate-crawler" + data_json = jsonencode({ + db_password = var.realestate_crawler_db_password + notification_settings = jsonencode(var.realestate_crawler_notification_settings) + }) + depends_on = [helm_release.vault] +} + +# --- Stacks with homepage_credentials + other secrets --- + +resource "vault_kv_secret_v2" "immich" { + mount = "secret" + name = "immich" + data_json = jsonencode({ + db_password = var.immich_postgresql_password + frame_api_key = var.immich_frame_api_key + homepage_credentials = jsonencode(var.homepage_credentials) + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "nextcloud" { + mount = "secret" + name = "nextcloud" + data_json = jsonencode({ + db_password = var.nextcloud_db_password + homepage_credentials = jsonencode(var.homepage_credentials) + }) + depends_on = [helm_release.vault] +} + +resource "vault_kv_secret_v2" "paperless-ngx" { + mount = "secret" + name = "paperless-ngx" + data_json = jsonencode({ + db_password = var.paperless_db_password + homepage_credentials = jsonencode(var.homepage_credentials) + }) + depends_on = [helm_release.vault] +} + +# --- Platform stack (largest — all core/cluster secrets) --- + +resource "vault_kv_secret_v2" "platform" { + mount = "secret" + name = "platform" + data_json = jsonencode({ + dbaas_root_password = var.dbaas_root_password + dbaas_postgresql_root_password = var.dbaas_postgresql_root_password + dbaas_pgadmin_password = var.dbaas_pgadmin_password + ingress_crowdsec_api_key = var.ingress_crowdsec_api_key + auth_fallback_htpasswd = var.auth_fallback_htpasswd + technitium_db_password = var.technitium_db_password + homepage_credentials = jsonencode(var.homepage_credentials) + headscale_config = var.headscale_config + headscale_acl = var.headscale_acl + authentik_secret_key = var.authentik_secret_key + authentik_postgres_password = var.authentik_postgres_password + k8s_users = jsonencode(var.k8s_users) + crowdsec_enroll_key = var.crowdsec_enroll_key + crowdsec_db_password = var.crowdsec_db_password + crowdsec_dash_api_key = var.crowdsec_dash_api_key + crowdsec_dash_machine_id = var.crowdsec_dash_machine_id + crowdsec_dash_machine_password = var.crowdsec_dash_machine_password + alertmanager_slack_api_url = var.alertmanager_slack_api_url + cloudflare_api_key = var.cloudflare_api_key + cloudflare_tunnel_token = var.cloudflare_tunnel_token + alertmanager_account_password = var.alertmanager_account_password + monitoring_idrac_password = var.monitoring_idrac_password + tiny_tuya_service_secret = var.tiny_tuya_service_secret + haos_api_token = var.haos_api_token + pve_password = var.pve_password + grafana_db_password = var.grafana_db_password + grafana_admin_password = var.grafana_admin_password + vaultwarden_smtp_password = var.vaultwarden_smtp_password + wireguard_wg_0_conf = var.wireguard_wg_0_conf + wireguard_wg_0_key = var.wireguard_wg_0_key + wireguard_firewall_sh = var.wireguard_firewall_sh + xray_reality_clients = jsonencode(var.xray_reality_clients) + xray_reality_private_key = var.xray_reality_private_key + xray_reality_short_ids = jsonencode(var.xray_reality_short_ids) + mailserver_accounts = jsonencode(var.mailserver_accounts) + mailserver_aliases = jsonencode(var.mailserver_aliases) + mailserver_opendkim_key = jsonencode(var.mailserver_opendkim_key) + mailserver_sasl_passwd = jsonencode(var.mailserver_sasl_passwd) + mailserver_roundcubemail_db_password = var.mailserver_roundcubemail_db_password + webhook_handler_git_user = var.webhook_handler_git_user + webhook_handler_git_token = var.webhook_handler_git_token + technitium_username = var.technitium_username + technitium_password = var.technitium_password + truenas_api_key = var.truenas_api_key + truenas_ssh_private_key = var.truenas_ssh_private_key + }) + depends_on = [helm_release.vault] +} + diff --git a/stacks/vault/vault_provider.tf b/stacks/vault/vault_provider.tf deleted file mode 100644 index 22f031e8..00000000 --- a/stacks/vault/vault_provider.tf +++ /dev/null @@ -1,18 +0,0 @@ -terraform { - required_providers { - vault = { - source = "hashicorp/vault" - version = "~> 4.0" - } - } -} - -variable "vault_root_token" { - type = string - sensitive = true -} - -provider "vault" { - address = "https://vault.viktorbarzin.me" - token = var.vault_root_token -} diff --git a/stacks/wealthfolio/main.tf b/stacks/wealthfolio/main.tf index 72799c42..55c6b141 100644 --- a/stacks/wealthfolio/main.tf +++ b/stacks/wealthfolio/main.tf @@ -2,12 +2,12 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "wealthfolio_password_hash" { - type = string - sensitive = true -} variable "nfs_server" { type = string } +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "wealthfolio" +} # To refresh transactions use finance db positions exporters: # @@ -80,7 +80,7 @@ resource "kubernetes_deployment" "wealthfolio" { } env { name = "WF_AUTH_PASSWORD_HASH" - value = var.wealthfolio_password_hash + value = data.vault_kv_secret_v2.secrets.data["password_hash"] } env { name = "WF_DB_PATH" diff --git a/stacks/wealthfolio/terragrunt.hcl b/stacks/wealthfolio/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/wealthfolio/terragrunt.hcl +++ b/stacks/wealthfolio/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/webhook_handler/main.tf b/stacks/webhook_handler/main.tf index 83ec99ac..8cabc294 100644 --- a/stacks/webhook_handler/main.tf +++ b/stacks/webhook_handler/main.tf @@ -2,30 +2,9 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "webhook_handler_secret" { - type = string - sensitive = true -} -variable "webhook_handler_fb_verify_token" { - type = string - sensitive = true -} -variable "webhook_handler_fb_page_token" { - type = string - sensitive = true -} -variable "webhook_handler_fb_app_secret" { - type = string - sensitive = true -} -variable "webhook_handler_git_user" { type = string } -variable "webhook_handler_git_token" { - type = string - sensitive = true -} -variable "webhook_handler_ssh_key" { - type = string - sensitive = true +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "webhook-handler" } @@ -85,7 +64,7 @@ resource "kubernetes_secret" "ssh-key" { } } data = { - "id_rsa" = var.webhook_handler_ssh_key + "id_rsa" = data.vault_kv_secret_v2.secrets.data["ssh_key"] } type = "generic" } @@ -148,19 +127,19 @@ resource "kubernetes_deployment" "webhook_handler" { } env { name = "WEBHOOKSECRET" - value = var.webhook_handler_secret + value = data.vault_kv_secret_v2.secrets.data["secret"] } env { name = "FB_APP_SECRET" - value = var.webhook_handler_fb_app_secret + value = data.vault_kv_secret_v2.secrets.data["fb_app_secret"] } env { name = "FB_VERIFY_TOKEN" - value = var.webhook_handler_fb_verify_token + value = data.vault_kv_secret_v2.secrets.data["fb_verify_token"] } env { name = "FB_PAGE_TOKEN" - value = var.webhook_handler_fb_page_token + value = data.vault_kv_secret_v2.secrets.data["fb_page_token"] } env { name = "CONFIG" @@ -168,11 +147,11 @@ resource "kubernetes_deployment" "webhook_handler" { } env { name = "GIT_USER" - value = var.webhook_handler_git_user + value = data.vault_kv_secret_v2.secrets.data["git_user"] } env { name = "GIT_TOKEN" - value = var.webhook_handler_git_token + value = data.vault_kv_secret_v2.secrets.data["git_token"] } env { name = "SSH_KEY" diff --git a/stacks/webhook_handler/terragrunt.hcl b/stacks/webhook_handler/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/webhook_handler/terragrunt.hcl +++ b/stacks/webhook_handler/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/woodpecker/main.tf b/stacks/woodpecker/main.tf index 46aa6890..51a51653 100644 --- a/stacks/woodpecker/main.tf +++ b/stacks/woodpecker/main.tf @@ -2,32 +2,15 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "woodpecker_github_client_id" { type = string } -variable "woodpecker_github_client_secret" { - type = string - sensitive = true -} -variable "woodpecker_agent_secret" { - type = string - sensitive = true -} -variable "woodpecker_db_password" { - type = string - sensitive = true -} -variable "dbaas_postgresql_root_password" { - type = string - sensitive = true -} variable "nfs_server" { type = string } variable "postgresql_host" { type = string } -variable "woodpecker_forgejo_client_id" { type = string } -variable "woodpecker_forgejo_client_secret" { - type = string - sensitive = true -} variable "woodpecker_forgejo_url" { type = string } +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "woodpecker" +} + resource "kubernetes_namespace" "woodpecker" { metadata { @@ -89,11 +72,11 @@ resource "kubernetes_job" "db_init" { <<-EOT set -e # Create user if not exists - PGPASSWORD='${var.dbaas_postgresql_root_password}' psql -h ${var.postgresql_host} -U root -tc "SELECT 1 FROM pg_roles WHERE rolname='woodpecker'" | grep -q 1 || \ - PGPASSWORD='${var.dbaas_postgresql_root_password}' psql -h ${var.postgresql_host} -U root -c "CREATE ROLE woodpecker WITH LOGIN PASSWORD '${var.woodpecker_db_password}'" + PGPASSWORD='${data.vault_kv_secret_v2.secrets.data["dbaas_root_password"]}' psql -h ${var.postgresql_host} -U root -tc "SELECT 1 FROM pg_roles WHERE rolname='woodpecker'" | grep -q 1 || \ + PGPASSWORD='${data.vault_kv_secret_v2.secrets.data["dbaas_root_password"]}' psql -h ${var.postgresql_host} -U root -c "CREATE ROLE woodpecker WITH LOGIN PASSWORD '${data.vault_kv_secret_v2.secrets.data["db_password"]}'" # Create database if not exists - PGPASSWORD='${var.dbaas_postgresql_root_password}' psql -h ${var.postgresql_host} -U root -tc "SELECT 1 FROM pg_database WHERE datname='woodpecker'" | grep -q 1 || \ - PGPASSWORD='${var.dbaas_postgresql_root_password}' psql -h ${var.postgresql_host} -U root -c "CREATE DATABASE woodpecker OWNER woodpecker" + PGPASSWORD='${data.vault_kv_secret_v2.secrets.data["dbaas_root_password"]}' psql -h ${var.postgresql_host} -U root -tc "SELECT 1 FROM pg_database WHERE datname='woodpecker'" | grep -q 1 || \ + PGPASSWORD='${data.vault_kv_secret_v2.secrets.data["dbaas_root_password"]}' psql -h ${var.postgresql_host} -U root -c "CREATE DATABASE woodpecker OWNER woodpecker" echo "Database init complete" EOT ] @@ -149,13 +132,13 @@ resource "helm_release" "woodpecker" { values = [ templatefile("${path.module}/values.yaml", { - github_client_id = var.woodpecker_github_client_id - github_client_secret = var.woodpecker_github_client_secret - agent_secret = var.woodpecker_agent_secret - db_password = var.woodpecker_db_password + github_client_id = data.vault_kv_secret_v2.secrets.data["github_client_id"] + github_client_secret = data.vault_kv_secret_v2.secrets.data["github_client_secret"] + agent_secret = data.vault_kv_secret_v2.secrets.data["agent_secret"] + db_password = data.vault_kv_secret_v2.secrets.data["db_password"] postgresql_host = var.postgresql_host - forgejo_client_id = var.woodpecker_forgejo_client_id - forgejo_client_secret = var.woodpecker_forgejo_client_secret + forgejo_client_id = data.vault_kv_secret_v2.secrets.data["forgejo_client_id"] + forgejo_client_secret = data.vault_kv_secret_v2.secrets.data["forgejo_client_secret"] forgejo_url = var.woodpecker_forgejo_url }) ] diff --git a/stacks/woodpecker/terragrunt.hcl b/stacks/woodpecker/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/woodpecker/terragrunt.hcl +++ b/stacks/woodpecker/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/ytdlp/main.tf b/stacks/ytdlp/main.tf index 325c960f..7891048d 100644 --- a/stacks/ytdlp/main.tf +++ b/stacks/ytdlp/main.tf @@ -2,16 +2,13 @@ variable "tls_secret_name" { type = string sensitive = true } -variable "openrouter_api_key" { - type = string - sensitive = true -} -variable "slack_bot_token" { - type = string - sensitive = true -} variable "slack_channel" { type = string } variable "nfs_server" { type = string } + +data "vault_kv_secret_v2" "secrets" { + mount = "secret" + name = "ytdlp" +} variable "redis_host" { type = string } variable "ollama_host" { type = string } @@ -173,7 +170,7 @@ resource "kubernetes_secret" "openrouter" { namespace = kubernetes_namespace.ytdlp.metadata[0].name } data = { - "api-key" = var.openrouter_api_key + "api-key" = data.vault_kv_secret_v2.secrets.data["openrouter_api_key"] } } @@ -183,7 +180,7 @@ resource "kubernetes_secret" "slack" { namespace = kubernetes_namespace.ytdlp.metadata[0].name } data = { - "bot-token" = var.slack_bot_token + "bot-token" = data.vault_kv_secret_v2.secrets.data["slack_bot_token"] "channel" = var.slack_channel } } diff --git a/stacks/ytdlp/terragrunt.hcl b/stacks/ytdlp/terragrunt.hcl index 0d1c8e53..f4c920ab 100644 --- a/stacks/ytdlp/terragrunt.hcl +++ b/stacks/ytdlp/terragrunt.hcl @@ -6,3 +6,8 @@ dependency "platform" { config_path = "../platform" skip_outputs = true } + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/terragrunt.hcl b/terragrunt.hcl index f519539b..b591c981 100644 --- a/terragrunt.hcl +++ b/terragrunt.hcl @@ -48,11 +48,26 @@ generate "k8s_providers" { path = "providers.tf" if_exists = "overwrite_terragrunt" contents = <