From 6dda15afa060f7bd48c91a590c8efcf97c8c6c38 Mon Sep 17 00:00:00 2001 From: Viktor Barzin Date: Wed, 25 Mar 2026 13:03:35 +0200 Subject: [PATCH] add insta2spotify stack: namespace, ESO, NFS, 2-container deploy, split ingress - Namespace insta2spotify (tier 4-aux) - ExternalSecret from Vault secret/insta2spotify - NFS volume at /mnt/main/insta2spotify for SQLite + Spotify cache - Frontend (128Mi) + backend (512Mi req / 2Gi limit) in one pod - Split ingress: protected (Authentik) for frontend, unprotected for /api/* - DNS via Cloudflare (proxied) --- config.tfvars | Bin 10058 -> 10075 bytes stacks/insta2spotify/main.tf | 243 ++++++++++++++++++++++++++++ stacks/insta2spotify/terragrunt.hcl | 13 ++ stacks/insta2spotify/tiers.tf | 10 ++ 4 files changed, 266 insertions(+) create mode 100644 stacks/insta2spotify/main.tf create mode 100644 stacks/insta2spotify/terragrunt.hcl create mode 100644 stacks/insta2spotify/tiers.tf diff --git a/config.tfvars b/config.tfvars index d633b6aabec76b842475167fef4cac28116908c5..fb8f2a00184d6b367c5a406edb6904fbc31a0a34 100644 GIT binary patch literal 10075 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 literal 10058 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 diff --git a/stacks/insta2spotify/main.tf b/stacks/insta2spotify/main.tf new file mode 100644 index 00000000..adbda115 --- /dev/null +++ b/stacks/insta2spotify/main.tf @@ -0,0 +1,243 @@ +variable "tls_secret_name" { + type = string + sensitive = true +} +variable "nfs_server" { type = string } + +resource "kubernetes_namespace" "insta2spotify" { + metadata { + name = "insta2spotify" + labels = { + "istio-injection" = "disabled" + tier = local.tiers.aux + } + } +} + +resource "kubernetes_manifest" "external_secret" { + manifest = { + apiVersion = "external-secrets.io/v1beta1" + kind = "ExternalSecret" + metadata = { + name = "insta2spotify-secrets" + namespace = "insta2spotify" + } + spec = { + refreshInterval = "15m" + secretStoreRef = { + name = "vault-kv" + kind = "ClusterSecretStore" + } + target = { + name = "insta2spotify-secrets" + } + dataFrom = [{ + extract = { + key = "insta2spotify" + } + }] + } + } + depends_on = [kubernetes_namespace.insta2spotify] +} + +module "nfs_data" { + source = "../../modules/kubernetes/nfs_volume" + name = "insta2spotify-data" + namespace = kubernetes_namespace.insta2spotify.metadata[0].name + nfs_server = var.nfs_server + nfs_path = "/mnt/main/insta2spotify" +} + +resource "kubernetes_deployment" "insta2spotify" { + metadata { + name = "insta2spotify" + namespace = kubernetes_namespace.insta2spotify.metadata[0].name + labels = { + app = "insta2spotify" + tier = local.tiers.aux + } + annotations = { + "reloader.stakater.com/auto" = "true" + } + } + spec { + replicas = 1 + selector { + match_labels = { + app = "insta2spotify" + } + } + template { + metadata { + labels = { + app = "insta2spotify" + } + } + spec { + container { + name = "frontend" + image = "viktorbarzin/insta2spotify-frontend:latest" + port { + container_port = 3000 + } + env { + name = "BACKEND_URL" + value = "http://127.0.0.1:8000" + } + env { + name = "ORIGIN" + value = "https://insta2spotify.viktorbarzin.me" + } + resources { + limits = { + memory = "128Mi" + } + requests = { + cpu = "10m" + memory = "128Mi" + } + } + } + container { + name = "backend" + image = "viktorbarzin/insta2spotify-backend:latest" + port { + container_port = 8000 + } + env { + name = "DATABASE_PATH" + value = "/data/insta2spotify.db" + } + env { + name = "SPOTIFY_CACHE_PATH" + value = "/data/.spotify_cache" + } + env { + name = "SPOTIFY_REDIRECT_URI" + value = "https://insta2spotify.viktorbarzin.me/api/auth/callback" + } + env { + name = "SPOTIFY_PLAYLIST_ID" + value = "7lcLakPy8pwwegFoOQ7MoG" + } + env { + name = "SPOTIFY_CLIENT_ID" + value_from { + secret_key_ref { + name = "insta2spotify-secrets" + key = "spotify_client_id" + } + } + } + env { + name = "SPOTIFY_CLIENT_SECRET" + value_from { + secret_key_ref { + name = "insta2spotify-secrets" + key = "spotify_client_secret" + } + } + } + env { + name = "API_KEY" + value_from { + secret_key_ref { + name = "insta2spotify-secrets" + key = "api_key" + } + } + } + env { + name = "SPOTIFY_REFRESH_TOKEN" + value_from { + secret_key_ref { + name = "insta2spotify-secrets" + key = "spotify_refresh_token" + } + } + } + volume_mount { + name = "data" + mount_path = "/data" + } + resources { + limits = { + memory = "2Gi" + } + requests = { + cpu = "50m" + memory = "512Mi" + } + } + } + volume { + name = "data" + persistent_volume_claim { + claim_name = module.nfs_data.claim_name + } + } + } + } + } + lifecycle { + ignore_changes = [spec[0].template[0].spec[0].dns_config] + } +} + +resource "kubernetes_service" "insta2spotify" { + metadata { + name = "insta2spotify" + namespace = kubernetes_namespace.insta2spotify.metadata[0].name + labels = { + app = "insta2spotify" + } + } + spec { + selector = { + app = "insta2spotify" + } + port { + name = "http" + port = 80 + target_port = 3000 + } + } +} + +module "tls_secret" { + source = "../../modules/kubernetes/setup_tls_secret" + namespace = kubernetes_namespace.insta2spotify.metadata[0].name + tls_secret_name = var.tls_secret_name +} + +# Main ingress — protected by Authentik (frontend) +module "ingress" { + source = "../../modules/kubernetes/ingress_factory" + namespace = kubernetes_namespace.insta2spotify.metadata[0].name + name = "insta2spotify" + tls_secret_name = var.tls_secret_name + protected = true + max_body_size = "50m" + extra_annotations = { + "gethomepage.dev/enabled" = "true" + "gethomepage.dev/name" = "insta2spotify" + "gethomepage.dev/description" = "Instagram Reels to Spotify" + "gethomepage.dev/icon" = "si-spotify" + "gethomepage.dev/group" = "Media & Entertainment" + "gethomepage.dev/pod-selector" = "" + } +} + +# API ingress — unprotected (API key auth handled by backend) +module "ingress_api" { + source = "../../modules/kubernetes/ingress_factory" + namespace = kubernetes_namespace.insta2spotify.metadata[0].name + name = "insta2spotify-api" + host = "insta2spotify" + service_name = "insta2spotify" + tls_secret_name = var.tls_secret_name + protected = false + ingress_path = ["/api/identify", "/api/auth", "/api/health", "/api/history"] + max_body_size = "50m" +} diff --git a/stacks/insta2spotify/terragrunt.hcl b/stacks/insta2spotify/terragrunt.hcl new file mode 100644 index 00000000..f4c920ab --- /dev/null +++ b/stacks/insta2spotify/terragrunt.hcl @@ -0,0 +1,13 @@ +include "root" { + path = find_in_parent_folders() +} + +dependency "platform" { + config_path = "../platform" + skip_outputs = true +} + +dependency "vault" { + config_path = "../vault" + skip_outputs = true +} diff --git a/stacks/insta2spotify/tiers.tf b/stacks/insta2spotify/tiers.tf new file mode 100644 index 00000000..eb0f8083 --- /dev/null +++ b/stacks/insta2spotify/tiers.tf @@ -0,0 +1,10 @@ +# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa +locals { + tiers = { + core = "0-core" + cluster = "1-cluster" + gpu = "2-gpu" + edge = "3-edge" + aux = "4-aux" + } +}