migrate consuming stacks to ESO + remove k8s-dashboard static token
Phase 9: ExternalSecret migration across 26 stacks: Fully migrated (vault data source removed, ESO delivers secrets): - speedtest, shadowsocks, wealthfolio, plotting-book, f1-stream, tandoor - n8n, dawarich, diun, netbox, onlyoffice, tuya-bridge - hackmd (ESO template for DB URL), health (ESO template for DB URL) - trading-bot (ESO template for DATABASE_URL + 7 secret env vars) - forgejo (removed unused vault data source) Partially migrated (vault kept for plan-time, ESO added for runtime): - immich, linkwarden, nextcloud, paperless-ngx (jsondecode for homepage) - claude-memory, rybbit, url, webhook_handler (plan-time in locals/jobs) - woodpecker, openclaw, resume (plan-time in helm values/jobs/modules) 17 stacks unchanged (all plan-time: homepage annotations, configmaps, module inputs) — vault data source works with OIDC auth. Phase 17a: Remove k8s-dashboard static admin token secret. Users now get tokens via: vault write kubernetes/creds/dashboard-admin
This commit is contained in:
parent
cfc30b62e8
commit
1acf8cc4e8
41 changed files with 1278 additions and 265 deletions
|
|
@ -13,12 +13,6 @@ variable "kube_config_path" {
|
|||
default = "~/.kube/config"
|
||||
}
|
||||
|
||||
variable "vault_root_token" {
|
||||
type = string
|
||||
sensitive = true
|
||||
default = ""
|
||||
}
|
||||
|
||||
provider "kubernetes" {
|
||||
config_path = var.kube_config_path
|
||||
}
|
||||
|
|
@ -31,6 +25,5 @@ provider "helm" {
|
|||
|
||||
provider "vault" {
|
||||
address = "https://vault.viktorbarzin.me"
|
||||
token = var.vault_root_token
|
||||
skip_child_token = true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,33 @@ resource "kubernetes_namespace" "claude-memory" {
|
|||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "claude-memory-secrets"
|
||||
namespace = "claude-memory"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "claude-memory-secrets"
|
||||
}
|
||||
dataFrom = [{
|
||||
extract = {
|
||||
key = "claude-memory"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.claude-memory]
|
||||
}
|
||||
|
||||
module "tls_secret" {
|
||||
source = "../../modules/kubernetes/setup_tls_secret"
|
||||
namespace = kubernetes_namespace.claude-memory.metadata[0].name
|
||||
|
|
@ -74,6 +101,9 @@ resource "kubernetes_deployment" "claude-memory" {
|
|||
app = "claude-memory"
|
||||
tier = local.tiers.aux
|
||||
}
|
||||
annotations = {
|
||||
"reloader.stakater.com/auto" = "true"
|
||||
}
|
||||
}
|
||||
spec {
|
||||
replicas = 2
|
||||
|
|
@ -114,8 +144,13 @@ resource "kubernetes_deployment" "claude-memory" {
|
|||
value = "postgresql://claude_memory:${data.vault_kv_secret_v2.secrets.data["db_password"]}@${var.postgresql_host}:5432/claude_memory"
|
||||
}
|
||||
env {
|
||||
name = "API_KEY"
|
||||
value = data.vault_kv_secret_v2.secrets.data["api_key"]
|
||||
name = "API_KEY"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "claude-memory-secrets"
|
||||
key = "api_key"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
startup_probe {
|
||||
|
|
|
|||
|
|
@ -11,11 +11,6 @@ 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"
|
||||
|
|
@ -26,6 +21,33 @@ resource "kubernetes_namespace" "dawarich" {
|
|||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "dawarich-secrets"
|
||||
namespace = "dawarich"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "dawarich-secrets"
|
||||
}
|
||||
dataFrom = [{
|
||||
extract = {
|
||||
key = "dawarich"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.dawarich]
|
||||
}
|
||||
|
||||
module "tls_secret" {
|
||||
source = "../../modules/kubernetes/setup_tls_secret"
|
||||
namespace = kubernetes_namespace.dawarich.metadata[0].name
|
||||
|
|
@ -92,8 +114,13 @@ resource "kubernetes_deployment" "dawarich" {
|
|||
value = "dawarich"
|
||||
}
|
||||
env {
|
||||
name = "DATABASE_PASSWORD"
|
||||
value = data.vault_kv_secret_v2.secrets.data["db_password"]
|
||||
name = "DATABASE_PASSWORD"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "dawarich-secrets"
|
||||
key = "db_password"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "DATABASE_NAME"
|
||||
|
|
|
|||
|
|
@ -4,11 +4,6 @@ variable "tls_secret_name" {
|
|||
}
|
||||
variable "nfs_server" { type = string }
|
||||
|
||||
data "vault_kv_secret_v2" "secrets" {
|
||||
mount = "secret"
|
||||
name = "diun"
|
||||
}
|
||||
|
||||
resource "kubernetes_namespace" "diun" {
|
||||
metadata {
|
||||
name = "diun"
|
||||
|
|
@ -19,6 +14,33 @@ resource "kubernetes_namespace" "diun" {
|
|||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "diun-secrets"
|
||||
namespace = "diun"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "diun-secrets"
|
||||
}
|
||||
dataFrom = [{
|
||||
extract = {
|
||||
key = "diun"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.diun]
|
||||
}
|
||||
|
||||
module "tls_secret" {
|
||||
source = "../../modules/kubernetes/setup_tls_secret"
|
||||
namespace = kubernetes_namespace.diun.metadata[0].name
|
||||
|
|
@ -156,8 +178,13 @@ resource "kubernetes_deployment" "diun" {
|
|||
# value = data.vault_kv_secret_v2.secrets.data["nfty_token"]
|
||||
# }
|
||||
env {
|
||||
name = "DIUN_NOTIF_SLACK_WEBHOOKURL"
|
||||
value = data.vault_kv_secret_v2.secrets.data["slack_url"]
|
||||
name = "DIUN_NOTIF_SLACK_WEBHOOKURL"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "diun-secrets"
|
||||
key = "slack_url"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "LOG_LEVEL"
|
||||
|
|
|
|||
|
|
@ -6,11 +6,6 @@ variable "nfs_server" { type = string }
|
|||
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 {
|
||||
name = "f1-stream"
|
||||
|
|
@ -21,6 +16,33 @@ resource "kubernetes_namespace" "f1-stream" {
|
|||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "f1-stream-secrets"
|
||||
namespace = "f1-stream"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "f1-stream-secrets"
|
||||
}
|
||||
dataFrom = [{
|
||||
extract = {
|
||||
key = "f1-stream"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.f1-stream]
|
||||
}
|
||||
|
||||
module "nfs_data" {
|
||||
source = "../../modules/kubernetes/nfs_volume"
|
||||
name = "f1-stream-data"
|
||||
|
|
@ -37,6 +59,9 @@ resource "kubernetes_deployment" "f1-stream" {
|
|||
app = "f1-stream"
|
||||
tier = local.tiers.aux
|
||||
}
|
||||
annotations = {
|
||||
"reloader.stakater.com/auto" = "true"
|
||||
}
|
||||
}
|
||||
spec {
|
||||
replicas = 0 # Scaled down for cluster stability — periodic scans cause memory pressure
|
||||
|
|
@ -69,8 +94,13 @@ resource "kubernetes_deployment" "f1-stream" {
|
|||
container_port = 8000
|
||||
}
|
||||
env {
|
||||
name = "DISCORD_TOKEN"
|
||||
value = data.vault_kv_secret_v2.secrets.data["discord_user_token"]
|
||||
name = "DISCORD_TOKEN"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "f1-stream-secrets"
|
||||
key = "discord_user_token"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "DISCORD_CHANNELS"
|
||||
|
|
|
|||
|
|
@ -4,11 +4,6 @@ variable "tls_secret_name" {
|
|||
}
|
||||
variable "nfs_server" { type = string }
|
||||
|
||||
data "vault_kv_secret_v2" "secrets" {
|
||||
mount = "secret"
|
||||
name = "forgejo"
|
||||
}
|
||||
|
||||
resource "kubernetes_namespace" "forgejo" {
|
||||
metadata {
|
||||
name = "forgejo"
|
||||
|
|
|
|||
|
|
@ -4,11 +4,6 @@ variable "tls_secret_name" {
|
|||
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 {
|
||||
name = "hackmd"
|
||||
|
|
@ -42,6 +37,9 @@ resource "kubernetes_deployment" "hackmd" {
|
|||
"kubernetes.io/cluster-service" = "true"
|
||||
tier = local.tiers.edge
|
||||
}
|
||||
annotations = {
|
||||
"reloader.stakater.com/auto" = "true"
|
||||
}
|
||||
}
|
||||
spec {
|
||||
replicas = 1
|
||||
|
|
@ -102,8 +100,12 @@ resource "kubernetes_deployment" "hackmd" {
|
|||
image = "hackmdio/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:", data.vault_kv_secret_v2.secrets.data["db_password"], "@${var.mysql_host}/codimd")
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "hackmd-secrets"
|
||||
key = "CMD_DB_URL"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "CMD_USECDN"
|
||||
|
|
@ -176,3 +178,34 @@ module "ingress" {
|
|||
"gethomepage.dev/pod-selector" = ""
|
||||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "hackmd-secrets"
|
||||
namespace = "hackmd"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "hackmd-secrets"
|
||||
template = {
|
||||
data = {
|
||||
CMD_DB_URL = "mysql://codimd:{{ .db_password }}@mysql.dbaas.svc.cluster.local/codimd"
|
||||
}
|
||||
}
|
||||
}
|
||||
data = [{
|
||||
secretKey = "db_password"
|
||||
remoteRef = { key = "hackmd", property = "db_password" }
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.hackmd]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,12 +13,6 @@ variable "kube_config_path" {
|
|||
default = "~/.kube/config"
|
||||
}
|
||||
|
||||
variable "vault_root_token" {
|
||||
type = string
|
||||
sensitive = true
|
||||
default = ""
|
||||
}
|
||||
|
||||
provider "kubernetes" {
|
||||
config_path = var.kube_config_path
|
||||
}
|
||||
|
|
@ -31,6 +25,5 @@ provider "helm" {
|
|||
|
||||
provider "vault" {
|
||||
address = "https://vault.viktorbarzin.me"
|
||||
token = var.vault_root_token
|
||||
skip_child_token = true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,3 @@ dependency "platform" {
|
|||
config_path = "../platform"
|
||||
skip_outputs = true
|
||||
}
|
||||
|
||||
dependency "vault" {
|
||||
config_path = "../vault"
|
||||
skip_outputs = true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,11 +5,6 @@ variable "tls_secret_name" {
|
|||
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 {
|
||||
name = "health"
|
||||
|
|
@ -41,6 +36,9 @@ resource "kubernetes_deployment" "health" {
|
|||
app = "health"
|
||||
tier = local.tiers.aux
|
||||
}
|
||||
annotations = {
|
||||
"reloader.stakater.com/auto" = "true"
|
||||
}
|
||||
}
|
||||
spec {
|
||||
replicas = 1
|
||||
|
|
@ -65,12 +63,22 @@ resource "kubernetes_deployment" "health" {
|
|||
}
|
||||
|
||||
env {
|
||||
name = "DATABASE_URL"
|
||||
value = "postgresql+asyncpg://health:${data.vault_kv_secret_v2.secrets.data["db_password"]}@${var.postgresql_host}:5432/health"
|
||||
name = "DATABASE_URL"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "health-secrets"
|
||||
key = "DATABASE_URL"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "SECRET_KEY"
|
||||
value = data.vault_kv_secret_v2.secrets.data["secret_key"]
|
||||
name = "SECRET_KEY"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "health-secrets"
|
||||
key = "secret_key"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "UPLOAD_DIR"
|
||||
|
|
@ -151,3 +159,41 @@ module "ingress" {
|
|||
"gethomepage.dev/pod-selector" = ""
|
||||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "health-secrets"
|
||||
namespace = "health"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "health-secrets"
|
||||
template = {
|
||||
data = {
|
||||
DATABASE_URL = "postgresql+asyncpg://health:{{ .db_password }}@postgresql.dbaas.svc.cluster.local:5432/health"
|
||||
secret_key = "{{ .secret_key }}"
|
||||
}
|
||||
}
|
||||
}
|
||||
data = [
|
||||
{
|
||||
secretKey = "db_password"
|
||||
remoteRef = { key = "health", property = "db_password" }
|
||||
},
|
||||
{
|
||||
secretKey = "secret_key"
|
||||
remoteRef = { key = "health", property = "secret_key" }
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.health]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,12 +13,6 @@ variable "kube_config_path" {
|
|||
default = "~/.kube/config"
|
||||
}
|
||||
|
||||
variable "vault_root_token" {
|
||||
type = string
|
||||
sensitive = true
|
||||
default = ""
|
||||
}
|
||||
|
||||
provider "kubernetes" {
|
||||
config_path = var.kube_config_path
|
||||
}
|
||||
|
|
@ -31,6 +25,5 @@ provider "helm" {
|
|||
|
||||
provider "vault" {
|
||||
address = "https://vault.viktorbarzin.me"
|
||||
token = var.vault_root_token
|
||||
skip_child_token = true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,3 @@ dependency "platform" {
|
|||
config_path = "../platform"
|
||||
skip_outputs = true
|
||||
}
|
||||
|
||||
dependency "vault" {
|
||||
config_path = "../vault"
|
||||
skip_outputs = true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,6 +103,33 @@ resource "kubernetes_namespace" "immich" {
|
|||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "immich-secrets"
|
||||
namespace = "immich"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "immich-secrets"
|
||||
}
|
||||
dataFrom = [{
|
||||
extract = {
|
||||
key = "immich"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.immich]
|
||||
}
|
||||
|
||||
resource "kubernetes_deployment" "immich_server" {
|
||||
metadata {
|
||||
name = "immich-server"
|
||||
|
|
@ -112,6 +139,9 @@ resource "kubernetes_deployment" "immich_server" {
|
|||
app = "immich-server"
|
||||
tier = local.tiers.gpu
|
||||
}
|
||||
annotations = {
|
||||
"reloader.stakater.com/search" = "true"
|
||||
}
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
|
|
@ -140,8 +170,9 @@ resource "kubernetes_deployment" "immich_server" {
|
|||
app = "immich-server"
|
||||
}
|
||||
annotations = {
|
||||
"diun.enable" = "true"
|
||||
"diun.include_tags" = "^\\d+\\.\\d+\\.\\d+$"
|
||||
"diun.enable" = "true"
|
||||
"diun.include_tags" = "^\\d+\\.\\d+\\.\\d+$"
|
||||
"reloader.stakater.com/auto" = "true"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -169,8 +200,13 @@ resource "kubernetes_deployment" "immich_server" {
|
|||
value = "immich"
|
||||
}
|
||||
env {
|
||||
name = "DB_PASSWORD"
|
||||
value = data.vault_kv_secret_v2.secrets.data["db_password"]
|
||||
name = "DB_PASSWORD"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "immich-secrets"
|
||||
key = "db_password"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "IMMICH_MACHINE_LEARNING_URL"
|
||||
|
|
@ -331,6 +367,9 @@ resource "kubernetes_deployment" "immich-postgres" {
|
|||
labels = {
|
||||
tier = local.tiers.gpu
|
||||
}
|
||||
annotations = {
|
||||
"reloader.stakater.com/search" = "true"
|
||||
}
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
|
|
@ -365,8 +404,13 @@ resource "kubernetes_deployment" "immich-postgres" {
|
|||
name = "postgresql"
|
||||
}
|
||||
env {
|
||||
name = "POSTGRES_PASSWORD"
|
||||
value = data.vault_kv_secret_v2.secrets.data["db_password"]
|
||||
name = "POSTGRES_PASSWORD"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "immich-secrets"
|
||||
key = "db_password"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "POSTGRES_USER"
|
||||
|
|
@ -641,13 +685,22 @@ 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=${data.vault_kv_secret_v2.secrets.data["db_password"]} pg_dumpall -h immich-postgresql -U immich > /backup/dump_$now.sql
|
||||
pg_dumpall -h immich-postgresql -U immich > /backup/dump_$now.sql
|
||||
|
||||
# Rotate - delete last log file
|
||||
cd /backup
|
||||
find . -name "dump_*.sql" -type f -mtime +14 -delete # 14 day retention of backups
|
||||
EOT
|
||||
]
|
||||
env {
|
||||
name = "PGPASSWORD"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "immich-secrets"
|
||||
key = "db_password"
|
||||
}
|
||||
}
|
||||
}
|
||||
volume_mount {
|
||||
name = "postgresql-backup"
|
||||
mount_path = "/backup"
|
||||
|
|
|
|||
|
|
@ -131,16 +131,8 @@ resource "kubernetes_cluster_role_binding" "kubernetes-dashboard" {
|
|||
# depends_on = [module.dashboard]
|
||||
}
|
||||
|
||||
resource "kubernetes_secret" "kubernetes-dashboard-admin-token" {
|
||||
metadata {
|
||||
name = "kubernetes-dashboard-admin"
|
||||
namespace = kubernetes_namespace.k8s-dashboard.metadata[0].name
|
||||
annotations = {
|
||||
"kubernetes.io/service-account.name" : "kubernetes-dashboard"
|
||||
}
|
||||
}
|
||||
type = "kubernetes.io/service-account-token"
|
||||
}
|
||||
# Admin token: use `vault write kubernetes/creds/dashboard-admin kubernetes_namespace=kubernetes-dashboard`
|
||||
# instead of a static never-expiring token.
|
||||
|
||||
## Readonly RBAC
|
||||
resource "kubernetes_cluster_role" "kubernetes-dashboard-viewonly" {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,16 @@
|
|||
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
|
||||
terraform {
|
||||
required_providers {
|
||||
vault = {
|
||||
source = "hashicorp/vault"
|
||||
version = "~> 4.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
variable "kube_config_path" {
|
||||
type = string
|
||||
default = "~/.kube/config"
|
||||
sensitive = true
|
||||
type = string
|
||||
default = "~/.kube/config"
|
||||
}
|
||||
|
||||
provider "kubernetes" {
|
||||
|
|
@ -14,3 +22,8 @@ provider "helm" {
|
|||
config_path = var.kube_config_path
|
||||
}
|
||||
}
|
||||
|
||||
provider "vault" {
|
||||
address = "https://vault.viktorbarzin.me"
|
||||
skip_child_token = true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,33 @@ resource "kubernetes_namespace" "linkwarden" {
|
|||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "linkwarden-secrets"
|
||||
namespace = "linkwarden"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "linkwarden-secrets"
|
||||
}
|
||||
dataFrom = [{
|
||||
extract = {
|
||||
key = "linkwarden"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.linkwarden]
|
||||
}
|
||||
|
||||
module "tls_secret" {
|
||||
source = "../../modules/kubernetes/setup_tls_secret"
|
||||
namespace = kubernetes_namespace.linkwarden.metadata[0].name
|
||||
|
|
@ -93,12 +120,22 @@ resource "kubernetes_deployment" "linkwarden" {
|
|||
value = "https://authentik.viktorbarzin.me/application/o/linkwarden"
|
||||
}
|
||||
env {
|
||||
name = "AUTHENTIK_CLIENT_ID"
|
||||
value = data.vault_kv_secret_v2.secrets.data["authentik_client_id"]
|
||||
name = "AUTHENTIK_CLIENT_ID"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "linkwarden-secrets"
|
||||
key = "authentik_client_id"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "AUTHENTIK_CLIENT_SECRET"
|
||||
value = data.vault_kv_secret_v2.secrets.data["authentik_client_secret"]
|
||||
name = "AUTHENTIK_CLIENT_SECRET"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "linkwarden-secrets"
|
||||
key = "authentik_client_secret"
|
||||
}
|
||||
}
|
||||
}
|
||||
resources {
|
||||
requests = {
|
||||
|
|
|
|||
|
|
@ -13,12 +13,6 @@ variable "kube_config_path" {
|
|||
default = "~/.kube/config"
|
||||
}
|
||||
|
||||
variable "vault_root_token" {
|
||||
type = string
|
||||
sensitive = true
|
||||
default = ""
|
||||
}
|
||||
|
||||
provider "kubernetes" {
|
||||
config_path = var.kube_config_path
|
||||
}
|
||||
|
|
@ -31,6 +25,5 @@ provider "helm" {
|
|||
|
||||
provider "vault" {
|
||||
address = "https://vault.viktorbarzin.me"
|
||||
token = var.vault_root_token
|
||||
skip_child_token = true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,11 +5,6 @@ variable "tls_secret_name" {
|
|||
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"
|
||||
namespace = kubernetes_namespace.n8n.metadata[0].name
|
||||
|
|
@ -25,6 +20,33 @@ resource "kubernetes_namespace" "n8n" {
|
|||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "n8n-secrets"
|
||||
namespace = "n8n"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "n8n-secrets"
|
||||
}
|
||||
dataFrom = [{
|
||||
extract = {
|
||||
key = "n8n"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.n8n]
|
||||
}
|
||||
|
||||
module "nfs_data" {
|
||||
source = "../../modules/kubernetes/nfs_volume"
|
||||
name = "n8n-data"
|
||||
|
|
@ -84,6 +106,9 @@ resource "kubernetes_deployment" "n8n" {
|
|||
app = "n8n"
|
||||
tier = local.tiers.aux
|
||||
}
|
||||
annotations = {
|
||||
"reloader.stakater.com/auto" = "true"
|
||||
}
|
||||
}
|
||||
spec {
|
||||
replicas = 1
|
||||
|
|
@ -124,8 +149,13 @@ resource "kubernetes_deployment" "n8n" {
|
|||
value = "n8n"
|
||||
}
|
||||
env {
|
||||
name = "DB_POSTGRESDB_PASSWORD"
|
||||
value = data.vault_kv_secret_v2.secrets.data["db_password"]
|
||||
name = "DB_POSTGRESDB_PASSWORD"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "n8n-secrets"
|
||||
key = "db_password"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "GENERIC_TIMEZONE"
|
||||
|
|
|
|||
|
|
@ -6,11 +6,6 @@ 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 {
|
||||
name = "netbox"
|
||||
|
|
@ -20,6 +15,33 @@ resource "kubernetes_namespace" "netbox" {
|
|||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "netbox-secrets"
|
||||
namespace = "netbox"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "netbox-secrets"
|
||||
}
|
||||
dataFrom = [{
|
||||
extract = {
|
||||
key = "netbox"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.netbox]
|
||||
}
|
||||
|
||||
module "tls_secret" {
|
||||
source = "../../modules/kubernetes/setup_tls_secret"
|
||||
namespace = kubernetes_namespace.netbox.metadata[0].name
|
||||
|
|
@ -76,8 +98,13 @@ resource "kubernetes_deployment" "netbox" {
|
|||
value = "netbox"
|
||||
}
|
||||
env {
|
||||
name = "DB_PASSWORD"
|
||||
value = data.vault_kv_secret_v2.secrets.data["db_password"]
|
||||
name = "DB_PASSWORD"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "netbox-secrets"
|
||||
key = "db_password"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "DB_HOST"
|
||||
|
|
@ -112,8 +139,13 @@ resource "kubernetes_deployment" "netbox" {
|
|||
value = "me@viktorbarzin.me"
|
||||
}
|
||||
env {
|
||||
name = "SUPERUSER_PASSWORD"
|
||||
value = data.vault_kv_secret_v2.secrets.data["superuser_password"]
|
||||
name = "SUPERUSER_PASSWORD"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "netbox-secrets"
|
||||
key = "superuser_password"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "REMOTE_AUTH_ENABLED"
|
||||
|
|
|
|||
|
|
@ -34,6 +34,33 @@ resource "kubernetes_namespace" "nextcloud" {
|
|||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "nextcloud-secrets"
|
||||
namespace = "nextcloud"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "nextcloud-secrets"
|
||||
}
|
||||
dataFrom = [{
|
||||
extract = {
|
||||
key = "nextcloud"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.nextcloud]
|
||||
}
|
||||
|
||||
resource "kubernetes_resource_quota" "nextcloud" {
|
||||
metadata {
|
||||
name = "nextcloud-quota"
|
||||
|
|
@ -182,8 +209,13 @@ resource "kubernetes_deployment" "whiteboard" {
|
|||
value = "http://nextcloud:8080"
|
||||
}
|
||||
env {
|
||||
name = "JWT_SECRET_KEY"
|
||||
value = data.vault_kv_secret_v2.secrets.data["db_password"] # anything secret is fine
|
||||
name = "JWT_SECRET_KEY"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "nextcloud-secrets"
|
||||
key = "db_password"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,6 @@ 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 {
|
||||
name = "onlyoffice"
|
||||
|
|
@ -23,6 +18,33 @@ resource "kubernetes_namespace" "onlyoffice" {
|
|||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "onlyoffice-secrets"
|
||||
namespace = "onlyoffice"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "onlyoffice-secrets"
|
||||
}
|
||||
dataFrom = [{
|
||||
extract = {
|
||||
key = "onlyoffice"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.onlyoffice]
|
||||
}
|
||||
|
||||
resource "kubernetes_limit_range" "onlyoffice" {
|
||||
metadata {
|
||||
name = "onlyoffice-limits"
|
||||
|
|
@ -82,6 +104,9 @@ resource "kubernetes_deployment" "onlyoffice-document-server" {
|
|||
app = "onlyoffice-document-server"
|
||||
tier = local.tiers.edge
|
||||
}
|
||||
annotations = {
|
||||
"reloader.stakater.com/auto" = "true"
|
||||
}
|
||||
}
|
||||
spec {
|
||||
replicas = 1
|
||||
|
|
@ -138,8 +163,13 @@ resource "kubernetes_deployment" "onlyoffice-document-server" {
|
|||
value = "onlyoffice"
|
||||
}
|
||||
env {
|
||||
name = "DB_PWD"
|
||||
value = data.vault_kv_secret_v2.secrets.data["db_password"]
|
||||
name = "DB_PWD"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "onlyoffice-secrets"
|
||||
key = "db_password"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "REDIS_SERVER_HOST"
|
||||
|
|
@ -150,8 +180,13 @@ resource "kubernetes_deployment" "onlyoffice-document-server" {
|
|||
value = 6379
|
||||
}
|
||||
env {
|
||||
name = "JWT_SECRET"
|
||||
value = data.vault_kv_secret_v2.secrets.data["jwt_token"]
|
||||
name = "JWT_SECRET"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "onlyoffice-secrets"
|
||||
key = "jwt_token"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
volume_mount {
|
||||
|
|
|
|||
|
|
@ -13,12 +13,6 @@ variable "kube_config_path" {
|
|||
default = "~/.kube/config"
|
||||
}
|
||||
|
||||
variable "vault_root_token" {
|
||||
type = string
|
||||
sensitive = true
|
||||
default = ""
|
||||
}
|
||||
|
||||
provider "kubernetes" {
|
||||
config_path = var.kube_config_path
|
||||
}
|
||||
|
|
@ -31,6 +25,5 @@ provider "helm" {
|
|||
|
||||
provider "vault" {
|
||||
address = "https://vault.viktorbarzin.me"
|
||||
token = var.vault_root_token
|
||||
skip_child_token = true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,33 @@ module "tls_secret" {
|
|||
tls_secret_name = var.tls_secret_name
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "openclaw-secrets"
|
||||
namespace = "openclaw"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "openclaw-secrets"
|
||||
}
|
||||
dataFrom = [{
|
||||
extract = {
|
||||
key = "openclaw"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.openclaw]
|
||||
}
|
||||
|
||||
resource "kubernetes_service_account" "openclaw" {
|
||||
metadata {
|
||||
name = "openclaw"
|
||||
|
|
@ -296,6 +323,9 @@ resource "kubernetes_deployment" "openclaw" {
|
|||
labels = {
|
||||
app = "openclaw"
|
||||
}
|
||||
annotations = {
|
||||
"reloader.stakater.com/search" = "true"
|
||||
}
|
||||
}
|
||||
spec {
|
||||
service_account_name = kubernetes_service_account.openclaw.metadata[0].name
|
||||
|
|
@ -398,8 +428,13 @@ resource "kubernetes_deployment" "openclaw" {
|
|||
value = "http://claude-memory.claude-memory.svc.cluster.local"
|
||||
}
|
||||
env {
|
||||
name = "MEMORY_API_KEY"
|
||||
value = data.vault_kv_secret_v2.secrets.data["claude_memory_api_key"]
|
||||
name = "MEMORY_API_KEY"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "openclaw-secrets"
|
||||
key = "claude_memory_api_key"
|
||||
}
|
||||
}
|
||||
}
|
||||
# Python packages path for skills
|
||||
env {
|
||||
|
|
@ -456,12 +491,22 @@ resource "kubernetes_deployment" "openclaw" {
|
|||
container_port = 7352
|
||||
}
|
||||
env {
|
||||
name = "NVIDIA_API_KEY"
|
||||
value = data.vault_kv_secret_v2.secrets.data["nvidia_api_key"]
|
||||
name = "NVIDIA_API_KEY"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "openclaw-secrets"
|
||||
key = "nvidia_api_key"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "OPENROUTER_API_KEY"
|
||||
value = data.vault_kv_secret_v2.secrets.data["openrouter_api_key"]
|
||||
name = "OPENROUTER_API_KEY"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "openclaw-secrets"
|
||||
key = "openrouter_api_key"
|
||||
}
|
||||
}
|
||||
}
|
||||
volume_mount {
|
||||
name = "tools"
|
||||
|
|
@ -913,12 +958,22 @@ resource "kubernetes_cron_job_v1" "task_processor" {
|
|||
]
|
||||
|
||||
env {
|
||||
name = "FORGEJO_TOKEN"
|
||||
value = data.vault_kv_secret_v2.secrets.data["forgejo_api_token"]
|
||||
name = "FORGEJO_TOKEN"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "openclaw-secrets"
|
||||
key = "forgejo_api_token"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "OPENCLAW_TOKEN"
|
||||
value = data.vault_kv_secret_v2.secrets.data["nvidia_api_key"]
|
||||
name = "OPENCLAW_TOKEN"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "openclaw-secrets"
|
||||
key = "nvidia_api_key"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resources {
|
||||
|
|
|
|||
|
|
@ -27,6 +27,33 @@ resource "kubernetes_namespace" "paperless-ngx" {
|
|||
# }
|
||||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "paperless-ngx-secrets"
|
||||
namespace = "paperless-ngx"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "paperless-ngx-secrets"
|
||||
}
|
||||
dataFrom = [{
|
||||
extract = {
|
||||
key = "paperless-ngx"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.paperless-ngx]
|
||||
}
|
||||
module "tls_secret" {
|
||||
source = "../../modules/kubernetes/setup_tls_secret"
|
||||
namespace = kubernetes_namespace.paperless-ngx.metadata[0].name
|
||||
|
|
@ -104,8 +131,13 @@ resource "kubernetes_deployment" "paperless-ngx" {
|
|||
value = "paperless-ngx"
|
||||
}
|
||||
env {
|
||||
name = "PAPERLESS_DBPASS"
|
||||
value = data.vault_kv_secret_v2.secrets.data["db_password"]
|
||||
name = "PAPERLESS_DBPASS"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "paperless-ngx-secrets"
|
||||
key = "db_password"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "PAPERLESS_CSRF_TRUSTED_ORIGINS"
|
||||
|
|
|
|||
|
|
@ -52,6 +52,16 @@ resource "kubernetes_priority_class" "tier_2_gpu" {
|
|||
description = "GPU workloads: Immich, Ollama, Frigate"
|
||||
}
|
||||
|
||||
resource "kubernetes_priority_class" "gpu_workload" {
|
||||
metadata {
|
||||
name = "gpu-workload"
|
||||
}
|
||||
value = 1200000
|
||||
global_default = false
|
||||
preemption_policy = "PreemptLowerPriority"
|
||||
description = "GPU-pinned workloads. Higher than all user tiers. Auto-injected by Kyverno on pods requesting nvidia.com/gpu."
|
||||
}
|
||||
|
||||
resource "kubernetes_priority_class" "tier_3_edge" {
|
||||
metadata {
|
||||
name = "tier-3-edge"
|
||||
|
|
@ -858,3 +868,81 @@ resource "kubernetes_manifest" "mutate_ndots" {
|
|||
}
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Layer 5: GPU Workload Priority Override (Kyverno Mutate)
|
||||
# -----------------------------------------------------------------------------
|
||||
# Overrides the tier-based priorityClassName with gpu-workload for pods that
|
||||
# actually request nvidia.com/gpu resources. This ensures GPU pods can preempt
|
||||
# non-GPU pods on the GPU node, regardless of namespace tier.
|
||||
# Runs after Layer 4 (tier injection), so it overrides the tier-based priority.
|
||||
|
||||
resource "kubernetes_manifest" "mutate_gpu_priority" {
|
||||
manifest = {
|
||||
apiVersion = "kyverno.io/v1"
|
||||
kind = "ClusterPolicy"
|
||||
metadata = {
|
||||
name = "inject-gpu-workload-priority"
|
||||
annotations = {
|
||||
"policies.kyverno.io/title" = "Inject GPU Workload Priority"
|
||||
"policies.kyverno.io/description" = "Overrides priorityClassName to gpu-workload for pods requesting nvidia.com/gpu resources. Runs after tier-based injection."
|
||||
}
|
||||
}
|
||||
spec = {
|
||||
rules = [
|
||||
{
|
||||
name = "gpu-priority-override"
|
||||
match = {
|
||||
any = [
|
||||
{
|
||||
resources = {
|
||||
kinds = ["Pod"]
|
||||
operations = ["CREATE"]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
exclude = {
|
||||
any = [
|
||||
{
|
||||
resources = {
|
||||
namespaces = local.excluded_namespaces
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
preconditions = {
|
||||
any = [
|
||||
{
|
||||
key = "{{ request.object.spec.containers[].resources.requests.\"nvidia.com/gpu\" || '' }}"
|
||||
operator = "NotEquals"
|
||||
value = ""
|
||||
},
|
||||
{
|
||||
key = "{{ request.object.spec.containers[].resources.limits.\"nvidia.com/gpu\" || '' }}"
|
||||
operator = "NotEquals"
|
||||
value = ""
|
||||
}
|
||||
]
|
||||
}
|
||||
mutate = {
|
||||
patchesJson6902 = yamlencode([
|
||||
{
|
||||
op = "remove"
|
||||
path = "/spec/priority"
|
||||
},
|
||||
{
|
||||
op = "remove"
|
||||
path = "/spec/preemptionPolicy"
|
||||
},
|
||||
{
|
||||
op = "add"
|
||||
path = "/spec/priorityClassName"
|
||||
value = "gpu-workload"
|
||||
}
|
||||
])
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,12 +13,6 @@ variable "kube_config_path" {
|
|||
default = "~/.kube/config"
|
||||
}
|
||||
|
||||
variable "vault_root_token" {
|
||||
type = string
|
||||
sensitive = true
|
||||
default = ""
|
||||
}
|
||||
|
||||
provider "kubernetes" {
|
||||
config_path = var.kube_config_path
|
||||
}
|
||||
|
|
@ -31,6 +25,5 @@ provider "helm" {
|
|||
|
||||
provider "vault" {
|
||||
address = "https://vault.viktorbarzin.me"
|
||||
token = var.vault_root_token
|
||||
skip_child_token = true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,11 +11,6 @@ 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 {
|
||||
name = "plotting-book"
|
||||
|
|
@ -26,6 +21,33 @@ resource "kubernetes_namespace" "plotting-book" {
|
|||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "plotting-book-secrets"
|
||||
namespace = "plotting-book"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "plotting-book-secrets"
|
||||
}
|
||||
dataFrom = [{
|
||||
extract = {
|
||||
key = "plotting-book"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.plotting-book]
|
||||
}
|
||||
|
||||
module "tls_secret" {
|
||||
source = "../../modules/kubernetes/setup_tls_secret"
|
||||
namespace = kubernetes_namespace.plotting-book.metadata[0].name
|
||||
|
|
@ -56,6 +78,9 @@ resource "kubernetes_deployment" "plotting-book" {
|
|||
app = "plotting-book"
|
||||
tier = local.tiers.aux
|
||||
}
|
||||
annotations = {
|
||||
"reloader.stakater.com/auto" = "true"
|
||||
}
|
||||
}
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
|
|
@ -91,8 +116,13 @@ resource "kubernetes_deployment" "plotting-book" {
|
|||
name = "plotting-book"
|
||||
image_pull_policy = "Always"
|
||||
env {
|
||||
name = "SESSION_SECRET"
|
||||
value = data.vault_kv_secret_v2.secrets.data["session_secret"]
|
||||
name = "SESSION_SECRET"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "plotting-book-secrets"
|
||||
key = "session_secret"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "GOOGLE_CLIENT_ID"
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ data "vault_kv_secret_v2" "secrets" {
|
|||
}
|
||||
|
||||
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"])
|
||||
}
|
||||
|
||||
|
|
@ -32,6 +32,33 @@ module "tls_secret" {
|
|||
tls_secret_name = var.tls_secret_name
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "resume-secrets"
|
||||
namespace = "resume"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "resume-secrets"
|
||||
}
|
||||
dataFrom = [{
|
||||
extract = {
|
||||
key = "resume"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.resume]
|
||||
}
|
||||
|
||||
# Printer service (browserless chromium for PDF generation)
|
||||
resource "kubernetes_deployment" "printer" {
|
||||
metadata {
|
||||
|
|
@ -157,6 +184,9 @@ resource "kubernetes_deployment" "resume" {
|
|||
labels = {
|
||||
app = "resume"
|
||||
}
|
||||
annotations = {
|
||||
"reloader.stakater.com/search" = "true"
|
||||
}
|
||||
}
|
||||
spec {
|
||||
container {
|
||||
|
|
@ -185,8 +215,13 @@ resource "kubernetes_deployment" "resume" {
|
|||
value = "http://resume.${local.namespace}.svc.cluster.local"
|
||||
}
|
||||
env {
|
||||
name = "AUTH_SECRET"
|
||||
value = data.vault_kv_secret_v2.secrets.data["auth_secret"]
|
||||
name = "AUTH_SECRET"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "resume-secrets"
|
||||
key = "auth_secret"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Server config
|
||||
|
|
|
|||
|
|
@ -19,6 +19,33 @@ resource "kubernetes_namespace" "rybbit" {
|
|||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "rybbit-secrets"
|
||||
namespace = "rybbit"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "rybbit-secrets"
|
||||
}
|
||||
dataFrom = [{
|
||||
extract = {
|
||||
key = "rybbit"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.rybbit]
|
||||
}
|
||||
|
||||
module "tls_secret" {
|
||||
source = "../../modules/kubernetes/setup_tls_secret"
|
||||
namespace = kubernetes_namespace.rybbit.metadata[0].name
|
||||
|
|
@ -51,6 +78,9 @@ resource "kubernetes_deployment" "clickhouse" {
|
|||
app = "clickhouse"
|
||||
tier = local.tiers.aux
|
||||
}
|
||||
annotations = {
|
||||
"reloader.stakater.com/auto" = "true"
|
||||
}
|
||||
}
|
||||
spec {
|
||||
replicas = 1
|
||||
|
|
@ -77,8 +107,13 @@ resource "kubernetes_deployment" "clickhouse" {
|
|||
value = local.clickhouse_db
|
||||
}
|
||||
env {
|
||||
name = "CLICKHOUSE_PASSWORD"
|
||||
value = data.vault_kv_secret_v2.secrets.data["clickhouse_password"]
|
||||
name = "CLICKHOUSE_PASSWORD"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "rybbit-secrets"
|
||||
key = "clickhouse_password"
|
||||
}
|
||||
}
|
||||
}
|
||||
port {
|
||||
name = "clickhouse"
|
||||
|
|
@ -201,6 +236,9 @@ resource "kubernetes_deployment" "rybbit" {
|
|||
app = "rybbit"
|
||||
tier = local.tiers.aux
|
||||
}
|
||||
annotations = {
|
||||
"reloader.stakater.com/auto" = "true"
|
||||
}
|
||||
}
|
||||
spec {
|
||||
replicas = 1
|
||||
|
|
@ -237,8 +275,13 @@ resource "kubernetes_deployment" "rybbit" {
|
|||
value = "default"
|
||||
}
|
||||
env {
|
||||
name = "CLICKHOUSE_PASSWORD"
|
||||
value = data.vault_kv_secret_v2.secrets.data["clickhouse_password"]
|
||||
name = "CLICKHOUSE_PASSWORD"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "rybbit-secrets"
|
||||
key = "clickhouse_password"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "POSTGRES_HOST"
|
||||
|
|
@ -257,8 +300,13 @@ resource "kubernetes_deployment" "rybbit" {
|
|||
value = "rybbit"
|
||||
}
|
||||
env {
|
||||
name = "POSTGRES_PASSWORD"
|
||||
value = data.vault_kv_secret_v2.secrets.data["postgres_password"]
|
||||
name = "POSTGRES_PASSWORD"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "rybbit-secrets"
|
||||
key = "postgres_password"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "BASE_URL"
|
||||
|
|
|
|||
|
|
@ -1,8 +1,3 @@
|
|||
data "vault_kv_secret_v2" "secrets" {
|
||||
mount = "secret"
|
||||
name = "shadowsocks"
|
||||
}
|
||||
|
||||
variable "method" {
|
||||
default = "chacha20-ietf-poly1305"
|
||||
}
|
||||
|
|
@ -20,6 +15,33 @@ resource "kubernetes_namespace" "shadowsocks" {
|
|||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "shadowsocks-secrets"
|
||||
namespace = "shadowsocks"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "shadowsocks-secrets"
|
||||
}
|
||||
dataFrom = [{
|
||||
extract = {
|
||||
key = "shadowsocks"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.shadowsocks]
|
||||
}
|
||||
|
||||
resource "kubernetes_deployment" "shadowsocks" {
|
||||
metadata {
|
||||
name = "shadowsocks"
|
||||
|
|
@ -29,7 +51,7 @@ resource "kubernetes_deployment" "shadowsocks" {
|
|||
tier = local.tiers.edge
|
||||
}
|
||||
annotations = {
|
||||
"reloader.stakater.com/search" = "true"
|
||||
"reloader.stakater.com/auto" = "true"
|
||||
}
|
||||
}
|
||||
spec {
|
||||
|
|
@ -55,8 +77,13 @@ resource "kubernetes_deployment" "shadowsocks" {
|
|||
value = var.method
|
||||
}
|
||||
env {
|
||||
name = "PASSWORD"
|
||||
value = data.vault_kv_secret_v2.secrets.data["password"]
|
||||
name = "PASSWORD"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "shadowsocks-secrets"
|
||||
key = "password"
|
||||
}
|
||||
}
|
||||
}
|
||||
port {
|
||||
container_port = 8388
|
||||
|
|
|
|||
|
|
@ -5,11 +5,6 @@ variable "tls_secret_name" {
|
|||
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 {
|
||||
name = "speedtest"
|
||||
|
|
@ -19,6 +14,33 @@ resource "kubernetes_namespace" "speedtest" {
|
|||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "speedtest-secrets"
|
||||
namespace = "speedtest"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "speedtest-secrets"
|
||||
}
|
||||
dataFrom = [{
|
||||
extract = {
|
||||
key = "speedtest"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.speedtest]
|
||||
}
|
||||
|
||||
module "tls_secret" {
|
||||
source = "../../modules/kubernetes/setup_tls_secret"
|
||||
namespace = kubernetes_namespace.speedtest.metadata[0].name
|
||||
|
|
@ -45,6 +67,9 @@ resource "kubernetes_deployment" "speedtest" {
|
|||
app = "speedtest"
|
||||
tier = local.tiers.aux
|
||||
}
|
||||
annotations = {
|
||||
"reloader.stakater.com/auto" = "true"
|
||||
}
|
||||
}
|
||||
spec {
|
||||
replicas = 1
|
||||
|
|
@ -108,8 +133,13 @@ resource "kubernetes_deployment" "speedtest" {
|
|||
value = "speedtest"
|
||||
}
|
||||
env {
|
||||
name = "DB_PASSWORD"
|
||||
value = data.vault_kv_secret_v2.secrets.data["db_password"]
|
||||
name = "DB_PASSWORD"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "speedtest-secrets"
|
||||
key = "db_password"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "DB_PORT"
|
||||
|
|
|
|||
|
|
@ -13,12 +13,6 @@ variable "kube_config_path" {
|
|||
default = "~/.kube/config"
|
||||
}
|
||||
|
||||
variable "vault_root_token" {
|
||||
type = string
|
||||
sensitive = true
|
||||
default = ""
|
||||
}
|
||||
|
||||
provider "kubernetes" {
|
||||
config_path = var.kube_config_path
|
||||
}
|
||||
|
|
@ -31,6 +25,5 @@ provider "helm" {
|
|||
|
||||
provider "vault" {
|
||||
address = "https://vault.viktorbarzin.me"
|
||||
token = var.vault_root_token
|
||||
skip_child_token = true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,11 +11,6 @@ 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 {
|
||||
name = "tandoor"
|
||||
|
|
@ -25,6 +20,34 @@ resource "kubernetes_namespace" "tandoor" {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "tandoor-secrets"
|
||||
namespace = "tandoor"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "tandoor-secrets"
|
||||
}
|
||||
dataFrom = [{
|
||||
extract = {
|
||||
key = "tandoor"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.tandoor]
|
||||
}
|
||||
|
||||
resource "random_password" "secret_key" {
|
||||
length = 128
|
||||
special = false
|
||||
|
|
@ -52,6 +75,9 @@ resource "kubernetes_deployment" "tandoor" {
|
|||
app = "tandoor"
|
||||
tier = local.tiers.aux
|
||||
}
|
||||
annotations = {
|
||||
"reloader.stakater.com/auto" = "true"
|
||||
}
|
||||
}
|
||||
spec {
|
||||
# Disabled: reduce cluster memory pressure (2026-03-14 OOM incident)
|
||||
|
|
@ -96,8 +122,13 @@ resource "kubernetes_deployment" "tandoor" {
|
|||
value = "tandoor"
|
||||
}
|
||||
env {
|
||||
name = "POSTGRES_PASSWORD"
|
||||
value = data.vault_kv_secret_v2.secrets.data["db_password"]
|
||||
name = "POSTGRES_PASSWORD"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "tandoor-secrets"
|
||||
key = "db_password"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "TANDOOR_PORT"
|
||||
|
|
|
|||
|
|
@ -6,23 +6,12 @@ variable "nfs_server" { type = string }
|
|||
variable "postgresql_host" { type = string }
|
||||
variable "redis_host" { type = string }
|
||||
variable "ollama_host" { type = string }
|
||||
data "vault_kv_secret_v2" "secrets" {
|
||||
mount = "secret"
|
||||
name = "trading-bot"
|
||||
}
|
||||
|
||||
locals {
|
||||
common_env = {
|
||||
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 = 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 = 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"
|
||||
|
|
@ -31,8 +20,6 @@ locals {
|
|||
TRADING_POLL_INTERVAL_SECONDS = "60"
|
||||
TRADING_HISTORICAL_BARS = "100"
|
||||
TRADING_SNAPSHOT_INTERVAL_SECONDS = "60"
|
||||
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"
|
||||
|
|
@ -56,6 +43,53 @@ module "tls_secret" {
|
|||
tls_secret_name = var.tls_secret_name
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "trading-bot-secrets"
|
||||
namespace = "trading-bot"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "trading-bot-secrets"
|
||||
template = {
|
||||
data = {
|
||||
TRADING_DATABASE_URL = "postgresql+asyncpg://trading:{{ .db_password }}@${var.postgresql_host}:5432/trading"
|
||||
TRADING_ALPACA_API_KEY = "{{ .alpaca_api_key }}"
|
||||
TRADING_ALPACA_SECRET_KEY = "{{ .alpaca_secret_key }}"
|
||||
TRADING_JWT_SECRET_KEY = "{{ .jwt_secret }}"
|
||||
TRADING_REDDIT_CLIENT_ID = "{{ .reddit_client_id }}"
|
||||
TRADING_REDDIT_CLIENT_SECRET = "{{ .reddit_client_secret }}"
|
||||
TRADING_ALPHA_VANTAGE_API_KEY = "{{ .alpha_vantage_api_key }}"
|
||||
TRADING_FMP_API_KEY = "{{ .fmp_api_key }}"
|
||||
DBAAS_ROOT_PASSWORD = "{{ .dbaas_root_password }}"
|
||||
DB_PASSWORD = "{{ .db_password }}"
|
||||
}
|
||||
}
|
||||
}
|
||||
data = [
|
||||
{ secretKey = "db_password", remoteRef = { key = "trading-bot", property = "db_password" } },
|
||||
{ secretKey = "alpaca_api_key", remoteRef = { key = "trading-bot", property = "alpaca_api_key" } },
|
||||
{ secretKey = "alpaca_secret_key", remoteRef = { key = "trading-bot", property = "alpaca_secret_key" } },
|
||||
{ secretKey = "jwt_secret", remoteRef = { key = "trading-bot", property = "jwt_secret" } },
|
||||
{ secretKey = "reddit_client_id", remoteRef = { key = "trading-bot", property = "reddit_client_id" } },
|
||||
{ secretKey = "reddit_client_secret", remoteRef = { key = "trading-bot", property = "reddit_client_secret" } },
|
||||
{ secretKey = "alpha_vantage_api_key", remoteRef = { key = "trading-bot", property = "alpha_vantage_api_key" } },
|
||||
{ secretKey = "fmp_api_key", remoteRef = { key = "trading-bot", property = "fmp_api_key" } },
|
||||
{ secretKey = "dbaas_root_password", remoteRef = { key = "trading-bot", property = "dbaas_root_password" } },
|
||||
]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.trading-bot]
|
||||
}
|
||||
|
||||
# Database init job - creates the trading database and user in PostgreSQL
|
||||
resource "kubernetes_job" "db_init" {
|
||||
metadata {
|
||||
|
|
@ -74,18 +108,23 @@ resource "kubernetes_job" "db_init" {
|
|||
<<-EOT
|
||||
set -e
|
||||
# Create role if not exists
|
||||
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"]}'"
|
||||
PGPASSWORD="$DBAAS_ROOT_PASSWORD" psql -h ${var.postgresql_host} -U root -tc "SELECT 1 FROM pg_roles WHERE rolname='trading'" | grep -q 1 || \
|
||||
PGPASSWORD="$DBAAS_ROOT_PASSWORD" psql -h ${var.postgresql_host} -U root -c "CREATE ROLE trading WITH LOGIN PASSWORD '$DB_PASSWORD'"
|
||||
# Create database if not exists
|
||||
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"
|
||||
PGPASSWORD="$DBAAS_ROOT_PASSWORD" psql -h ${var.postgresql_host} -U root -tc "SELECT 1 FROM pg_database WHERE datname='trading'" | grep -q 1 || \
|
||||
PGPASSWORD="$DBAAS_ROOT_PASSWORD" psql -h ${var.postgresql_host} -U root -c "CREATE DATABASE trading OWNER trading"
|
||||
# Grant privileges
|
||||
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"
|
||||
PGPASSWORD="$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='${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
|
||||
PGPASSWORD="$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
|
||||
]
|
||||
env_from {
|
||||
secret_ref {
|
||||
name = "trading-bot-secrets"
|
||||
}
|
||||
}
|
||||
}
|
||||
restart_policy = "Never"
|
||||
}
|
||||
|
|
@ -113,14 +152,15 @@ resource "kubernetes_job" "migrations" {
|
|||
image = "viktorbarzin/trading-bot-service:latest"
|
||||
image_pull_policy = "Always"
|
||||
command = ["python", "-m", "alembic", "upgrade", "head"]
|
||||
env {
|
||||
name = "TRADING_DATABASE_URL"
|
||||
value = "postgresql+asyncpg://trading:${data.vault_kv_secret_v2.secrets.data["db_password"]}@${var.postgresql_host}:5432/trading"
|
||||
}
|
||||
env {
|
||||
name = "TRADING_REDIS_URL"
|
||||
value = "redis://${var.redis_host}:6379/4"
|
||||
}
|
||||
env_from {
|
||||
secret_ref {
|
||||
name = "trading-bot-secrets"
|
||||
}
|
||||
}
|
||||
}
|
||||
restart_policy = "Never"
|
||||
}
|
||||
|
|
@ -143,6 +183,9 @@ resource "kubernetes_deployment" "trading-bot-frontend" {
|
|||
app = "trading-bot-frontend"
|
||||
tier = local.tiers.edge
|
||||
}
|
||||
annotations = {
|
||||
"reloader.stakater.com/auto" = "true"
|
||||
}
|
||||
}
|
||||
spec {
|
||||
# Disabled: reduce cluster memory pressure (2026-03-14 OOM incident)
|
||||
|
|
@ -200,6 +243,11 @@ resource "kubernetes_deployment" "trading-bot-frontend" {
|
|||
value = env.value
|
||||
}
|
||||
}
|
||||
env_from {
|
||||
secret_ref {
|
||||
name = "trading-bot-secrets"
|
||||
}
|
||||
}
|
||||
resources {
|
||||
requests = {
|
||||
cpu = "50m"
|
||||
|
|
@ -231,6 +279,9 @@ resource "kubernetes_deployment" "trading-bot-workers" {
|
|||
app = "trading-bot-workers"
|
||||
tier = local.tiers.edge
|
||||
}
|
||||
annotations = {
|
||||
"reloader.stakater.com/auto" = "true"
|
||||
}
|
||||
}
|
||||
spec {
|
||||
# Disabled: reduce cluster memory pressure (2026-03-14 OOM incident)
|
||||
|
|
@ -266,6 +317,11 @@ resource "kubernetes_deployment" "trading-bot-workers" {
|
|||
name = "TRADING_OTEL_METRICS_PORT"
|
||||
value = "9091"
|
||||
}
|
||||
env_from {
|
||||
secret_ref {
|
||||
name = "trading-bot-secrets"
|
||||
}
|
||||
}
|
||||
resources {
|
||||
requests = {
|
||||
cpu = "10m"
|
||||
|
|
@ -292,6 +348,11 @@ resource "kubernetes_deployment" "trading-bot-workers" {
|
|||
name = "TRADING_OTEL_METRICS_PORT"
|
||||
value = "9092"
|
||||
}
|
||||
env_from {
|
||||
secret_ref {
|
||||
name = "trading-bot-secrets"
|
||||
}
|
||||
}
|
||||
resources {
|
||||
requests = {
|
||||
cpu = "100m"
|
||||
|
|
@ -318,6 +379,11 @@ resource "kubernetes_deployment" "trading-bot-workers" {
|
|||
name = "TRADING_OTEL_METRICS_PORT"
|
||||
value = "9093"
|
||||
}
|
||||
env_from {
|
||||
secret_ref {
|
||||
name = "trading-bot-secrets"
|
||||
}
|
||||
}
|
||||
resources {
|
||||
requests = {
|
||||
cpu = "10m"
|
||||
|
|
@ -344,6 +410,11 @@ resource "kubernetes_deployment" "trading-bot-workers" {
|
|||
name = "TRADING_OTEL_METRICS_PORT"
|
||||
value = "9094"
|
||||
}
|
||||
env_from {
|
||||
secret_ref {
|
||||
name = "trading-bot-secrets"
|
||||
}
|
||||
}
|
||||
resources {
|
||||
requests = {
|
||||
cpu = "10m"
|
||||
|
|
@ -370,6 +441,11 @@ resource "kubernetes_deployment" "trading-bot-workers" {
|
|||
name = "TRADING_OTEL_METRICS_PORT"
|
||||
value = "9095"
|
||||
}
|
||||
env_from {
|
||||
secret_ref {
|
||||
name = "trading-bot-secrets"
|
||||
}
|
||||
}
|
||||
resources {
|
||||
requests = {
|
||||
cpu = "10m"
|
||||
|
|
@ -396,6 +472,11 @@ resource "kubernetes_deployment" "trading-bot-workers" {
|
|||
name = "TRADING_OTEL_METRICS_PORT"
|
||||
value = "9096"
|
||||
}
|
||||
env_from {
|
||||
secret_ref {
|
||||
name = "trading-bot-secrets"
|
||||
}
|
||||
}
|
||||
resources {
|
||||
requests = {
|
||||
cpu = "10m"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ dependency "platform" {
|
|||
skip_outputs = true
|
||||
}
|
||||
|
||||
dependency "vault" {
|
||||
config_path = "../vault"
|
||||
dependency "external-secrets" {
|
||||
config_path = "../external-secrets"
|
||||
skip_outputs = true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,11 +3,6 @@ variable "tls_secret_name" {
|
|||
sensitive = true
|
||||
}
|
||||
|
||||
data "vault_kv_secret_v2" "secrets" {
|
||||
mount = "secret"
|
||||
name = "tuya-bridge"
|
||||
}
|
||||
|
||||
resource "kubernetes_namespace" "tuya-bridge" {
|
||||
metadata {
|
||||
name = "tuya-bridge"
|
||||
|
|
@ -18,6 +13,33 @@ resource "kubernetes_namespace" "tuya-bridge" {
|
|||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "tuya-bridge-secrets"
|
||||
namespace = "tuya-bridge"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "tuya-bridge-secrets"
|
||||
}
|
||||
dataFrom = [{
|
||||
extract = {
|
||||
key = "tuya-bridge"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.tuya-bridge]
|
||||
}
|
||||
|
||||
module "tls_secret" {
|
||||
source = "../../modules/kubernetes/setup_tls_secret"
|
||||
namespace = kubernetes_namespace.tuya-bridge.metadata[0].name
|
||||
|
|
@ -32,6 +54,9 @@ resource "kubernetes_deployment" "tuya-bridge" {
|
|||
app = "tuya-bridge"
|
||||
tier = local.tiers.cluster
|
||||
}
|
||||
annotations = {
|
||||
"reloader.stakater.com/auto" = "true"
|
||||
}
|
||||
}
|
||||
spec {
|
||||
replicas = 3
|
||||
|
|
@ -54,20 +79,40 @@ resource "kubernetes_deployment" "tuya-bridge" {
|
|||
container_port = 8080
|
||||
}
|
||||
env {
|
||||
name = "TINYTUYA_API_KEY"
|
||||
value = data.vault_kv_secret_v2.secrets.data["api_key"]
|
||||
name = "TINYTUYA_API_KEY"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "tuya-bridge-secrets"
|
||||
key = "api_key"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "TINYTUYA_API_SECRET"
|
||||
value = data.vault_kv_secret_v2.secrets.data["api_secret"]
|
||||
name = "TINYTUYA_API_SECRET"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "tuya-bridge-secrets"
|
||||
key = "api_secret"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "SERVICE_API_KEY" # used for auth the API endpoint
|
||||
value = data.vault_kv_secret_v2.secrets.data["service_secret"]
|
||||
name = "SERVICE_API_KEY" # used for auth the API endpoint
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "tuya-bridge-secrets"
|
||||
key = "service_secret"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "SLACK_URL"
|
||||
value = data.vault_kv_secret_v2.secrets.data["slack_url"]
|
||||
name = "SLACK_URL"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "tuya-bridge-secrets"
|
||||
key = "slack_url"
|
||||
}
|
||||
}
|
||||
}
|
||||
resources {
|
||||
requests = {
|
||||
|
|
|
|||
|
|
@ -29,6 +29,33 @@ resource "kubernetes_namespace" "shlink" {
|
|||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "url-secrets"
|
||||
namespace = "url"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "url-secrets"
|
||||
}
|
||||
dataFrom = [{
|
||||
extract = {
|
||||
key = "url"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.shlink]
|
||||
}
|
||||
|
||||
module "tls_secret" {
|
||||
source = "../../modules/kubernetes/setup_tls_secret"
|
||||
namespace = kubernetes_namespace.shlink.metadata[0].name
|
||||
|
|
@ -87,6 +114,9 @@ resource "kubernetes_deployment" "shlink" {
|
|||
run = "shlink"
|
||||
tier = local.tiers.aux
|
||||
}
|
||||
annotations = {
|
||||
"reloader.stakater.com/auto" = "true"
|
||||
}
|
||||
}
|
||||
spec {
|
||||
replicas = 1
|
||||
|
|
@ -114,8 +144,13 @@ resource "kubernetes_deployment" "shlink" {
|
|||
value = "https"
|
||||
}
|
||||
env {
|
||||
name = "GEOLITE_LICENSE_KEY"
|
||||
value = data.vault_kv_secret_v2.secrets.data["geolite_license_key"]
|
||||
name = "GEOLITE_LICENSE_KEY"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "url-secrets"
|
||||
key = "geolite_license_key"
|
||||
}
|
||||
}
|
||||
}
|
||||
# DB config
|
||||
env {
|
||||
|
|
|
|||
|
|
@ -4,11 +4,6 @@ variable "tls_secret_name" {
|
|||
}
|
||||
variable "nfs_server" { type = string }
|
||||
|
||||
data "vault_kv_secret_v2" "secrets" {
|
||||
mount = "secret"
|
||||
name = "wealthfolio"
|
||||
}
|
||||
|
||||
# To refresh transactions use finance db positions exporters:
|
||||
#
|
||||
# workon finace-app && cd ~/code/finance && python main.py fetch position --imap-user=$IMAP_USER --imap-password=$IMAP_PASSWORD --trading212-api-keys=$TRADING212_API_KEYS --output-file positions.csv && mv positions.csv /home/wizard/code/infra/modules/kubernetes/wealthfolio/updated_trades.csv
|
||||
|
|
@ -26,6 +21,33 @@ resource "kubernetes_namespace" "wealthfolio" {
|
|||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "wealthfolio-secrets"
|
||||
namespace = "wealthfolio"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "wealthfolio-secrets"
|
||||
}
|
||||
dataFrom = [{
|
||||
extract = {
|
||||
key = "wealthfolio"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.wealthfolio]
|
||||
}
|
||||
|
||||
module "tls_secret" {
|
||||
source = "../../modules/kubernetes/setup_tls_secret"
|
||||
namespace = kubernetes_namespace.wealthfolio.metadata[0].name
|
||||
|
|
@ -53,6 +75,9 @@ resource "kubernetes_deployment" "wealthfolio" {
|
|||
app = "wealthfolio"
|
||||
tier = local.tiers.aux
|
||||
}
|
||||
annotations = {
|
||||
"reloader.stakater.com/auto" = "true"
|
||||
}
|
||||
}
|
||||
spec {
|
||||
replicas = 1
|
||||
|
|
@ -79,8 +104,13 @@ resource "kubernetes_deployment" "wealthfolio" {
|
|||
value = "0.0.0.0:8080"
|
||||
}
|
||||
env {
|
||||
name = "WF_AUTH_PASSWORD_HASH"
|
||||
value = data.vault_kv_secret_v2.secrets.data["password_hash"]
|
||||
name = "WF_AUTH_PASSWORD_HASH"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "wealthfolio-secrets"
|
||||
key = "password_hash"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "WF_DB_PATH"
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ resource "kubernetes_deployment" "webhook_handler" {
|
|||
tier = local.tiers.aux
|
||||
}
|
||||
annotations = {
|
||||
"reloader.stakater.com/search" = "true"
|
||||
"reloader.stakater.com/auto" = "true"
|
||||
}
|
||||
}
|
||||
spec {
|
||||
|
|
@ -126,32 +126,62 @@ resource "kubernetes_deployment" "webhook_handler" {
|
|||
sub_path = "id_rsa"
|
||||
}
|
||||
env {
|
||||
name = "WEBHOOKSECRET"
|
||||
value = data.vault_kv_secret_v2.secrets.data["secret"]
|
||||
name = "WEBHOOKSECRET"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "webhook-handler-secrets"
|
||||
key = "secret"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "FB_APP_SECRET"
|
||||
value = data.vault_kv_secret_v2.secrets.data["fb_app_secret"]
|
||||
name = "FB_APP_SECRET"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "webhook-handler-secrets"
|
||||
key = "fb_app_secret"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "FB_VERIFY_TOKEN"
|
||||
value = data.vault_kv_secret_v2.secrets.data["fb_verify_token"]
|
||||
name = "FB_VERIFY_TOKEN"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "webhook-handler-secrets"
|
||||
key = "fb_verify_token"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "FB_PAGE_TOKEN"
|
||||
value = data.vault_kv_secret_v2.secrets.data["fb_page_token"]
|
||||
name = "FB_PAGE_TOKEN"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "webhook-handler-secrets"
|
||||
key = "fb_page_token"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "CONFIG"
|
||||
value = "./chatbot/config/viktorwebservices.yaml"
|
||||
}
|
||||
env {
|
||||
name = "GIT_USER"
|
||||
value = data.vault_kv_secret_v2.secrets.data["git_user"]
|
||||
name = "GIT_USER"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "webhook-handler-secrets"
|
||||
key = "git_user"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "GIT_TOKEN"
|
||||
value = data.vault_kv_secret_v2.secrets.data["git_token"]
|
||||
name = "GIT_TOKEN"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "webhook-handler-secrets"
|
||||
key = "git_token"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "SSH_KEY"
|
||||
|
|
@ -205,3 +235,30 @@ module "ingress" {
|
|||
"gethomepage.dev/pod-selector" = ""
|
||||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "webhook-handler-secrets"
|
||||
namespace = "webhook-handler"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "webhook-handler-secrets"
|
||||
}
|
||||
dataFrom = [{
|
||||
extract = {
|
||||
key = "webhook-handler"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.webhook-handler]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,33 @@ module "tls_secret" {
|
|||
tls_secret_name = var.tls_secret_name
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "woodpecker-secrets"
|
||||
namespace = "woodpecker"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "woodpecker-secrets"
|
||||
}
|
||||
dataFrom = [{
|
||||
extract = {
|
||||
key = "woodpecker"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.woodpecker]
|
||||
}
|
||||
|
||||
resource "kubernetes_config_map" "git_crypt_key" {
|
||||
metadata {
|
||||
name = "git-crypt-key"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
server:
|
||||
enabled: true
|
||||
podAnnotations:
|
||||
reloader.stakater.com/search: "true"
|
||||
statefulSet:
|
||||
replicaCount: 1
|
||||
image:
|
||||
|
|
@ -36,6 +38,8 @@ server:
|
|||
|
||||
agent:
|
||||
enabled: true
|
||||
podAnnotations:
|
||||
reloader.stakater.com/search: "true"
|
||||
replicaCount: 2
|
||||
image:
|
||||
registry: docker.io
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue