diff --git a/.github/actions/provision/action.yml b/.github/actions/provision/action.yml index 0165a3d..0e84cb2 100644 --- a/.github/actions/provision/action.yml +++ b/.github/actions/provision/action.yml @@ -71,3 +71,8 @@ runs: shell: bash working-directory: bootstrap run: ./.github/scripts/verify_platform_health.sh + + - name: Disable platform autosync + shell: bash + working-directory: bootstrap + run: ./.github/scripts/disable_platform_autosync.sh diff --git a/.github/scripts/disable_platform_autosync.sh b/.github/scripts/disable_platform_autosync.sh new file mode 100755 index 0000000..0cc5729 --- /dev/null +++ b/.github/scripts/disable_platform_autosync.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +set -euo pipefail + +ARGO_NAMESPACE=${ARGO_NAMESPACE:-argocd} +PLATFORM_APPLICATION=${PLATFORM_APPLICATION:-platform} + +SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +REPO_ROOT=$(cd "$SCRIPT_DIR/../.." && pwd) +readonly KUBECONFIG_PATH="$REPO_ROOT/stacks/k8s/.kube/agyn-local-kubeconfig.yaml" + +if [[ ! -f "$KUBECONFIG_PATH" ]]; then + printf 'Unable to locate kubeconfig at %s\n' "$KUBECONFIG_PATH" >&2 + exit 1 +fi + +kubectl --kubeconfig "$KUBECONFIG_PATH" \ + -n "$ARGO_NAMESPACE" patch application "$PLATFORM_APPLICATION" \ + --type merge \ + -p '{"spec":{"syncPolicy":{"automated":{"enabled":false}}}}' + +printf 'Disabled automated sync for Argo CD application %s/%s.\n' "$ARGO_NAMESPACE" "$PLATFORM_APPLICATION" diff --git a/.github/scripts/verify_platform_health.sh b/.github/scripts/verify_platform_health.sh index 96ec377..e3fb170 100755 --- a/.github/scripts/verify_platform_health.sh +++ b/.github/scripts/verify_platform_health.sh @@ -24,7 +24,7 @@ if [[ ! -f "$KUBECONFIG_PATH" ]]; then exit 1 fi -REQUIRED_APPS_JSON='["cert-manager","trust-manager","ziti-controller","ziti-management","registry-mirror","minio","platform-db","threads-db","chat-db","identity-db","runners-db","metering-db","identity","authorization","gateway","runners","notifications-redis","notifications","metering","threads","chat","k8s-runner"]' +REQUIRED_APPS_JSON='["cert-manager","trust-manager","ziti-controller","platform","registry-mirror","minio","openfga-db","openfga","platform-db","threads-db","metering-db","chat-db","tracing-db","secrets-db","llm-db","agents-db","ziti-management-db","users-db","expose-db","organizations-db","agents-orchestrator-db","identity-db","runners-db","apps-db","reminders-db","reminders","telegram-connector-db","telegram-connector","k8s-runner"]' deadline=$((SECONDS + TOTAL_TIMEOUT)) pod_terminal_failures_streak=0 diff --git a/apply.sh b/apply.sh index 490ade3..b4edd02 100755 --- a/apply.sh +++ b/apply.sh @@ -487,44 +487,43 @@ run_stack "platform" step_end "stack:platform" echo "=== Waiting for platform ArgoCD applications to sync ===" -for app in identity organizations gateway apps runners; do - echo "--- Waiting for ${app} ---" - synced=0 - for i in $(seq 1 60); do - sync_status=$(kubectl --kubeconfig "${KUBECONFIG_PATH}" \ - -n argocd get application "${app}" \ - -o jsonpath='{.status.sync.status}' 2>/dev/null || echo "Unknown") - health_status=$(kubectl --kubeconfig "${KUBECONFIG_PATH}" \ - -n argocd get application "${app}" \ - -o jsonpath='{.status.health.status}' 2>/dev/null || echo "Unknown") - - if [[ "${sync_status}" == "Synced" && "${health_status}" == "Healthy" ]]; then - echo "${app}: Synced and Healthy" - synced=1 - break - fi - echo " ${app}: sync=${sync_status} health=${health_status} (${i}/60)" - sleep 10 - done - - if [[ "${synced}" -ne 1 ]]; then - echo "ERROR: ${app} did not become Synced+Healthy within timeout" - echo "--- Full Application status ---" - kubectl --kubeconfig "${KUBECONFIG_PATH}" \ - -n argocd get application "${app}" -o yaml 2>&1 || true - echo "--- ${app} namespace pods ---" - ns=$(kubectl --kubeconfig "${KUBECONFIG_PATH}" \ - -n argocd get application "${app}" \ - -o jsonpath='{.spec.destination.namespace}' 2>/dev/null || echo "unknown") - kubectl --kubeconfig "${KUBECONFIG_PATH}" \ - -n "${ns}" get pods -o wide 2>&1 || true - echo "--- ${app} namespace events ---" - kubectl --kubeconfig "${KUBECONFIG_PATH}" \ - -n "${ns}" get events --sort-by='.lastTimestamp' 2>&1 | tail -30 || true - exit 1 +app="platform" +echo "--- Waiting for ${app} ---" +synced=0 +for i in $(seq 1 60); do + sync_status=$(kubectl --kubeconfig "${KUBECONFIG_PATH}" \ + -n argocd get application "${app}" \ + -o jsonpath='{.status.sync.status}' 2>/dev/null || echo "Unknown") + health_status=$(kubectl --kubeconfig "${KUBECONFIG_PATH}" \ + -n argocd get application "${app}" \ + -o jsonpath='{.status.health.status}' 2>/dev/null || echo "Unknown") + + if [[ "${sync_status}" == "Synced" && "${health_status}" == "Healthy" ]]; then + echo "${app}: Synced and Healthy" + synced=1 + break fi + echo " ${app}: sync=${sync_status} health=${health_status} (${i}/60)" + sleep 10 done +if [[ "${synced}" -ne 1 ]]; then + echo "ERROR: ${app} did not become Synced+Healthy within timeout" + echo "--- Full Application status ---" + kubectl --kubeconfig "${KUBECONFIG_PATH}" \ + -n argocd get application "${app}" -o yaml 2>&1 || true + echo "--- ${app} namespace pods ---" + ns=$(kubectl --kubeconfig "${KUBECONFIG_PATH}" \ + -n argocd get application "${app}" \ + -o jsonpath='{.spec.destination.namespace}' 2>/dev/null || echo "unknown") + kubectl --kubeconfig "${KUBECONFIG_PATH}" \ + -n "${ns}" get pods -o wide 2>&1 || true + echo "--- ${app} namespace events ---" + kubectl --kubeconfig "${KUBECONFIG_PATH}" \ + -n "${ns}" get events --sort-by='.lastTimestamp' 2>&1 | tail -30 || true + exit 1 +fi + echo "=== Waiting for gateway HTTP endpoint ===" gateway_base_url="https://gateway.${domain}:${port}" gateway_paths=("/healthz" "/health" "/readyz" "/version" "/") diff --git a/stacks/apps/.terraform.lock.hcl b/stacks/apps/.terraform.lock.hcl index dba30e2..5d1cb39 100644 --- a/stacks/apps/.terraform.lock.hcl +++ b/stacks/apps/.terraform.lock.hcl @@ -5,6 +5,7 @@ provider "registry.terraform.io/agynio/agyn" { version = "0.6.11" constraints = "~> 0.6" hashes = [ + "h1:0C+xHFKqzWi+9YT10SyvMDCnvPTxkWuGJxjKLYA0wMs=", "h1:2EpEMlLIhAbEFx6wnOObjbfUYVzdkue+CFBuZn6NaQo=", "zh:1db60ffcb376618c75e36652e28a43290db1c9de3f9a3f8cc4e54e2bb2cea7fe", "zh:2213189873c66cfd6621e55b122699a6c30ac8d37f47daf0c0f98a246c3a4a60", @@ -24,6 +25,7 @@ provider "registry.terraform.io/argoproj-labs/argocd" { constraints = "~> 7.14" hashes = [ "h1:ZCIcaDzTy2WN2iaaMA9puR1khbGetdesJDYNEgshfZE=", + "h1:ZeLDjsFcmAraMlBYOyk38WECajt3tTNnGnaJgY4wlYg=", "h1:gklxppttVJ+pXqxAkUwmQFR9EreSKNBqoh7hbLbyIPI=", "zh:1a754d97259b9d2e9e624703eec655278bff20ca829b9d48ee9aae9591af2681", "zh:3728ed3654f426d745d624d6895631651ebd8e84d594fe475849f2ad02c5c027", @@ -43,6 +45,7 @@ provider "registry.terraform.io/hashicorp/kubernetes" { constraints = "~> 2.33" hashes = [ "h1:5CkveFo5ynsLdzKk+Kv+r7+U9rMrNjfZPT3a0N/fhgE=", + "h1:XCkL/mxjWTawg6gg+jlpCQhF/+SNRoCEZxbbkDTj42s=", "h1:soK8Lt0SZ6dB+HsypFRDzuX/npqlMU6M0fvyaR1yW0k=", "zh:0af928d776eb269b192dc0ea0f8a3f0f5ec117224cd644bdacdc682300f84ba0", "zh:1be998e67206f7cfc4ffe77c01a09ac91ce725de0abaec9030b22c0a832af44f", diff --git a/stacks/apps/main.tf b/stacks/apps/main.tf index 7ece564..d23167d 100644 --- a/stacks/apps/main.tf +++ b/stacks/apps/main.tf @@ -92,7 +92,7 @@ locals { }, { name = "GATEWAY_URL" - value = "http://gateway-gateway.platform.svc.cluster.local:8080" + value = "http://gateway.platform.svc.cluster.local:8080" }, { name = "SERVICE_TOKEN" @@ -174,7 +174,7 @@ locals { }, { name = "GATEWAY_URL" - value = "http://gateway-gateway.platform.svc.cluster.local:8080" + value = "http://gateway.platform.svc.cluster.local:8080" }, { name = "ZITI_SERVICE_NAME" @@ -228,7 +228,7 @@ locals { }, { name = "GATEWAY_ADDRESS" - value = "gateway-gateway:8080" + value = "gateway:8080" }, { name = "CAPABILITY_IMPLEMENTATIONS" diff --git a/stacks/platform/main.tf b/stacks/platform/main.tf index 9445eae..71ab22e 100644 --- a/stacks/platform/main.tf +++ b/stacks/platform/main.tf @@ -2,7 +2,6 @@ locals { resolved_gateway_image_tag = trimspace(var.gateway_image_tag) != "" ? var.gateway_image_tag : var.gateway_chart_version resolved_agents_orchestrator_image_tag = trimspace(var.agents_orchestrator_image_tag) != "" ? var.agents_orchestrator_image_tag : var.agents_orchestrator_chart_version resolved_threads_image_tag = trimspace(var.threads_image_tag) != "" ? var.threads_image_tag : var.threads_chart_version - resolved_metering_image_tag = trimspace(var.metering_image_tag) != "" ? var.metering_image_tag : var.metering_chart_version resolved_tracing_image_tag = trimspace(var.tracing_image_tag) != "" ? var.tracing_image_tag : format("v%s", var.tracing_chart_version) resolved_chat_image_tag = trimspace(var.chat_image_tag) != "" ? var.chat_image_tag : var.chat_chart_version resolved_chat_app_image_tag = trimspace(var.chat_app_image_tag) != "" ? var.chat_app_image_tag : var.chat_app_chart_version @@ -34,33 +33,9 @@ locals { ncps_chart_name = "agynio/charts/ncps" ncps_chart_revision = "0.1.3" platform_chart_repo_host = "ghcr.io" + platform_chart_name = "agynio/charts/agyn-platform" postgres_chart_repo_host = "ghcr.io" postgres_chart_name = "agynio/charts/postgres-helm" - agents_orchestrator_chart_name = "agynio/charts/agents-orchestrator" - threads_chart_name = "agynio/charts/threads" - metering_chart_name = "agynio/charts/metering" - tracing_chart_name = "agynio/charts/tracing" - chat_chart_name = "agynio/charts/chat" - chat_app_chart_name = "agynio/charts/chat-app" - console_app_chart_name = "agynio/charts/console-app" - tracing_app_chart_name = "agynio/charts/tracing-app" - files_chart_name = "agynio/charts/files" - media_proxy_chart_name = "agynio/charts/media-proxy" - llm_chart_name = "agynio/charts/llm" - llm_proxy_chart_name = "agynio/charts/llm-proxy" - secrets_chart_name = "agynio/charts/secrets" - token_counting_chart_name = "agynio/charts/token-counting" - notifications_chart_name = "agynio/charts/notifications" - redis_chart_name = "redis" - agents_chart_name = "agynio/charts/agents" - ziti_management_chart_name = "agynio/charts/ziti-management" - users_chart_name = "agynio/charts/users" - expose_chart_name = "agynio/charts/expose" - organizations_chart_name = "agynio/charts/organizations" - authorization_chart_name = "agynio/charts/authorization" - identity_chart_name = "agynio/charts/identity" - runners_chart_name = "agynio/charts/runners" - apps_chart_name = "agynio/charts/apps" istio_gateway_namespace = data.terraform_remote_state.system.outputs.istio_gateway_namespace istio_gateway_tls_secret_name = data.terraform_remote_state.system.outputs.wildcard_tls_gateway_secret_name openfga_api_url_external = format("https://openfga.%s:%d", local.base_domain, local.ingress_port) @@ -468,631 +443,776 @@ locals { } }) - threads_values = yamlencode({ - replicaCount = 1 - fullnameOverride = "threads" - service = { - ports = [ - { - name = "grpc" - port = 50051 - targetPort = "grpc" - protocol = "TCP" + platform_database_secret_name = "agyn-platform-database-urls" + files_s3_secret_name = "agyn-files-s3" + + platform_database_urls = { + "agents" = format("postgresql://agents:%s@agents-db:5432/agents?sslmode=disable", var.agents_db_password) + "agents-orchestrator" = format("postgresql://orchestrator:%s@agents-orchestrator-db:5432/orchestrator?sslmode=disable", var.agents_orchestrator_db_password) + "apps" = format("postgresql://apps:%s@apps-db:5432/apps?sslmode=disable", var.apps_db_password) + "chat" = format("postgresql://chat:%s@chat-db:5432/chat?sslmode=disable", var.chat_db_password) + "expose" = format("postgresql://expose:%s@expose-db:5432/expose?sslmode=disable", var.expose_db_password) + "files" = format("postgresql://files:%s@files-db:5432/files?sslmode=disable", var.files_db_password) + "identity" = format("postgresql://identity:%s@identity-db:5432/identity?sslmode=disable", var.identity_db_password) + "llm" = format("postgresql://llm:%s@llm-db:5432/llm?sslmode=disable", var.llm_db_password) + "organizations" = format("postgresql://organizations:%s@organizations-db:5432/organizations?sslmode=disable", var.organizations_db_password) + "runners" = format("postgresql://runners:%s@runners-db:5432/runners?sslmode=disable", var.runners_db_password) + "secrets" = format("postgresql://secrets:%s@secrets-db:5432/secrets?sslmode=disable", var.secrets_db_password) + "threads" = format("postgresql://threads:%s@threads-db:5432/threads?sslmode=disable", var.threads_db_password) + "tracing" = format("postgresql://tracing:%s@tracing-db:5432/tracing?sslmode=disable", var.tracing_db_password) + "users" = format("postgresql://users:%s@users-db:5432/users?sslmode=disable", var.users_db_password) + "ziti-management" = format("postgresql://ziti_management:%s@ziti-management-db:5432/ziti_management?sslmode=disable", var.ziti_management_db_password) + } + + database_url_env_refs = { + for service in keys(local.platform_database_urls) : service => { + name = "DATABASE_URL" + valueFrom = { + secretKeyRef = { + name = "agyn-platform-database-urls" + key = service } - ] - } - env = [ - { - name = "GRPC_ADDRESS" - value = ":50051" - }, - { - name = "DATABASE_URL" - value = format("postgresql://threads:%s@threads-db:5432/threads?sslmode=disable", var.threads_db_password) - }, - ] - securityContext = { - runAsUser = 100 - runAsGroup = 101 - } - image = { - repository = "ghcr.io/agynio/threads" - tag = local.resolved_threads_image_tag - pullPolicy = "IfNotPresent" - } - }) - - metering_values = yamlencode({ - replicaCount = 1 - fullnameOverride = "metering" - image = { - repository = "ghcr.io/agynio/metering" - tag = local.resolved_metering_image_tag - pullPolicy = "IfNotPresent" - } - env = [ - { - name = "GRPC_ADDRESS" - value = ":50051" - }, - { - name = "DATABASE_URL" - value = format("postgresql://metering:%s@metering-db:5432/metering?sslmode=disable", var.metering_db_password) - }, - { - name = "LOG_LEVEL" - value = "info" - }, - ] - }) - - tracing_values = yamlencode({ - replicaCount = 1 - fullnameOverride = "tracing" - service = { - port = 50051 - } - extraEnvVars = [ - { - name = "DATABASE_URL" - value = format("postgresql://tracing:%s@tracing-db:5432/tracing?sslmode=disable", var.tracing_db_password) - }, - { - name = "ZITI_ENABLED" - value = "true" - }, - ] - image = { - repository = "ghcr.io/agynio/tracing" - tag = local.resolved_tracing_image_tag - pullPolicy = "IfNotPresent" - } - }) - - chat_values = yamlencode({ - fullnameOverride = "chat" - image = { - repository = "ghcr.io/agynio/chat" - tag = local.resolved_chat_image_tag - pullPolicy = "IfNotPresent" - } - env = [ - { - name = "DATABASE_URL" - value = format("postgresql://chat:%s@chat-db:5432/chat?sslmode=disable", var.chat_db_password) - }, - ] - }) - - secrets_values = yamlencode({ - fullnameOverride = "secrets" - service = { - port = 50051 - } - database = { - url = format("postgresql://secrets:%s@secrets-db:5432/secrets?sslmode=disable", var.secrets_db_password) - } - image = { - repository = "ghcr.io/agynio/secrets" - tag = local.resolved_secrets_image_tag - pullPolicy = "IfNotPresent" - } - secrets = { - encryptionKeyFile = "/etc/secrets-encryption/encryptionKey" - encryptionKeySecretName = "secrets-encryption-key" - } - }) - - agents_values = yamlencode({ - fullnameOverride = "agents" - image = { - repository = "ghcr.io/agynio/agents" - tag = local.resolved_agents_image_tag - pullPolicy = "IfNotPresent" + } } - env = [ - { - name = "DATABASE_URL" - value = format("postgresql://agents:%s@agents-db:5432/agents?sslmode=disable", var.agents_db_password) - }, - ] - }) + } - ziti_management_values = yamlencode({ - fullnameOverride = "ziti-management" - image = { - repository = "ghcr.io/agynio/ziti-management" - tag = local.resolved_ziti_management_image_tag - pullPolicy = "IfNotPresent" - } - updateStrategy = { - type = "Recreate" + notifications_redis_values = { + fullnameOverride = "notifications-redis" + architecture = "standalone" + auth = { + enabled = false } - securityContext = { - enabled = true - runAsNonRoot = true - runAsUser = 100 - runAsGroup = 101 - readOnlyRootFilesystem = true - allowPrivilegeEscalation = false - capabilities = { - drop = ["ALL"] - } - seccompProfile = { - type = "RuntimeDefault" + master = { + persistence = { + enabled = false } } - persistence = { - enabled = true - accessMode = "ReadWriteOnce" - size = "10Mi" - } - configMounts = [ - { - name = "ziti-enrollment" - sourceName = "ziti-management-enrollment" - type = "secret" - mountPath = "/etc/ziti-enrollment" - readOnly = true - }, - ] - env = [ - { - name = "DATABASE_URL" - value = format("postgresql://ziti_management:%s@ziti-management-db:5432/ziti_management?sslmode=disable", var.ziti_management_db_password) - }, - { - name = "ZITI_CONTROLLER_URL" - value = format("https://ziti-mgmt.%s:%d/edge/management/v1", local.base_domain, local.ingress_port) - }, - { - name = "ZITI_CERT_FILE" - value = "/var/lib/ziti/tls.crt" - }, - { - name = "ZITI_KEY_FILE" - value = "/var/lib/ziti/tls.key" - }, - { - name = "ZITI_CA_FILE" - value = "/var/lib/ziti/ca.crt" - }, - { - name = "ZITI_ENROLLMENT_JWT_FILE" - value = "/etc/ziti-enrollment/enrollmentJwt" - }, - { - name = "ZITI_IDENTITY_NAME_RESOLVE" - value = "true" - }, - ] - }) + } - users_values = yamlencode({ - fullnameOverride = "users" - image = { - repository = "ghcr.io/agynio/users" - tag = local.resolved_users_image_tag - pullPolicy = "IfNotPresent" - } - env = [ + web_app_service_values = { + type = "ClusterIP" + ports = [ { - name = "DATABASE_URL" - value = format("postgresql://users:%s@users-db:5432/users?sslmode=disable", var.users_db_password) - }, + name = "http" + port = 3000 + targetPort = "http" + protocol = "TCP" + } ] - }) + } - expose_values = yamlencode({ - fullnameOverride = "expose" - image = { - repository = "ghcr.io/agynio/expose" - tag = local.resolved_expose_image_tag - pullPolicy = "IfNotPresent" - } - env = [ - { - name = "DATABASE_URL" - value = format("postgresql://expose:%s@expose-db:5432/expose?sslmode=disable", var.expose_db_password) - }, + web_app_extra_volumes = { + for app_name in ["chat-app", "console-app", "tracing-app"] : app_name => [ { - name = "ZITI_MANAGEMENT_ADDRESS" - value = "ziti-management:50051" + name = "${app_name}-cache" + emptyDir = {} }, { - name = "RUNNERS_ADDRESS" - value = "runners:50051" + name = "${app_name}-run" + emptyDir = {} }, { - name = "NOTIFICATIONS_ADDRESS" - value = "notifications:50051" + name = "${app_name}-tmp" + emptyDir = {} }, { - name = "RECONCILIATION_INTERVAL" - value = "30s" + name = "${app_name}-conf" + emptyDir = {} }, ] - }) + } - organizations_values = yamlencode({ - fullnameOverride = "organizations" - image = { - repository = "ghcr.io/agynio/organizations" - tag = local.resolved_organizations_image_tag - pullPolicy = "IfNotPresent" - } - env = [ + web_app_extra_volume_mounts = { + for app_name in ["chat-app", "console-app", "tracing-app"] : app_name => [ { - name = "DATABASE_URL" - value = format("postgresql://organizations:%s@organizations-db:5432/organizations?sslmode=disable", var.organizations_db_password) + name = "${app_name}-cache" + mountPath = "/var/cache/nginx" }, - ] - }) - - identity_values = yamlencode({ - replicaCount = 1 - fullnameOverride = "identity" - image = { - repository = "ghcr.io/agynio/identity" - tag = local.resolved_identity_image_tag - pullPolicy = "IfNotPresent" - } - env = [ { - name = "DATABASE_URL" - value = format("postgresql://identity:%s@identity-db:5432/identity?sslmode=disable", var.identity_db_password) + name = "${app_name}-run" + mountPath = "/var/run" }, - ] - }) - - runners_values = yamlencode({ - replicaCount = 1 - fullnameOverride = "runners" - image = { - repository = "ghcr.io/agynio/runners" - tag = local.resolved_runners_image_tag - pullPolicy = "IfNotPresent" - } - env = [ { - name = "DATABASE_URL" - value = format("postgresql://runners:%s@runners-db:5432/runners?sslmode=disable", var.runners_db_password) + name = "${app_name}-tmp" + mountPath = "/tmp" }, - ] - }) - - apps_values = yamlencode({ - replicaCount = 1 - fullnameOverride = "apps" - image = { - repository = "ghcr.io/agynio/apps" - tag = local.resolved_apps_image_tag - pullPolicy = "IfNotPresent" - } - env = [ { - name = "DATABASE_URL" - value = format("postgresql://apps:%s@apps-db:5432/apps?sslmode=disable", var.apps_db_password) + name = "${app_name}-conf" + mountPath = "/etc/nginx/conf.d" }, ] - }) + } - agents_orchestrator_values = yamlencode({ - replicaCount = 1 - fullnameOverride = "agents-orchestrator" - service = { - enabled = false - } - image = { - repository = "ghcr.io/agynio/agents-orchestrator" - tag = local.resolved_agents_orchestrator_image_tag - pullPolicy = "IfNotPresent" + platform_values = yamlencode({ + validation = { + requireExistingSecrets = false + } + platform = { + database = { + mode = "external" + existingSecret = local.platform_database_secret_name + existingSecretKeyPattern = "{{ .service }}" + } + oidc = { + issuerUrl = var.oidc_issuer_url + clientId = var.oidc_client_id + } + } + openfga = { + apiUrl = local.openfga_api_url_internal + storeId = module.openfga_authorization.store_id + modelId = module.openfga_authorization.model_id + } + s3 = { + existingSecret = local.files_s3_secret_name + accessKeyKey = "access-key" + secretKeyKey = "secret-key" + endpoint = "minio.minio.svc.cluster.local:9000" + bucket = var.minio_bucket_name + region = "us-east-1" + useSSL = false + forcePathStyle = false + } + gateway = { + fullnameOverride = "gateway" + replicaCount = 1 + image = { + tag = local.resolved_gateway_image_tag + } + gateway = { + oidcIssuerUrl = var.oidc_issuer_url + oidcClientId = var.oidc_client_id + clusterAdminIdentityId = local.cluster_admin_identity_id + usersGrpcTarget = "users:50051" + organizationsGrpcTarget = "organizations:50051" + } + env = [ + { + name = "ZITI_ENABLED" + value = "true" + }, + { + name = "CLUSTER_ADMIN_TOKEN" + valueFrom = { + secretKeyRef = { + name = "agyn-cluster-admin" + key = "token" + } + } + }, + ] } - env = [ - { - name = "DATABASE_URL" - value = format("postgresql://orchestrator:%s@agents-orchestrator-db:5432/orchestrator?sslmode=disable", var.agents_orchestrator_db_password) - }, - { - name = "POLL_INTERVAL" - value = "5s" - }, - { - name = "IDLE_TIMEOUT" - value = "30s" - }, - { - name = "ZITI_ENABLED" - value = "true" - }, - { - name = "ZITI_SIDECAR_IMAGE" - value = "openziti/ziti-tunnel:2.0.0-pre8" - }, - { - name = "RUNNER_ADDRESS" - value = "k8s-runner:50051" - }, - { - name = "RUNNERS_ADDRESS" - value = "runners:50051" + agents = { + fullnameOverride = "agents" + image = { + tag = local.resolved_agents_image_tag } - ] - }) - - authorization_values = yamlencode({ - fullnameOverride = "authorization" - image = { - repository = "ghcr.io/agynio/authorization" - tag = local.resolved_authorization_image_tag + env = [local.database_url_env_refs["agents"]] } - env = [ - { - name = "GRPC_ADDRESS" - value = ":50051" - }, - { - name = "OPENFGA_API_URL" - value = local.openfga_api_url_internal - }, - { - name = "OPENFGA_STORE_ID" - value = module.openfga_authorization.store_id - }, - { - name = "OPENFGA_MODEL_ID" - value = module.openfga_authorization.model_id + "agents-orchestrator" = { + fullnameOverride = "agents-orchestrator" + service = { + enabled = false } - ] - securityContext = { - runAsUser = 100 - runAsGroup = 101 + image = { + tag = local.resolved_agents_orchestrator_image_tag + } + env = [ + local.database_url_env_refs["agents-orchestrator"], + { + name = "POLL_INTERVAL" + value = "5s" + }, + { + name = "IDLE_TIMEOUT" + value = "30s" + }, + { + name = "ZITI_ENABLED" + value = "true" + }, + { + name = "ZITI_SIDECAR_IMAGE" + value = "openziti/ziti-tunnel:2.0.0-pre8" + }, + { + name = "RUNNER_ADDRESS" + value = "k8s-runner:50051" + }, + { + name = "RUNNERS_ADDRESS" + value = "runners:50051" + }, + ] } - }) - - token_counting_values = yamlencode({ - replicaCount = 1 - fullnameOverride = "token-counting" - service = { - port = 50051 + threads = { + fullnameOverride = "threads" + replicaCount = 1 + service = { + ports = [ + { + name = "grpc" + port = 50051 + targetPort = "grpc" + protocol = "TCP" + } + ] + } + env = [ + { + name = "GRPC_ADDRESS" + value = ":50051" + }, + local.database_url_env_refs["threads"], + ] + securityContext = { + runAsUser = 100 + runAsGroup = 101 + } + image = { + tag = local.resolved_threads_image_tag + } } - image = { - repository = "ghcr.io/agynio/token-counting" - tag = local.resolved_token_counting_image_tag - pullPolicy = "IfNotPresent" + chat = { + fullnameOverride = "chat" + image = { + tag = local.resolved_chat_image_tag + } + env = [local.database_url_env_refs["chat"]] } - }) - - redis_values = yamlencode({ - fullnameOverride = "notifications-redis" - architecture = "standalone" - auth = { - enabled = false + users = { + fullnameOverride = "users" + image = { + tag = local.resolved_users_image_tag + } + env = [local.database_url_env_refs["users"]] } - master = { - persistence = { - enabled = false + organizations = { + fullnameOverride = "organizations" + image = { + tag = local.resolved_organizations_image_tag } + env = [local.database_url_env_refs["organizations"]] } - }) - - notifications_values = yamlencode({ - replicaCount = 1 - fullnameOverride = "notifications" - image = { - repository = "ghcr.io/agynio/notifications" - tag = local.resolved_notifications_image_tag - pullPolicy = "IfNotPresent" + identity = { + fullnameOverride = "identity" + replicaCount = 1 + image = { + tag = local.resolved_identity_image_tag + } + env = [local.database_url_env_refs["identity"]] } - containerPorts = [ - { - name = "grpc" - containerPort = 50051 - protocol = "TCP" + authorization = { + fullnameOverride = "authorization" + image = { + tag = local.resolved_authorization_image_tag } - ] - service = { - enabled = true - type = "ClusterIP" - ports = [ + env = [ { - name = "grpc" - port = 50051 - targetPort = "grpc" - protocol = "TCP" + name = "GRPC_ADDRESS" + value = ":50051" + }, + ] + extraEnvVarsCM = "agyn-platform-openfga" + securityContext = { + runAsUser = 100 + runAsGroup = 101 + } + } + apps = { + fullnameOverride = "apps" + replicaCount = 1 + image = { + tag = local.resolved_apps_image_tag + } + env = [local.database_url_env_refs["apps"]] + } + runners = { + fullnameOverride = "runners" + replicaCount = 1 + image = { + tag = local.resolved_runners_image_tag + } + env = [local.database_url_env_refs["runners"]] + } + "ziti-management" = { + fullnameOverride = "ziti-management" + image = { + tag = local.resolved_ziti_management_image_tag + } + updateStrategy = { + type = "Recreate" + } + securityContext = { + enabled = true + runAsNonRoot = true + runAsUser = 100 + runAsGroup = 101 + readOnlyRootFilesystem = true + allowPrivilegeEscalation = false + capabilities = { + drop = ["ALL"] } + seccompProfile = { + type = "RuntimeDefault" + } + } + persistence = { + enabled = true + accessMode = "ReadWriteOnce" + size = "10Mi" + } + configMounts = [ + { + name = "ziti-enrollment" + sourceName = "ziti-management-enrollment" + type = "secret" + mountPath = "/etc/ziti-enrollment" + readOnly = true + }, + ] + env = [ + local.database_url_env_refs["ziti-management"], + { + name = "ZITI_CONTROLLER_URL" + value = format("https://ziti-mgmt.%s:%d/edge/management/v1", local.base_domain, local.ingress_port) + }, + { + name = "ZITI_CERT_FILE" + value = "/var/lib/ziti/tls.crt" + }, + { + name = "ZITI_KEY_FILE" + value = "/var/lib/ziti/tls.key" + }, + { + name = "ZITI_CA_FILE" + value = "/var/lib/ziti/ca.crt" + }, + { + name = "ZITI_ENROLLMENT_JWT_FILE" + value = "/etc/ziti-enrollment/enrollmentJwt" + }, + { + name = "ZITI_IDENTITY_NAME_RESOLVE" + value = "true" + }, ] } - env = [ - { - name = "GRPC_ADDR" - value = "0.0.0.0:50051" - }, - { - name = "REDIS_ADDR" - value = var.notifications_redis_addr - }, - { - name = "REDIS_DB" - value = "0" - }, - { - name = "REDIS_CHANNEL" - value = "notifications.v1" - }, - { - name = "LOG_LEVEL" - value = "info" + expose = { + fullnameOverride = "expose" + image = { + tag = local.resolved_expose_image_tag } - ] - }) - - files_values = yamlencode({ - replicaCount = 1 - fullnameOverride = "files" - image = { - repository = "ghcr.io/agynio/files" - tag = local.resolved_files_image_tag - pullPolicy = "IfNotPresent" + env = [ + local.database_url_env_refs["expose"], + { + name = "ZITI_MANAGEMENT_ADDRESS" + value = "ziti-management:50051" + }, + { + name = "RUNNERS_ADDRESS" + value = "runners:50051" + }, + { + name = "NOTIFICATIONS_ADDRESS" + value = "notifications:50051" + }, + { + name = "RECONCILIATION_INTERVAL" + value = "30s" + }, + ] } - securityContext = { - enabled = true - runAsNonRoot = true - runAsUser = 65532 - runAsGroup = 65532 - readOnlyRootFilesystem = true - allowPrivilegeEscalation = false - capabilities = { - drop = ["ALL"] + secrets = { + fullnameOverride = "secrets" + service = { + port = 50051 + } + database = { + existingSecret = { + name = "agyn-platform-database-urls" + key = "secrets" + } + } + image = { + tag = local.resolved_secrets_image_tag } - seccompProfile = { - type = "RuntimeDefault" + secrets = { + encryptionKeyFile = "/etc/secrets-encryption/encryptionKey" + encryptionKeySecretName = "secrets-encryption-key" } } - containerPorts = [ - { - name = "grpc" - containerPort = 50051 - protocol = "TCP" + llm = { + fullnameOverride = "llm" + image = { + tag = local.resolved_llm_image_tag + } + securityContext = { + enabled = true + runAsNonRoot = true + runAsUser = 65532 + runAsGroup = 65532 + readOnlyRootFilesystem = true + allowPrivilegeEscalation = false + capabilities = { + drop = ["ALL"] + } + seccompProfile = { + type = "RuntimeDefault" + } } - ] - service = { - enabled = true - type = "ClusterIP" - ports = [ + containerPorts = [ { - name = "grpc" - port = 50051 - targetPort = "grpc" - protocol = "TCP" + name = "grpc" + containerPort = 50051 + protocol = "TCP" } ] + service = { + enabled = true + type = "ClusterIP" + ports = [ + { + name = "grpc" + port = 50051 + targetPort = "grpc" + protocol = "TCP" + } + ] + } + livenessProbe = { + enabled = true + grpc = { + port = 50051 + } + } + readinessProbe = { + enabled = true + grpc = { + port = 50051 + } + } + llm = { + databaseUrl = { + existingSecret = "agyn-platform-database-urls" + existingSecretKey = "llm" + } + } } - livenessProbe = { - enabled = true - grpc = { + "llm-proxy" = { + fullnameOverride = "llm-proxy" + image = { + tag = local.resolved_llm_proxy_image_tag + } + securityContext = { + enabled = true + runAsNonRoot = true + runAsUser = 65532 + runAsGroup = 65532 + readOnlyRootFilesystem = true + allowPrivilegeEscalation = false + capabilities = { + drop = ["ALL"] + } + seccompProfile = { + type = "RuntimeDefault" + } + } + env = [ + { + name = "ZITI_ENABLED" + value = "true" + }, + ] + } + "token-counting" = { + fullnameOverride = "token-counting" + service = { port = 50051 } + image = { + tag = local.resolved_token_counting_image_tag + } } - readinessProbe = { - enabled = true - grpc = { + tracing = { + fullnameOverride = "tracing" + replicaCount = 1 + service = { port = 50051 } + extraEnvVars = [ + local.database_url_env_refs["tracing"], + { + name = "ZITI_ENABLED" + value = "true" + }, + ] + image = { + tag = local.resolved_tracing_image_tag + } } - files = { - databaseUrl = { - value = format("postgresql://files:%s@files-db:5432/files?sslmode=disable", var.files_db_password) - } - urlExpiry = "1h" - s3 = { - endpoint = "minio.minio.svc.cluster.local:9000" - bucket = var.minio_bucket_name - region = "us-east-1" - useSSL = false - accessKey = { - value = var.minio_root_user - } - secretKey = { - value = var.minio_root_password + notifications = { + fullnameOverride = "notifications" + replicaCount = 1 + redis = { + enabled = true + externalAddress = "notifications-redis-master.${var.platform_namespace}.svc.cluster.local:6379" + } + image = { + tag = local.resolved_notifications_image_tag + } + containerPorts = [ + { + name = "grpc" + containerPort = 50051 + protocol = "TCP" } + ] + service = { + enabled = true + type = "ClusterIP" + ports = [ + { + name = "grpc" + port = 50051 + targetPort = "grpc" + protocol = "TCP" + } + ] } + env = [ + { + name = "GRPC_ADDR" + value = "0.0.0.0:50051" + }, + { + name = "REDIS_ADDR" + value = "notifications-redis-master.${var.platform_namespace}.svc.cluster.local:6379" + }, + { + name = "REDIS_DB" + value = "0" + }, + { + name = "REDIS_CHANNEL" + value = "notifications.v1" + }, + { + name = "LOG_LEVEL" + value = "info" + }, + ] } - }) - - media_proxy_values = yamlencode({ - replicaCount = 1 - fullnameOverride = "media-proxy" - image = { - repository = "ghcr.io/agynio/media-proxy" - tag = local.resolved_media_proxy_image_tag - pullPolicy = "IfNotPresent" - } - containerPorts = [ - { - name = "http" - containerPort = 8080 - protocol = "TCP" + "notifications-redis" = local.notifications_redis_values + files = { + fullnameOverride = "files" + replicaCount = 1 + image = { + tag = local.resolved_files_image_tag + } + securityContext = { + enabled = true + runAsNonRoot = true + runAsUser = 65532 + runAsGroup = 65532 + readOnlyRootFilesystem = true + allowPrivilegeEscalation = false + capabilities = { + drop = ["ALL"] + } + seccompProfile = { + type = "RuntimeDefault" + } } - ] - service = { - enabled = true - type = "ClusterIP" - ports = [ + containerPorts = [ { - name = "http" - port = 8080 - targetPort = "http" - protocol = "TCP" + name = "grpc" + containerPort = 50051 + protocol = "TCP" } ] - } - mediaProxy = { - listenAddr = ":8080" - oidcIssuerUrl = var.oidc_issuer_url - oidcClientId = var.oidc_client_id - usersGrpcTarget = "users:50051" - filesGrpcTarget = "files:50051" - corsAllowedOrigin = format("https://chat.%s:%d", local.base_domain, local.ingress_port) - } - }) - - llm_values = yamlencode({ - fullnameOverride = "llm" - image = { - repository = "ghcr.io/agynio/llm" - tag = local.resolved_llm_image_tag - pullPolicy = "IfNotPresent" - } - securityContext = { - enabled = true - runAsNonRoot = true - runAsUser = 65532 - runAsGroup = 65532 - readOnlyRootFilesystem = true - allowPrivilegeEscalation = false - capabilities = { - drop = ["ALL"] + service = { + enabled = true + type = "ClusterIP" + ports = [ + { + name = "grpc" + port = 50051 + targetPort = "grpc" + protocol = "TCP" + } + ] + } + livenessProbe = { + enabled = true + grpc = { + port = 50051 + } } - seccompProfile = { - type = "RuntimeDefault" + readinessProbe = { + enabled = true + grpc = { + port = 50051 + } + } + files = { + databaseUrl = { + existingSecret = "agyn-platform-database-urls" + existingSecretKey = "files" + } + urlExpiry = "1h" + s3 = { + endpoint = "minio.minio.svc.cluster.local:9000" + bucket = var.minio_bucket_name + region = "us-east-1" + useSSL = false + accessKey = { + existingSecret = "agyn-files-s3" + existingSecretKey = "access-key" + } + secretKey = { + existingSecret = "agyn-files-s3" + existingSecretKey = "secret-key" + } + } } } - containerPorts = [ - { - name = "grpc" - containerPort = 50051 - protocol = "TCP" + "media-proxy" = { + fullnameOverride = "media-proxy" + replicaCount = 1 + image = { + tag = local.resolved_media_proxy_image_tag } - ] - service = { - enabled = true - type = "ClusterIP" - ports = [ + containerPorts = [ { - name = "grpc" - port = 50051 - targetPort = "grpc" - protocol = "TCP" + name = "http" + containerPort = 8080 + protocol = "TCP" } ] - } - livenessProbe = { - enabled = true - grpc = { - port = 50051 + service = { + enabled = true + type = "ClusterIP" + ports = [ + { + name = "http" + port = 8080 + targetPort = "http" + protocol = "TCP" + } + ] } + mediaProxy = { + listenAddr = ":8080" + oidcIssuerUrl = var.oidc_issuer_url + oidcClientId = var.oidc_client_id + usersGrpcTarget = "users:50051" + filesGrpcTarget = "files:50051" + corsAllowedOrigin = format("https://chat.%s:%d", local.base_domain, local.ingress_port) + } + } + "chat-app" = { + fullnameOverride = "chat-app" + replicaCount = 1 + image = { + tag = local.resolved_chat_app_image_tag + } + service = local.web_app_service_values + extraVolumes = local.web_app_extra_volumes["chat-app"] + extraVolumeMounts = local.web_app_extra_volume_mounts["chat-app"] + env = [ + { + name = "OIDC_AUTHORITY" + value = var.oidc_issuer_url + }, + { + name = "OIDC_CLIENT_ID" + value = var.oidc_client_id + }, + { + name = "OIDC_REDIRECT_URI" + value = format("https://chat.%s:%d/callback", local.base_domain, local.ingress_port) + }, + { + name = "OIDC_POST_LOGOUT_REDIRECT_URI" + value = format("https://chat.%s:%d", local.base_domain, local.ingress_port) + }, + { + name = "OIDC_SCOPE" + value = "openid profile email offline_access" + }, + { + name = "API_BASE_URL" + value = "/api" + }, + { + name = "MEDIA_PROXY_URL" + value = format("https://media.%s:%d", local.base_domain, local.ingress_port) + }, + ] } - readinessProbe = { - enabled = true - grpc = { - port = 50051 + "console-app" = { + fullnameOverride = "console-app" + replicaCount = 1 + image = { + tag = local.resolved_console_app_image_tag } + service = local.web_app_service_values + extraVolumes = local.web_app_extra_volumes["console-app"] + extraVolumeMounts = local.web_app_extra_volume_mounts["console-app"] + env = [ + { + name = "OIDC_AUTHORITY" + value = var.oidc_issuer_url + }, + { + name = "OIDC_CLIENT_ID" + value = var.console_app_oidc_client_id + }, + { + name = "OIDC_SCOPE" + value = "openid profile email offline_access" + }, + { + name = "API_BASE_URL" + value = "/api" + }, + ] } - llm = { - databaseUrl = { - value = format("postgresql://llm:%s@llm-db:5432/llm?sslmode=disable", var.llm_db_password) + "tracing-app" = { + fullnameOverride = "tracing-app" + replicaCount = 1 + image = { + tag = local.resolved_tracing_app_image_tag } + service = local.web_app_service_values + extraVolumes = local.web_app_extra_volumes["tracing-app"] + extraVolumeMounts = local.web_app_extra_volume_mounts["tracing-app"] + env = [ + { + name = "API_BASE_URL" + value = "/api" + }, + { + name = "OIDC_AUTHORITY" + value = var.oidc_issuer_url + }, + { + name = "OIDC_CLIENT_ID" + value = local.resolved_tracing_app_oidc_client_id + }, + { + name = "OIDC_SCOPE" + value = "openid profile email offline_access" + }, + ] + } + registryMirror = { + enabled = false + } + ncps = { + enabled = false } }) ncps_values = yamlencode({ @@ -1211,244 +1331,7 @@ locals { enabled = false } }) - - chat_app_values = yamlencode({ - replicaCount = 1 - fullnameOverride = "chat-app" - image = { - repository = "ghcr.io/agynio/chat-app" - tag = local.resolved_chat_app_image_tag - pullPolicy = "IfNotPresent" - } - service = { - type = "ClusterIP" - ports = [ - { - name = "http" - port = 3000 - targetPort = "http" - protocol = "TCP" - } - ] - } - extraVolumes = [ - { - name = "chat-app-cache" - emptyDir = {} - }, - { - name = "chat-app-run" - emptyDir = {} - }, - { - name = "chat-app-tmp" - emptyDir = {} - }, - { - name = "chat-app-conf" - emptyDir = {} - } - ] - extraVolumeMounts = [ - { - name = "chat-app-cache" - mountPath = "/var/cache/nginx" - }, - { - name = "chat-app-run" - mountPath = "/var/run" - }, - { - name = "chat-app-tmp" - mountPath = "/tmp" - }, - { - name = "chat-app-conf" - mountPath = "/etc/nginx/conf.d" - } - ] - env = [ - { - name = "OIDC_AUTHORITY" - value = var.oidc_issuer_url - }, - { - name = "OIDC_CLIENT_ID" - value = var.oidc_client_id - }, - { - name = "OIDC_REDIRECT_URI" - value = format("https://chat.%s:%d/callback", local.base_domain, local.ingress_port) - }, - { - name = "OIDC_POST_LOGOUT_REDIRECT_URI" - value = format("https://chat.%s:%d", local.base_domain, local.ingress_port) - }, - { - name = "OIDC_SCOPE" - value = "openid profile email offline_access" - }, - { - name = "API_BASE_URL" - value = "/api" - }, - { - name = "MEDIA_PROXY_URL" - value = format("https://media.%s:%d", local.base_domain, local.ingress_port) - } - ] - }) - - console_app_values = yamlencode({ - replicaCount = 1 - fullnameOverride = "console-app" - image = { - repository = "ghcr.io/agynio/console-app" - tag = local.resolved_console_app_image_tag - pullPolicy = "IfNotPresent" - } - service = { - type = "ClusterIP" - ports = [ - { - name = "http" - port = 3000 - targetPort = "http" - protocol = "TCP" - } - ] - } - extraVolumes = [ - { - name = "console-app-cache" - emptyDir = {} - }, - { - name = "console-app-run" - emptyDir = {} - }, - { - name = "console-app-tmp" - emptyDir = {} - }, - { - name = "console-app-conf" - emptyDir = {} - } - ] - extraVolumeMounts = [ - { - name = "console-app-cache" - mountPath = "/var/cache/nginx" - }, - { - name = "console-app-run" - mountPath = "/var/run" - }, - { - name = "console-app-tmp" - mountPath = "/tmp" - }, - { - name = "console-app-conf" - mountPath = "/etc/nginx/conf.d" - } - ] - env = [ - { - name = "OIDC_AUTHORITY" - value = var.oidc_issuer_url - }, - { - name = "OIDC_CLIENT_ID" - value = var.console_app_oidc_client_id - }, - { - name = "OIDC_SCOPE" - value = "openid profile email offline_access" - }, - { - name = "API_BASE_URL" - value = "/api" - } - ] - }) - - tracing_app_values = yamlencode({ - replicaCount = 1 - fullnameOverride = "tracing-app" - image = { - repository = "ghcr.io/agynio/tracing-app" - tag = local.resolved_tracing_app_image_tag - pullPolicy = "IfNotPresent" - } - service = { - type = "ClusterIP" - ports = [ - { - name = "http" - port = 3000 - targetPort = "http" - protocol = "TCP" - } - ] - } - extraVolumes = [ - { - name = "tracing-app-cache" - emptyDir = {} - }, - { - name = "tracing-app-run" - emptyDir = {} - }, - { - name = "tracing-app-tmp" - emptyDir = {} - }, - { - name = "tracing-app-conf" - emptyDir = {} - } - ] - extraVolumeMounts = [ - { - name = "tracing-app-cache" - mountPath = "/var/cache/nginx" - }, - { - name = "tracing-app-run" - mountPath = "/var/run" - }, - { - name = "tracing-app-tmp" - mountPath = "/tmp" - }, - { - name = "tracing-app-conf" - mountPath = "/etc/nginx/conf.d" - } - ] - env = [ - { - name = "API_BASE_URL" - value = "/api" - }, - { - name = "OIDC_AUTHORITY" - value = var.oidc_issuer_url - }, - { - name = "OIDC_CLIENT_ID" - value = local.resolved_tracing_app_oidc_client_id - }, - { - name = "OIDC_SCOPE" - value = "openid profile email offline_access" - } - ] - }) -} +} # NOTE: The module ref (v0.5.2) must be updated in lockstep with # var.authorization_chart_version to ensure the provisioned FGA model @@ -1513,6 +1396,48 @@ resource "kubernetes_secret_v1" "secrets_encryption_key" { } } +resource "kubernetes_secret_v1" "platform_database_urls" { + metadata { + name = local.platform_database_secret_name + namespace = kubernetes_namespace.platform.metadata[0].name + } + + type = "Opaque" + + data = local.platform_database_urls + + depends_on = [kubernetes_namespace.platform] +} + +resource "kubernetes_secret_v1" "files_s3" { + metadata { + name = local.files_s3_secret_name + namespace = kubernetes_namespace.platform.metadata[0].name + } + + type = "Opaque" + + data = { + access-key = var.minio_root_user + secret-key = var.minio_root_password + } + + depends_on = [kubernetes_namespace.platform] +} + +resource "kubernetes_secret_v1" "cluster_admin" { + metadata { + name = "agyn-cluster-admin" + namespace = kubernetes_namespace.platform.metadata[0].name + } + + type = "Opaque" + + data = { + token = random_password.cluster_admin_token.result + } +} + resource "kubernetes_manifest" "virtualservice_chat_app" { manifest = { "apiVersion" = "networking.istio.io/v1beta1" @@ -1544,7 +1469,7 @@ resource "kubernetes_manifest" "virtualservice_chat_app" { "route" = [ { "destination" = { - "host" = "gateway-gateway.platform.svc.cluster.local" + "host" = "gateway.platform.svc.cluster.local" "port" = { "number" = 8080 } @@ -1563,7 +1488,7 @@ resource "kubernetes_manifest" "virtualservice_chat_app" { "route" = [ { "destination" = { - "host" = "gateway-gateway.platform.svc.cluster.local" + "host" = "gateway.platform.svc.cluster.local" "port" = { "number" = 8080 } @@ -1635,7 +1560,7 @@ resource "kubernetes_manifest" "virtualservice_console_app" { "route" = [ { "destination" = { - "host" = "gateway-gateway.platform.svc.cluster.local" + "host" = "gateway.platform.svc.cluster.local" "port" = { "number" = 8080 } @@ -1654,7 +1579,7 @@ resource "kubernetes_manifest" "virtualservice_console_app" { "route" = [ { "destination" = { - "host" = "gateway-gateway.platform.svc.cluster.local" + "host" = "gateway.platform.svc.cluster.local" "port" = { "number" = 8080 } @@ -1726,7 +1651,7 @@ resource "kubernetes_manifest" "virtualservice_tracing_app" { "route" = [ { "destination" = { - "host" = "gateway-gateway.platform.svc.cluster.local" + "host" = "gateway.platform.svc.cluster.local" "port" = { "number" = 8080 } @@ -1745,7 +1670,7 @@ resource "kubernetes_manifest" "virtualservice_tracing_app" { "route" = [ { "destination" = { - "host" = "gateway-gateway.platform.svc.cluster.local" + "host" = "gateway.platform.svc.cluster.local" "port" = { "number" = 8080 } @@ -1809,7 +1734,7 @@ resource "kubernetes_manifest" "virtualservice_gateway" { "route" = [ { "destination" = { - "host" = "gateway-gateway.platform.svc.cluster.local" + "host" = "gateway.platform.svc.cluster.local" "port" = { "number" = 8080 } @@ -1899,7 +1824,7 @@ resource "kubernetes_manifest" "virtualservice_llm_proxy" { "route" = [ { "destination" = { - "host" = "llm-proxy-llm-proxy.platform.svc.cluster.local" + "host" = "llm-proxy.platform.svc.cluster.local" "port" = { "number" = 8080 } @@ -1926,1361 +1851,142 @@ resource "kubernetes_service_v1" "files_db" { name = "files-db" namespace = kubernetes_namespace.platform.metadata[0].name labels = { - "app.kubernetes.io/name" = "files-db" - } - } - - spec { - selector = { - "app.kubernetes.io/name" = "files-db" - } - - port { - name = "postgres" - port = 5432 - target_port = 5432 - protocol = "TCP" - } - } -} - -resource "kubernetes_stateful_set_v1" "files_db" { - metadata { - name = "files-db" - namespace = kubernetes_namespace.platform.metadata[0].name - labels = { - "app.kubernetes.io/name" = "files-db" - } - } - - spec { - service_name = kubernetes_service_v1.files_db.metadata[0].name - replicas = 1 - - selector { - match_labels = { - "app.kubernetes.io/name" = "files-db" - } - } - - template { - metadata { - labels = { - "app.kubernetes.io/name" = "files-db" - } - } - - spec { - termination_grace_period_seconds = 30 - - container { - name = "postgres" - image = local.postgres_image - image_pull_policy = "IfNotPresent" - env { - name = "POSTGRES_DB" - value = "files" - } - env { - name = "POSTGRES_USER" - value = "files" - } - env { - name = "POSTGRES_PASSWORD" - value = var.files_db_password - } - env { - name = "PGDATA" - value = "/var/lib/postgresql/data/pgdata" - } - - port { - name = "postgres" - container_port = 5432 - } - - readiness_probe { - exec { - command = ["pg_isready", "-U", "files", "-d", "files"] - } - initial_delay_seconds = 5 - period_seconds = 10 - } - - liveness_probe { - exec { - command = ["pg_isready", "-U", "files", "-d", "files"] - } - initial_delay_seconds = 30 - period_seconds = 20 - } - - volume_mount { - name = "data" - mount_path = "/var/lib/postgresql/data" - } - } - } - } - - volume_claim_template { - metadata { - name = "data" - } - - spec { - access_modes = ["ReadWriteOnce"] - - resources { - requests = { - storage = var.files_db_pvc_size - } - } - } - } - } -} -resource "argocd_repository" "twuni_docker_registry" { - repo = local.registry_mirror_repo_url - type = "git" -} - -resource "argocd_repository" "bitnami_repo" { - repo = "https://charts.bitnami.com/bitnami" - type = "helm" -} -resource "argocd_repository" "ghcr" { - repo = "ghcr.io" - type = "helm" - enable_oci = true - username = trimspace(var.ghcr_username) != "" ? var.ghcr_username : null - password = trimspace(var.ghcr_token) != "" ? var.ghcr_token : null -} - -resource "argocd_application" "platform_db" { - depends_on = [argocd_repository.ghcr] - wait = true - - metadata { - name = "platform-db" - namespace = "argocd" - annotations = { - "argocd.argoproj.io/sync-wave" = "5" - } - } - - spec { - project = "default" - - source { - repo_url = local.postgres_chart_repo_host - chart = local.postgres_chart_name - target_revision = var.postgres_chart_version - - helm { - values = local.platform_db_values - } - } - - destination { - server = var.destination_server - namespace = var.platform_namespace - } - - sync_policy { - # DB apps always use automated sync with prune disabled for stateful safety, - # independent of var.argocd_automated_sync_enabled. - automated { - prune = false - self_heal = true - allow_empty = false - } - - sync_options = local.postgres_sync_options - } - } - - timeouts { - create = "5m" - update = "5m" - delete = "5m" - } -} - -resource "argocd_application" "threads_db" { - depends_on = [argocd_repository.ghcr] - wait = true - - metadata { - name = "threads-db" - namespace = "argocd" - annotations = { - "argocd.argoproj.io/sync-wave" = "7" - } - } - - spec { - project = "default" - - source { - repo_url = local.postgres_chart_repo_host - chart = local.postgres_chart_name - target_revision = var.postgres_chart_version - - helm { - values = local.threads_db_values - } - } - - destination { - server = var.destination_server - namespace = var.platform_namespace - } - - sync_policy { - # DB apps always use automated sync with prune disabled for stateful safety, - # independent of var.argocd_automated_sync_enabled. - automated { - prune = false - self_heal = true - allow_empty = false - } - - sync_options = local.postgres_sync_options - } - } - - timeouts { - create = "5m" - update = "5m" - delete = "5m" - } -} - -resource "argocd_application" "metering_db" { - depends_on = [argocd_repository.ghcr] - wait = true - - metadata { - name = "metering-db" - namespace = "argocd" - annotations = { - "argocd.argoproj.io/sync-wave" = "7" - } - } - - spec { - project = "default" - - source { - repo_url = local.postgres_chart_repo_host - chart = local.postgres_chart_name - target_revision = var.postgres_chart_version - - helm { - values = local.metering_db_values - } - } - - destination { - server = var.destination_server - namespace = var.platform_namespace - } - - sync_policy { - # DB apps always use automated sync with prune disabled for stateful safety, - # independent of var.argocd_automated_sync_enabled. - automated { - prune = false - self_heal = true - allow_empty = false - } - - sync_options = local.postgres_sync_options - } - } - - timeouts { - create = "5m" - update = "5m" - delete = "5m" - } -} - -resource "argocd_application" "chat_db" { - depends_on = [argocd_repository.ghcr] - wait = true - - metadata { - name = "chat-db" - namespace = "argocd" - annotations = { - "argocd.argoproj.io/sync-wave" = "7" - } - } - - spec { - project = "default" - - source { - repo_url = local.postgres_chart_repo_host - chart = local.postgres_chart_name - target_revision = var.postgres_chart_version - - helm { - values = local.chat_db_values - } - } - - destination { - server = var.destination_server - namespace = var.platform_namespace - } - - sync_policy { - # DB apps always use automated sync with prune disabled for stateful safety, - # independent of var.argocd_automated_sync_enabled. - automated { - prune = false - self_heal = true - allow_empty = false - } - - sync_options = local.postgres_sync_options - } - } - - timeouts { - create = "5m" - update = "5m" - delete = "5m" - } -} - -resource "argocd_application" "tracing_db" { - depends_on = [argocd_repository.ghcr] - wait = true - - metadata { - name = "tracing-db" - namespace = "argocd" - annotations = { - "argocd.argoproj.io/sync-wave" = "7" - } - } - - spec { - project = "default" - - source { - repo_url = local.postgres_chart_repo_host - chart = local.postgres_chart_name - target_revision = var.postgres_chart_version - - helm { - values = local.tracing_db_values - } - } - - destination { - server = var.destination_server - namespace = var.platform_namespace - } - - sync_policy { - # DB apps always use automated sync with prune disabled for stateful safety, - # independent of var.argocd_automated_sync_enabled. - automated { - prune = false - self_heal = true - allow_empty = false - } - - sync_options = local.postgres_sync_options - } - } - - timeouts { - create = "5m" - update = "5m" - delete = "5m" - } -} - -resource "argocd_application" "secrets_db" { - depends_on = [argocd_repository.ghcr] - wait = true - - metadata { - name = "secrets-db" - namespace = "argocd" - annotations = { - "argocd.argoproj.io/sync-wave" = "7" - } - } - - spec { - project = "default" - - source { - repo_url = local.postgres_chart_repo_host - chart = local.postgres_chart_name - target_revision = var.postgres_chart_version - - helm { - values = local.secrets_db_values - } - } - - destination { - server = var.destination_server - namespace = var.platform_namespace - } - - sync_policy { - # DB apps always use automated sync with prune disabled for stateful safety, - # independent of var.argocd_automated_sync_enabled. - automated { - prune = false - self_heal = true - allow_empty = false - } - - sync_options = local.postgres_sync_options - } - } - - timeouts { - create = "5m" - update = "5m" - delete = "5m" - } -} - -resource "argocd_application" "llm_db" { - depends_on = [argocd_repository.ghcr] - wait = true - - metadata { - name = "llm-db" - namespace = "argocd" - annotations = { - "argocd.argoproj.io/sync-wave" = "8" - } - } - - spec { - project = "default" - - source { - repo_url = local.postgres_chart_repo_host - chart = local.postgres_chart_name - target_revision = var.postgres_chart_version - - helm { - values = local.llm_db_values - } - } - - destination { - server = var.destination_server - namespace = var.platform_namespace - } - - sync_policy { - # DB apps always use automated sync with prune disabled for stateful safety, - # independent of var.argocd_automated_sync_enabled. - automated { - prune = false - self_heal = true - allow_empty = false - } - - sync_options = local.postgres_sync_options - } - } - - timeouts { - create = "5m" - update = "5m" - delete = "5m" - } -} - -resource "argocd_application" "agents_db" { - depends_on = [argocd_repository.ghcr] - wait = true - - metadata { - name = "agents-db" - namespace = "argocd" - annotations = { - "argocd.argoproj.io/sync-wave" = "8" - } - } - - spec { - project = "default" - - source { - repo_url = local.postgres_chart_repo_host - chart = local.postgres_chart_name - target_revision = var.postgres_chart_version - - helm { - values = local.agents_db_values - } - } - - destination { - server = var.destination_server - namespace = var.platform_namespace - } - - sync_policy { - # DB apps always use automated sync with prune disabled for stateful safety, - # independent of var.argocd_automated_sync_enabled. - automated { - prune = false - self_heal = true - allow_empty = false - } - - sync_options = local.postgres_sync_options - } - } - - timeouts { - create = "5m" - update = "5m" - delete = "5m" - } -} - -resource "argocd_application" "ziti_management_db" { - depends_on = [argocd_repository.ghcr] - wait = true - - metadata { - name = "ziti-management-db" - namespace = "argocd" - annotations = { - "argocd.argoproj.io/sync-wave" = "8" - } - } - - spec { - project = "default" - - source { - repo_url = local.postgres_chart_repo_host - chart = local.postgres_chart_name - target_revision = var.postgres_chart_version - - helm { - values = local.ziti_management_db_values - } - } - - destination { - server = var.destination_server - namespace = var.platform_namespace - } - - sync_policy { - # DB apps always use automated sync with prune disabled for stateful safety, - # independent of var.argocd_automated_sync_enabled. - automated { - prune = false - self_heal = true - allow_empty = false - } - - sync_options = local.postgres_sync_options - } - } - - timeouts { - create = "5m" - update = "5m" - delete = "5m" - } -} - -resource "argocd_application" "users_db" { - depends_on = [argocd_repository.ghcr] - wait = true - - metadata { - name = "users-db" - namespace = "argocd" - annotations = { - "argocd.argoproj.io/sync-wave" = "8" - } - } - - spec { - project = "default" - - source { - repo_url = local.postgres_chart_repo_host - chart = local.postgres_chart_name - target_revision = var.postgres_chart_version - - helm { - values = local.users_db_values - } - } - - destination { - server = var.destination_server - namespace = var.platform_namespace - } - - sync_policy { - # DB apps always use automated sync with prune disabled for stateful safety, - # independent of var.argocd_automated_sync_enabled. - automated { - prune = false - self_heal = true - allow_empty = false - } - - sync_options = local.postgres_sync_options - } - } - - timeouts { - create = "5m" - update = "5m" - delete = "5m" - } -} - -resource "argocd_application" "expose_db" { - depends_on = [argocd_repository.ghcr] - wait = true - - metadata { - name = "expose-db" - namespace = "argocd" - annotations = { - "argocd.argoproj.io/sync-wave" = "8" - } - } - - spec { - project = "default" - - source { - repo_url = local.postgres_chart_repo_host - chart = local.postgres_chart_name - target_revision = var.postgres_chart_version - - helm { - values = local.expose_db_values - } - } - - destination { - server = var.destination_server - namespace = var.platform_namespace - } - - sync_policy { - # DB apps always use automated sync with prune disabled for stateful safety, - # independent of var.argocd_automated_sync_enabled. - automated { - prune = false - self_heal = true - allow_empty = false - } - - sync_options = local.postgres_sync_options - } - } - - timeouts { - create = "5m" - update = "5m" - delete = "5m" - } -} - -resource "argocd_application" "organizations_db" { - depends_on = [argocd_repository.ghcr] - wait = true - - metadata { - name = "organizations-db" - namespace = "argocd" - annotations = { - "argocd.argoproj.io/sync-wave" = "8" - } - } - - spec { - project = "default" - - source { - repo_url = local.postgres_chart_repo_host - chart = local.postgres_chart_name - target_revision = var.postgres_chart_version - - helm { - values = local.organizations_db_values - } - } - - destination { - server = var.destination_server - namespace = var.platform_namespace - } - - sync_policy { - # DB apps always use automated sync with prune disabled for stateful safety, - # independent of var.argocd_automated_sync_enabled. - automated { - prune = false - self_heal = true - allow_empty = false - } - - sync_options = local.postgres_sync_options - } - } - - timeouts { - create = "5m" - update = "5m" - delete = "5m" - } -} - -resource "argocd_application" "agents_orchestrator_db" { - depends_on = [argocd_repository.ghcr] - wait = true - - metadata { - name = "agents-orchestrator-db" - namespace = "argocd" - annotations = { - "argocd.argoproj.io/sync-wave" = "8" - } - } - - spec { - project = "default" - - source { - repo_url = local.postgres_chart_repo_host - chart = local.postgres_chart_name - target_revision = var.postgres_chart_version - - helm { - values = local.agents_orchestrator_db_values - } - } - - destination { - server = var.destination_server - namespace = var.platform_namespace - } - - sync_policy { - # DB apps always use automated sync with prune disabled for stateful safety, - # independent of var.argocd_automated_sync_enabled. - automated { - prune = false - self_heal = true - allow_empty = false - } - - sync_options = local.postgres_sync_options - } - } - - timeouts { - create = "5m" - update = "5m" - delete = "5m" - } -} - -resource "argocd_application" "identity_db" { - depends_on = [argocd_repository.ghcr] - wait = true - - metadata { - name = "identity-db" - namespace = "argocd" - annotations = { - "argocd.argoproj.io/sync-wave" = "8" - } - } - - spec { - project = "default" - - source { - repo_url = local.postgres_chart_repo_host - chart = local.postgres_chart_name - target_revision = var.postgres_chart_version - - helm { - values = local.identity_db_values - } - } - - destination { - server = var.destination_server - namespace = var.platform_namespace - } - - sync_policy { - # DB apps always use automated sync with prune disabled for stateful safety, - # independent of var.argocd_automated_sync_enabled. - automated { - prune = false - self_heal = true - allow_empty = false - } - - sync_options = local.postgres_sync_options - } - } - - timeouts { - create = "5m" - update = "5m" - delete = "5m" - } -} - -resource "argocd_application" "runners_db" { - depends_on = [argocd_repository.ghcr] - wait = true - - metadata { - name = "runners-db" - namespace = "argocd" - annotations = { - "argocd.argoproj.io/sync-wave" = "8" - } - } - - spec { - project = "default" - - source { - repo_url = local.postgres_chart_repo_host - chart = local.postgres_chart_name - target_revision = var.postgres_chart_version - - helm { - values = local.runners_db_values - } - } - - destination { - server = var.destination_server - namespace = var.platform_namespace - } - - sync_policy { - # DB apps always use automated sync with prune disabled for stateful safety, - # independent of var.argocd_automated_sync_enabled. - automated { - prune = false - self_heal = true - allow_empty = false - } - - sync_options = local.postgres_sync_options - } - } - - timeouts { - create = "5m" - update = "5m" - delete = "5m" - } -} - -resource "argocd_application" "apps_db" { - depends_on = [argocd_repository.ghcr] - wait = true - - metadata { - name = "apps-db" - namespace = "argocd" - annotations = { - "argocd.argoproj.io/sync-wave" = "8" - } - } - - spec { - project = "default" - - source { - repo_url = local.postgres_chart_repo_host - chart = local.postgres_chart_name - target_revision = var.postgres_chart_version - - helm { - values = local.apps_db_values - } - } - - destination { - server = var.destination_server - namespace = var.platform_namespace - } - - sync_policy { - # DB apps always use automated sync with prune disabled for stateful safety, - # independent of var.argocd_automated_sync_enabled. - automated { - prune = false - self_heal = true - allow_empty = false - } - - sync_options = local.postgres_sync_options - } - } - - timeouts { - create = "5m" - update = "5m" - delete = "5m" - } -} - -resource "argocd_application" "registry_mirror" { - depends_on = [argocd_repository.twuni_docker_registry] - metadata { - name = "registry-mirror" - namespace = "argocd" - annotations = { - "argocd.argoproj.io/sync-wave" = "1" - } - } - - spec { - project = "default" - - source { - repo_url = local.registry_mirror_repo_url - target_revision = local.registry_mirror_chart_revision - path = local.registry_mirror_chart_path - - helm { - values = local.registry_mirror_values - } - } - - destination { - server = var.destination_server - namespace = var.platform_namespace - } - - sync_policy { - dynamic "automated" { - for_each = var.argocd_automated_sync_enabled ? [1] : [] - content { - prune = var.argocd_prune_enabled - self_heal = var.argocd_self_heal_enabled - allow_empty = false - } - } - - sync_options = local.default_sync_options - } - } -} - -resource "argocd_application" "ncps" { - depends_on = [argocd_repository.ghcr] - metadata { - name = "ncps" - namespace = "argocd" - annotations = { - "argocd.argoproj.io/sync-wave" = "15" - } - } - - spec { - project = "default" - - source { - repo_url = local.ncps_chart_repo_host - chart = local.ncps_chart_name - target_revision = local.ncps_chart_revision - - helm { - values = local.ncps_values - } - } - - destination { - server = var.destination_server - namespace = var.platform_namespace - } - - sync_policy { - dynamic "automated" { - for_each = var.argocd_automated_sync_enabled ? [1] : [] - content { - prune = var.argocd_prune_enabled - self_heal = var.argocd_self_heal_enabled - allow_empty = false - } - } - - sync_options = local.default_sync_options - } - } -} - -resource "argocd_application" "threads" { - depends_on = [ - argocd_repository.ghcr, - argocd_application.threads_db, - ] - metadata { - name = "threads" - namespace = "argocd" - annotations = { - "argocd.argoproj.io/sync-wave" = "16" - } - } - - spec { - project = "default" - - source { - repo_url = local.platform_chart_repo_host - chart = local.threads_chart_name - target_revision = var.threads_chart_version - - helm { - values = local.threads_values - } - } - - destination { - server = var.destination_server - namespace = var.platform_namespace - } - - sync_policy { - dynamic "automated" { - for_each = var.argocd_automated_sync_enabled ? [1] : [] - content { - prune = var.argocd_prune_enabled - self_heal = var.argocd_self_heal_enabled - allow_empty = false - } - } - - sync_options = local.default_sync_options - } - } -} - -resource "argocd_application" "metering" { - depends_on = [ - argocd_repository.ghcr, - argocd_application.metering_db, - ] - metadata { - name = "metering" - namespace = "argocd" - annotations = { - "argocd.argoproj.io/sync-wave" = "16" - } - } - - spec { - project = "default" - - source { - repo_url = local.platform_chart_repo_host - chart = local.metering_chart_name - target_revision = var.metering_chart_version - - helm { - values = local.metering_values - } - } - - destination { - server = var.destination_server - namespace = var.platform_namespace - } - - sync_policy { - dynamic "automated" { - for_each = var.argocd_automated_sync_enabled ? [1] : [] - content { - prune = var.argocd_prune_enabled - self_heal = var.argocd_self_heal_enabled - allow_empty = false - } - } - - sync_options = local.default_sync_options - } - } -} - -resource "argocd_application" "tracing" { - depends_on = [ - argocd_repository.ghcr, - argocd_application.tracing_db, - argocd_application.ziti_management, - ] - metadata { - name = "tracing" - namespace = "argocd" - annotations = { - "argocd.argoproj.io/sync-wave" = "16" - } - } - - spec { - project = "default" - - source { - repo_url = local.platform_chart_repo_host - chart = local.tracing_chart_name - target_revision = var.tracing_chart_version - - helm { - values = local.tracing_values - } - } - - destination { - server = var.destination_server - namespace = var.platform_namespace - } - - sync_policy { - dynamic "automated" { - for_each = var.argocd_automated_sync_enabled ? [1] : [] - content { - prune = var.argocd_prune_enabled - self_heal = var.argocd_self_heal_enabled - allow_empty = false - } - } - - sync_options = local.default_sync_options - } - } -} - -resource "argocd_application" "chat" { - depends_on = [ - argocd_repository.ghcr, - argocd_application.chat_db, - argocd_application.threads, - ] - metadata { - name = "chat" - namespace = "argocd" - annotations = { - "argocd.argoproj.io/sync-wave" = "17" - } - } - - spec { - project = "default" - - source { - repo_url = local.platform_chart_repo_host - chart = local.chat_chart_name - target_revision = var.chat_chart_version - - helm { - values = local.chat_values - } - } - - destination { - server = var.destination_server - namespace = var.platform_namespace - } - - sync_policy { - dynamic "automated" { - for_each = var.argocd_automated_sync_enabled ? [1] : [] - content { - prune = var.argocd_prune_enabled - self_heal = var.argocd_self_heal_enabled - allow_empty = false - } - } - - sync_options = local.default_sync_options - } - } -} - -resource "argocd_application" "secrets" { - depends_on = [ - argocd_repository.ghcr, - argocd_application.secrets_db, - ] - metadata { - name = "secrets" - namespace = "argocd" - annotations = { - "argocd.argoproj.io/sync-wave" = "16" - } - } - - spec { - project = "default" - - source { - repo_url = local.platform_chart_repo_host - chart = local.secrets_chart_name - target_revision = var.secrets_chart_version - - helm { - values = local.secrets_values - } - } - - destination { - server = var.destination_server - namespace = var.platform_namespace + "app.kubernetes.io/name" = "files-db" } + } - sync_policy { - dynamic "automated" { - for_each = var.argocd_automated_sync_enabled ? [1] : [] - content { - prune = var.argocd_prune_enabled - self_heal = var.argocd_self_heal_enabled - allow_empty = false - } - } + spec { + selector = { + "app.kubernetes.io/name" = "files-db" + } - sync_options = local.default_sync_options + port { + name = "postgres" + port = 5432 + target_port = 5432 + protocol = "TCP" } } } -resource "argocd_application" "authorization" { - depends_on = [ - argocd_repository.ghcr, - module.openfga_authorization, - ] - wait = true +resource "kubernetes_stateful_set_v1" "files_db" { metadata { - name = "authorization" - namespace = "argocd" - annotations = { - "argocd.argoproj.io/sync-wave" = "16" + name = "files-db" + namespace = kubernetes_namespace.platform.metadata[0].name + labels = { + "app.kubernetes.io/name" = "files-db" } } spec { - project = "default" - - source { - repo_url = local.platform_chart_repo_host - chart = local.authorization_chart_name - target_revision = var.authorization_chart_version + service_name = kubernetes_service_v1.files_db.metadata[0].name + replicas = 1 - helm { - values = local.authorization_values + selector { + match_labels = { + "app.kubernetes.io/name" = "files-db" } } - destination { - server = var.destination_server - namespace = var.platform_namespace - } - - sync_policy { - dynamic "automated" { - for_each = var.argocd_automated_sync_enabled ? [1] : [] - content { - prune = var.argocd_prune_enabled - self_heal = var.argocd_self_heal_enabled - allow_empty = false + template { + metadata { + labels = { + "app.kubernetes.io/name" = "files-db" } } - sync_options = local.default_sync_options - } - } + spec { + termination_grace_period_seconds = 30 - timeouts { - create = "5m" - update = "5m" - delete = "5m" - } -} + container { + name = "postgres" + image = local.postgres_image + image_pull_policy = "IfNotPresent" + env { + name = "POSTGRES_DB" + value = "files" + } + env { + name = "POSTGRES_USER" + value = "files" + } + env { + name = "POSTGRES_PASSWORD" + value = var.files_db_password + } + env { + name = "PGDATA" + value = "/var/lib/postgresql/data/pgdata" + } -resource "argocd_application" "identity" { - depends_on = [ - argocd_repository.ghcr, - argocd_application.identity_db, - ] - metadata { - name = "identity" - namespace = "argocd" - annotations = { - "argocd.argoproj.io/sync-wave" = "16" - } - } + port { + name = "postgres" + container_port = 5432 + } - spec { - project = "default" + readiness_probe { + exec { + command = ["pg_isready", "-U", "files", "-d", "files"] + } + initial_delay_seconds = 5 + period_seconds = 10 + } - source { - repo_url = local.platform_chart_repo_host - chart = local.identity_chart_name - target_revision = var.identity_chart_version + liveness_probe { + exec { + command = ["pg_isready", "-U", "files", "-d", "files"] + } + initial_delay_seconds = 30 + period_seconds = 20 + } - helm { - values = local.identity_values + volume_mount { + name = "data" + mount_path = "/var/lib/postgresql/data" + } + } } } - destination { - server = var.destination_server - namespace = var.platform_namespace - } + volume_claim_template { + metadata { + name = "data" + } - sync_policy { - dynamic "automated" { - for_each = var.argocd_automated_sync_enabled ? [1] : [] - content { - prune = var.argocd_prune_enabled - self_heal = var.argocd_self_heal_enabled - allow_empty = false + spec { + access_modes = ["ReadWriteOnce"] + + resources { + requests = { + storage = var.files_db_pvc_size + } } } - - sync_options = local.default_sync_options } } } +resource "argocd_repository" "twuni_docker_registry" { + repo = local.registry_mirror_repo_url + type = "git" +} + +resource "argocd_repository" "ghcr" { + repo = "ghcr.io" + type = "helm" + enable_oci = true + username = trimspace(var.ghcr_username) != "" ? var.ghcr_username : null + password = trimspace(var.ghcr_token) != "" ? var.ghcr_token : null +} -resource "argocd_application" "token_counting" { +resource "argocd_application" "platform_db" { depends_on = [argocd_repository.ghcr] + wait = true + metadata { - name = "token-counting" + name = "platform-db" namespace = "argocd" annotations = { - "argocd.argoproj.io/sync-wave" = "16" + "argocd.argoproj.io/sync-wave" = "5" } } @@ -3288,12 +1994,12 @@ resource "argocd_application" "token_counting" { project = "default" source { - repo_url = local.platform_chart_repo_host - chart = local.token_counting_chart_name - target_revision = var.token_counting_chart_version + repo_url = local.postgres_chart_repo_host + chart = local.postgres_chart_name + target_revision = var.postgres_chart_version helm { - values = local.token_counting_values + values = local.platform_db_values } } @@ -3303,27 +2009,34 @@ resource "argocd_application" "token_counting" { } sync_policy { - dynamic "automated" { - for_each = var.argocd_automated_sync_enabled ? [1] : [] - content { - prune = var.argocd_prune_enabled - self_heal = var.argocd_self_heal_enabled - allow_empty = false - } + # DB apps always use automated sync with prune disabled for stateful safety, + # independent of var.argocd_automated_sync_enabled. + automated { + prune = false + self_heal = true + allow_empty = false } - sync_options = local.default_sync_options + sync_options = local.postgres_sync_options } } + + timeouts { + create = "5m" + update = "5m" + delete = "5m" + } } -resource "argocd_application" "notifications_redis" { - depends_on = [argocd_repository.bitnami_repo] +resource "argocd_application" "threads_db" { + depends_on = [argocd_repository.ghcr] + wait = true + metadata { - name = "notifications-redis" + name = "threads-db" namespace = "argocd" annotations = { - "argocd.argoproj.io/sync-wave" = "16" + "argocd.argoproj.io/sync-wave" = "7" } } @@ -3331,12 +2044,12 @@ resource "argocd_application" "notifications_redis" { project = "default" source { - repo_url = "https://charts.bitnami.com/bitnami" - chart = local.redis_chart_name - target_revision = var.notifications_redis_chart_version + repo_url = local.postgres_chart_repo_host + chart = local.postgres_chart_name + target_revision = var.postgres_chart_version helm { - values = local.redis_values + values = local.threads_db_values } } @@ -3346,33 +2059,34 @@ resource "argocd_application" "notifications_redis" { } sync_policy { - dynamic "automated" { - for_each = var.argocd_automated_sync_enabled ? [1] : [] - content { - prune = var.argocd_prune_enabled - self_heal = var.argocd_self_heal_enabled - allow_empty = false - } + # DB apps always use automated sync with prune disabled for stateful safety, + # independent of var.argocd_automated_sync_enabled. + automated { + prune = false + self_heal = true + allow_empty = false } - sync_options = local.default_sync_options + sync_options = local.postgres_sync_options } } + + timeouts { + create = "5m" + update = "5m" + delete = "5m" + } } -resource "argocd_application" "runners" { - depends_on = [ - argocd_repository.ghcr, - argocd_application.runners_db, - argocd_application.identity, - argocd_application.authorization, - argocd_application.ziti_management, - ] +resource "argocd_application" "metering_db" { + depends_on = [argocd_repository.ghcr] + wait = true + metadata { - name = "runners" + name = "metering-db" namespace = "argocd" annotations = { - "argocd.argoproj.io/sync-wave" = "17" + "argocd.argoproj.io/sync-wave" = "7" } } @@ -3380,12 +2094,12 @@ resource "argocd_application" "runners" { project = "default" source { - repo_url = local.platform_chart_repo_host - chart = local.runners_chart_name - target_revision = var.runners_chart_version + repo_url = local.postgres_chart_repo_host + chart = local.postgres_chart_name + target_revision = var.postgres_chart_version helm { - values = local.runners_values + values = local.metering_db_values } } @@ -3395,33 +2109,34 @@ resource "argocd_application" "runners" { } sync_policy { - dynamic "automated" { - for_each = var.argocd_automated_sync_enabled ? [1] : [] - content { - prune = var.argocd_prune_enabled - self_heal = var.argocd_self_heal_enabled - allow_empty = false - } + # DB apps always use automated sync with prune disabled for stateful safety, + # independent of var.argocd_automated_sync_enabled. + automated { + prune = false + self_heal = true + allow_empty = false } - sync_options = local.default_sync_options + sync_options = local.postgres_sync_options } } + + timeouts { + create = "5m" + update = "5m" + delete = "5m" + } } -resource "argocd_application" "apps" { - depends_on = [ - argocd_repository.ghcr, - argocd_application.apps_db, - argocd_application.identity, - argocd_application.authorization, - argocd_application.ziti_management, - ] +resource "argocd_application" "chat_db" { + depends_on = [argocd_repository.ghcr] + wait = true + metadata { - name = "apps" + name = "chat-db" namespace = "argocd" annotations = { - "argocd.argoproj.io/sync-wave" = "17" + "argocd.argoproj.io/sync-wave" = "7" } } @@ -3429,12 +2144,12 @@ resource "argocd_application" "apps" { project = "default" source { - repo_url = local.platform_chart_repo_host - chart = local.apps_chart_name - target_revision = var.apps_chart_version + repo_url = local.postgres_chart_repo_host + chart = local.postgres_chart_name + target_revision = var.postgres_chart_version helm { - values = local.apps_values + values = local.chat_db_values } } @@ -3444,30 +2159,34 @@ resource "argocd_application" "apps" { } sync_policy { - dynamic "automated" { - for_each = var.argocd_automated_sync_enabled ? [1] : [] - content { - prune = var.argocd_prune_enabled - self_heal = var.argocd_self_heal_enabled - allow_empty = false - } + # DB apps always use automated sync with prune disabled for stateful safety, + # independent of var.argocd_automated_sync_enabled. + automated { + prune = false + self_heal = true + allow_empty = false } - sync_options = local.default_sync_options + sync_options = local.postgres_sync_options } } + + timeouts { + create = "5m" + update = "5m" + delete = "5m" + } } -resource "argocd_application" "agents" { - depends_on = [ - argocd_repository.ghcr, - argocd_application.agents_db, - ] +resource "argocd_application" "tracing_db" { + depends_on = [argocd_repository.ghcr] + wait = true + metadata { - name = "agents" + name = "tracing-db" namespace = "argocd" annotations = { - "argocd.argoproj.io/sync-wave" = "17" + "argocd.argoproj.io/sync-wave" = "7" } } @@ -3475,12 +2194,12 @@ resource "argocd_application" "agents" { project = "default" source { - repo_url = local.platform_chart_repo_host - chart = local.agents_chart_name - target_revision = var.agents_chart_version + repo_url = local.postgres_chart_repo_host + chart = local.postgres_chart_name + target_revision = var.postgres_chart_version helm { - values = local.agents_values + values = local.tracing_db_values } } @@ -3490,31 +2209,34 @@ resource "argocd_application" "agents" { } sync_policy { - dynamic "automated" { - for_each = var.argocd_automated_sync_enabled ? [1] : [] - content { - prune = var.argocd_prune_enabled - self_heal = var.argocd_self_heal_enabled - allow_empty = false - } + # DB apps always use automated sync with prune disabled for stateful safety, + # independent of var.argocd_automated_sync_enabled. + automated { + prune = false + self_heal = true + allow_empty = false } - sync_options = local.default_sync_options + sync_options = local.postgres_sync_options } } + + timeouts { + create = "5m" + update = "5m" + delete = "5m" + } } -resource "argocd_application" "ziti_management" { - depends_on = [ - argocd_repository.ghcr, - argocd_application.ziti_management_db, - ] +resource "argocd_application" "secrets_db" { + depends_on = [argocd_repository.ghcr] + wait = true metadata { - name = "ziti-management" + name = "secrets-db" namespace = "argocd" annotations = { - "argocd.argoproj.io/sync-wave" = "17" + "argocd.argoproj.io/sync-wave" = "7" } } @@ -3522,12 +2244,12 @@ resource "argocd_application" "ziti_management" { project = "default" source { - repo_url = local.platform_chart_repo_host - chart = local.ziti_management_chart_name - target_revision = var.ziti_management_chart_version + repo_url = local.postgres_chart_repo_host + chart = local.postgres_chart_name + target_revision = var.postgres_chart_version helm { - values = local.ziti_management_values + values = local.secrets_db_values } } @@ -3537,31 +2259,34 @@ resource "argocd_application" "ziti_management" { } sync_policy { - dynamic "automated" { - for_each = var.argocd_automated_sync_enabled ? [1] : [] - content { - prune = var.argocd_prune_enabled - self_heal = var.argocd_self_heal_enabled - allow_empty = false - } + # DB apps always use automated sync with prune disabled for stateful safety, + # independent of var.argocd_automated_sync_enabled. + automated { + prune = false + self_heal = true + allow_empty = false } - sync_options = local.default_sync_options + sync_options = local.postgres_sync_options } } + + timeouts { + create = "5m" + update = "5m" + delete = "5m" + } } -resource "argocd_application" "users" { - depends_on = [ - argocd_repository.ghcr, - argocd_application.users_db, - ] - wait = true +resource "argocd_application" "llm_db" { + depends_on = [argocd_repository.ghcr] + wait = true + metadata { - name = "users" + name = "llm-db" namespace = "argocd" annotations = { - "argocd.argoproj.io/sync-wave" = "17" + "argocd.argoproj.io/sync-wave" = "8" } } @@ -3569,12 +2294,12 @@ resource "argocd_application" "users" { project = "default" source { - repo_url = local.platform_chart_repo_host - chart = local.users_chart_name - target_revision = var.users_chart_version + repo_url = local.postgres_chart_repo_host + chart = local.postgres_chart_name + target_revision = var.postgres_chart_version helm { - values = local.users_values + values = local.llm_db_values } } @@ -3584,34 +2309,34 @@ resource "argocd_application" "users" { } sync_policy { - dynamic "automated" { - for_each = var.argocd_automated_sync_enabled ? [1] : [] - content { - prune = var.argocd_prune_enabled - self_heal = var.argocd_self_heal_enabled - allow_empty = false - } + # DB apps always use automated sync with prune disabled for stateful safety, + # independent of var.argocd_automated_sync_enabled. + automated { + prune = false + self_heal = true + allow_empty = false } - sync_options = local.default_sync_options + sync_options = local.postgres_sync_options } } + + timeouts { + create = "5m" + update = "5m" + delete = "5m" + } } -resource "argocd_application" "expose" { - depends_on = [ - argocd_repository.ghcr, - argocd_application.expose_db, - argocd_application.ziti_management, - argocd_application.runners, - argocd_application.notifications, - ] - wait = true +resource "argocd_application" "agents_db" { + depends_on = [argocd_repository.ghcr] + wait = true + metadata { - name = "expose" + name = "agents-db" namespace = "argocd" annotations = { - "argocd.argoproj.io/sync-wave" = "17" + "argocd.argoproj.io/sync-wave" = "8" } } @@ -3619,12 +2344,12 @@ resource "argocd_application" "expose" { project = "default" source { - repo_url = local.platform_chart_repo_host - chart = local.expose_chart_name - target_revision = var.expose_chart_version + repo_url = local.postgres_chart_repo_host + chart = local.postgres_chart_name + target_revision = var.postgres_chart_version helm { - values = local.expose_values + values = local.agents_db_values } } @@ -3634,31 +2359,34 @@ resource "argocd_application" "expose" { } sync_policy { - dynamic "automated" { - for_each = var.argocd_automated_sync_enabled ? [1] : [] - content { - prune = var.argocd_prune_enabled - self_heal = var.argocd_self_heal_enabled - allow_empty = false - } + # DB apps always use automated sync with prune disabled for stateful safety, + # independent of var.argocd_automated_sync_enabled. + automated { + prune = false + self_heal = true + allow_empty = false } - sync_options = local.default_sync_options + sync_options = local.postgres_sync_options } } + + timeouts { + create = "5m" + update = "5m" + delete = "5m" + } } -resource "argocd_application" "organizations" { - depends_on = [ - argocd_repository.ghcr, - argocd_application.organizations_db, - argocd_application.authorization, - ] +resource "argocd_application" "ziti_management_db" { + depends_on = [argocd_repository.ghcr] + wait = true + metadata { - name = "organizations" + name = "ziti-management-db" namespace = "argocd" annotations = { - "argocd.argoproj.io/sync-wave" = "17" + "argocd.argoproj.io/sync-wave" = "8" } } @@ -3666,12 +2394,12 @@ resource "argocd_application" "organizations" { project = "default" source { - repo_url = local.platform_chart_repo_host - chart = local.organizations_chart_name - target_revision = var.organizations_chart_version + repo_url = local.postgres_chart_repo_host + chart = local.postgres_chart_name + target_revision = var.postgres_chart_version helm { - values = local.organizations_values + values = local.ziti_management_db_values } } @@ -3681,30 +2409,34 @@ resource "argocd_application" "organizations" { } sync_policy { - dynamic "automated" { - for_each = var.argocd_automated_sync_enabled ? [1] : [] - content { - prune = var.argocd_prune_enabled - self_heal = var.argocd_self_heal_enabled - allow_empty = false - } + # DB apps always use automated sync with prune disabled for stateful safety, + # independent of var.argocd_automated_sync_enabled. + automated { + prune = false + self_heal = true + allow_empty = false } - sync_options = local.default_sync_options + sync_options = local.postgres_sync_options } } + + timeouts { + create = "5m" + update = "5m" + delete = "5m" + } } -resource "argocd_application" "llm" { - depends_on = [ - argocd_repository.ghcr, - argocd_application.llm_db, - ] +resource "argocd_application" "users_db" { + depends_on = [argocd_repository.ghcr] + wait = true + metadata { - name = "llm" + name = "users-db" namespace = "argocd" annotations = { - "argocd.argoproj.io/sync-wave" = "17" + "argocd.argoproj.io/sync-wave" = "8" } } @@ -3712,12 +2444,12 @@ resource "argocd_application" "llm" { project = "default" source { - repo_url = local.platform_chart_repo_host - chart = local.llm_chart_name - target_revision = var.llm_chart_version + repo_url = local.postgres_chart_repo_host + chart = local.postgres_chart_name + target_revision = var.postgres_chart_version helm { - values = local.llm_values + values = local.users_db_values } } @@ -3727,36 +2459,34 @@ resource "argocd_application" "llm" { } sync_policy { - dynamic "automated" { - for_each = var.argocd_automated_sync_enabled ? [1] : [] - content { - prune = var.argocd_prune_enabled - self_heal = var.argocd_self_heal_enabled - allow_empty = false - } + # DB apps always use automated sync with prune disabled for stateful safety, + # independent of var.argocd_automated_sync_enabled. + automated { + prune = false + self_heal = true + allow_empty = false } - sync_options = local.default_sync_options + sync_options = local.postgres_sync_options } } + + timeouts { + create = "5m" + update = "5m" + delete = "5m" + } } -resource "minio_s3_bucket" "files" { - bucket = var.minio_bucket_name - acl = "private" -} +resource "argocd_application" "expose_db" { + depends_on = [argocd_repository.ghcr] + wait = true -resource "argocd_application" "files" { - depends_on = [ - argocd_repository.ghcr, - kubernetes_stateful_set_v1.files_db, - minio_s3_bucket.files, - ] metadata { - name = "files" + name = "expose-db" namespace = "argocd" annotations = { - "argocd.argoproj.io/sync-wave" = "17" + "argocd.argoproj.io/sync-wave" = "8" } } @@ -3764,12 +2494,12 @@ resource "argocd_application" "files" { project = "default" source { - repo_url = local.platform_chart_repo_host - chart = local.files_chart_name - target_revision = var.files_chart_version + repo_url = local.postgres_chart_repo_host + chart = local.postgres_chart_name + target_revision = var.postgres_chart_version helm { - values = local.files_values + values = local.expose_db_values } } @@ -3779,30 +2509,34 @@ resource "argocd_application" "files" { } sync_policy { - dynamic "automated" { - for_each = var.argocd_automated_sync_enabled ? [1] : [] - content { - prune = var.argocd_prune_enabled - self_heal = var.argocd_self_heal_enabled - allow_empty = false - } + # DB apps always use automated sync with prune disabled for stateful safety, + # independent of var.argocd_automated_sync_enabled. + automated { + prune = false + self_heal = true + allow_empty = false } - sync_options = local.default_sync_options + sync_options = local.postgres_sync_options } } + + timeouts { + create = "5m" + update = "5m" + delete = "5m" + } } -resource "argocd_application" "notifications" { - depends_on = [ - argocd_repository.ghcr, - argocd_application.notifications_redis, - ] +resource "argocd_application" "organizations_db" { + depends_on = [argocd_repository.ghcr] + wait = true + metadata { - name = "notifications" + name = "organizations-db" namespace = "argocd" annotations = { - "argocd.argoproj.io/sync-wave" = "17" + "argocd.argoproj.io/sync-wave" = "8" } } @@ -3810,12 +2544,12 @@ resource "argocd_application" "notifications" { project = "default" source { - repo_url = local.platform_chart_repo_host - chart = local.notifications_chart_name - target_revision = var.notifications_chart_version + repo_url = local.postgres_chart_repo_host + chart = local.postgres_chart_name + target_revision = var.postgres_chart_version helm { - values = local.notifications_values + values = local.organizations_db_values } } @@ -3825,36 +2559,34 @@ resource "argocd_application" "notifications" { } sync_policy { - dynamic "automated" { - for_each = var.argocd_automated_sync_enabled ? [1] : [] - content { - prune = var.argocd_prune_enabled - self_heal = var.argocd_self_heal_enabled - allow_empty = false - } + # DB apps always use automated sync with prune disabled for stateful safety, + # independent of var.argocd_automated_sync_enabled. + automated { + prune = false + self_heal = true + allow_empty = false } - sync_options = local.default_sync_options + sync_options = local.postgres_sync_options } } + + timeouts { + create = "5m" + update = "5m" + delete = "5m" + } } -resource "argocd_application" "agents_orchestrator" { - depends_on = [ - argocd_repository.ghcr, - argocd_application.agents_orchestrator_db, - argocd_application.ziti_management, - argocd_application.threads, - argocd_application.notifications, - argocd_application.agents, - argocd_application.secrets, - argocd_application.runners, - ] +resource "argocd_application" "agents_orchestrator_db" { + depends_on = [argocd_repository.ghcr] + wait = true + metadata { - name = "agents-orchestrator" + name = "agents-orchestrator-db" namespace = "argocd" annotations = { - "argocd.argoproj.io/sync-wave" = "19" + "argocd.argoproj.io/sync-wave" = "8" } } @@ -3862,12 +2594,12 @@ resource "argocd_application" "agents_orchestrator" { project = "default" source { - repo_url = local.platform_chart_repo_host - chart = local.agents_orchestrator_chart_name - target_revision = var.agents_orchestrator_chart_version + repo_url = local.postgres_chart_repo_host + chart = local.postgres_chart_name + target_revision = var.postgres_chart_version helm { - values = local.agents_orchestrator_values + values = local.agents_orchestrator_db_values } } @@ -3877,32 +2609,34 @@ resource "argocd_application" "agents_orchestrator" { } sync_policy { - dynamic "automated" { - for_each = var.argocd_automated_sync_enabled ? [1] : [] - content { - prune = var.argocd_prune_enabled - self_heal = var.argocd_self_heal_enabled - allow_empty = false - } + # DB apps always use automated sync with prune disabled for stateful safety, + # independent of var.argocd_automated_sync_enabled. + automated { + prune = false + self_heal = true + allow_empty = false } - sync_options = local.default_sync_options + sync_options = local.postgres_sync_options } } + + timeouts { + create = "5m" + update = "5m" + delete = "5m" + } } -resource "argocd_application" "media_proxy" { - depends_on = [ - argocd_repository.ghcr, - argocd_application.users, - argocd_application.files, - argocd_application.authorization, - ] +resource "argocd_application" "identity_db" { + depends_on = [argocd_repository.ghcr] + wait = true + metadata { - name = "media-proxy" + name = "identity-db" namespace = "argocd" annotations = { - "argocd.argoproj.io/sync-wave" = "20" + "argocd.argoproj.io/sync-wave" = "8" } } @@ -3910,12 +2644,12 @@ resource "argocd_application" "media_proxy" { project = "default" source { - repo_url = local.platform_chart_repo_host - chart = local.media_proxy_chart_name - target_revision = var.media_proxy_chart_version + repo_url = local.postgres_chart_repo_host + chart = local.postgres_chart_name + target_revision = var.postgres_chart_version helm { - values = local.media_proxy_values + values = local.identity_db_values } } @@ -3925,27 +2659,34 @@ resource "argocd_application" "media_proxy" { } sync_policy { - dynamic "automated" { - for_each = var.argocd_automated_sync_enabled ? [1] : [] - content { - prune = var.argocd_prune_enabled - self_heal = var.argocd_self_heal_enabled - allow_empty = false - } + # DB apps always use automated sync with prune disabled for stateful safety, + # independent of var.argocd_automated_sync_enabled. + automated { + prune = false + self_heal = true + allow_empty = false } - sync_options = local.default_sync_options + sync_options = local.postgres_sync_options } } + + timeouts { + create = "5m" + update = "5m" + delete = "5m" + } } -resource "argocd_application" "chat_app" { +resource "argocd_application" "runners_db" { depends_on = [argocd_repository.ghcr] + wait = true + metadata { - name = "chat-app" + name = "runners-db" namespace = "argocd" annotations = { - "argocd.argoproj.io/sync-wave" = "25" + "argocd.argoproj.io/sync-wave" = "8" } } @@ -3953,12 +2694,12 @@ resource "argocd_application" "chat_app" { project = "default" source { - repo_url = local.platform_chart_repo_host - chart = local.chat_app_chart_name - target_revision = var.chat_app_chart_version + repo_url = local.postgres_chart_repo_host + chart = local.postgres_chart_name + target_revision = var.postgres_chart_version helm { - values = local.chat_app_values + values = local.runners_db_values } } @@ -3968,27 +2709,34 @@ resource "argocd_application" "chat_app" { } sync_policy { - dynamic "automated" { - for_each = var.argocd_automated_sync_enabled ? [1] : [] - content { - prune = var.argocd_prune_enabled - self_heal = var.argocd_self_heal_enabled - allow_empty = false - } + # DB apps always use automated sync with prune disabled for stateful safety, + # independent of var.argocd_automated_sync_enabled. + automated { + prune = false + self_heal = true + allow_empty = false } - sync_options = local.default_sync_options + sync_options = local.postgres_sync_options } } + + timeouts { + create = "5m" + update = "5m" + delete = "5m" + } } -resource "argocd_application" "console_app" { +resource "argocd_application" "apps_db" { depends_on = [argocd_repository.ghcr] + wait = true + metadata { - name = "console-app" + name = "apps-db" namespace = "argocd" annotations = { - "argocd.argoproj.io/sync-wave" = "25" + "argocd.argoproj.io/sync-wave" = "8" } } @@ -3996,12 +2744,12 @@ resource "argocd_application" "console_app" { project = "default" source { - repo_url = local.platform_chart_repo_host - chart = local.console_app_chart_name - target_revision = var.console_app_chart_version + repo_url = local.postgres_chart_repo_host + chart = local.postgres_chart_name + target_revision = var.postgres_chart_version helm { - values = local.console_app_values + values = local.apps_db_values } } @@ -4011,27 +2759,32 @@ resource "argocd_application" "console_app" { } sync_policy { - dynamic "automated" { - for_each = var.argocd_automated_sync_enabled ? [1] : [] - content { - prune = var.argocd_prune_enabled - self_heal = var.argocd_self_heal_enabled - allow_empty = false - } + # DB apps always use automated sync with prune disabled for stateful safety, + # independent of var.argocd_automated_sync_enabled. + automated { + prune = false + self_heal = true + allow_empty = false } - sync_options = local.default_sync_options + sync_options = local.postgres_sync_options } } + + timeouts { + create = "5m" + update = "5m" + delete = "5m" + } } -resource "argocd_application" "tracing_app" { - depends_on = [argocd_repository.ghcr] +resource "argocd_application" "registry_mirror" { + depends_on = [argocd_repository.twuni_docker_registry] metadata { - name = "tracing-app" + name = "registry-mirror" namespace = "argocd" annotations = { - "argocd.argoproj.io/sync-wave" = "25" + "argocd.argoproj.io/sync-wave" = "1" } } @@ -4039,12 +2792,12 @@ resource "argocd_application" "tracing_app" { project = "default" source { - repo_url = local.platform_chart_repo_host - chart = local.tracing_app_chart_name - target_revision = var.tracing_app_chart_version + repo_url = local.registry_mirror_repo_url + target_revision = local.registry_mirror_chart_revision + path = local.registry_mirror_chart_path helm { - values = local.tracing_app_values + values = local.registry_mirror_values } } @@ -4068,14 +2821,13 @@ resource "argocd_application" "tracing_app" { } } -resource "argocd_application" "gateway" { - depends_on = [argocd_application.llm, argocd_application.ziti_management, argocd_application.expose] - wait = true +resource "argocd_application" "ncps" { + depends_on = [argocd_repository.ghcr] metadata { - name = "gateway" + name = "ncps" namespace = "argocd" annotations = { - "argocd.argoproj.io/sync-wave" = "30" + "argocd.argoproj.io/sync-wave" = "15" } } @@ -4083,31 +2835,12 @@ resource "argocd_application" "gateway" { project = "default" source { - repo_url = "ghcr.io" - chart = "agynio/charts/gateway" - target_revision = var.gateway_chart_version + repo_url = local.ncps_chart_repo_host + chart = local.ncps_chart_name + target_revision = local.ncps_chart_revision helm { - values = yamlencode({ - replicaCount = 1 - image = { - tag = local.resolved_gateway_image_tag - } - gateway = { - oidcIssuerUrl = var.oidc_issuer_url - oidcClientId = var.oidc_client_id - clusterAdminToken = random_password.cluster_admin_token.result - clusterAdminIdentityId = local.cluster_admin_identity_id - usersGrpcTarget = "users:50051" - organizationsGrpcTarget = "organizations:50051" - } - env = [ - { - name = "ZITI_ENABLED" - value = "true" - }, - ] - }) + values = local.ncps_values } } @@ -4131,18 +2864,42 @@ resource "argocd_application" "gateway" { } } -resource "argocd_application" "llm_proxy" { +resource "argocd_application" "platform" { depends_on = [ - argocd_application.llm, - argocd_application.users, - argocd_application.authorization, - argocd_application.ziti_management, + argocd_repository.ghcr, + kubernetes_namespace.platform, + module.openfga_authorization, + kubernetes_secret_v1.platform_database_urls, + kubernetes_secret_v1.files_s3, + kubernetes_secret_v1.cluster_admin, + kubernetes_secret_v1.secrets_encryption_key, + kubernetes_secret_v1.ziti_management_enrollment, + argocd_application.platform_db, + argocd_application.threads_db, + argocd_application.metering_db, + argocd_application.chat_db, + argocd_application.tracing_db, + argocd_application.secrets_db, + argocd_application.llm_db, + argocd_application.agents_db, + argocd_application.ziti_management_db, + argocd_application.users_db, + argocd_application.expose_db, + argocd_application.organizations_db, + argocd_application.agents_orchestrator_db, + argocd_application.identity_db, + argocd_application.runners_db, + argocd_application.apps_db, + argocd_application.registry_mirror, + argocd_application.ncps, ] + wait = false + metadata { - name = "llm-proxy" + name = "platform" namespace = "argocd" annotations = { - "argocd.argoproj.io/sync-wave" = "30" + "argocd.argoproj.io/sync-wave" = "16" } } @@ -4151,36 +2908,11 @@ resource "argocd_application" "llm_proxy" { source { repo_url = local.platform_chart_repo_host - chart = local.llm_proxy_chart_name - target_revision = var.llm_proxy_chart_version + chart = local.platform_chart_name + target_revision = var.platform_chart_version helm { - values = yamlencode({ - replicaCount = 1 - image = { - tag = local.resolved_llm_proxy_image_tag - } - securityContext = { - enabled = true - runAsNonRoot = true - runAsUser = 65532 - runAsGroup = 65532 - readOnlyRootFilesystem = true - allowPrivilegeEscalation = false - capabilities = { - drop = ["ALL"] - } - seccompProfile = { - type = "RuntimeDefault" - } - } - env = [ - { - name = "ZITI_ENABLED" - value = "true" - }, - ] - }) + values = local.platform_values } } diff --git a/stacks/platform/outputs.tf b/stacks/platform/outputs.tf index 43bbe16..0cd18d7 100644 --- a/stacks/platform/outputs.tf +++ b/stacks/platform/outputs.tf @@ -3,21 +3,23 @@ output "platform_app_names" { value = [ argocd_application.registry_mirror.metadata[0].name, argocd_application.platform_db.metadata[0].name, + argocd_application.threads_db.metadata[0].name, + argocd_application.metering_db.metadata[0].name, + argocd_application.chat_db.metadata[0].name, argocd_application.tracing_db.metadata[0].name, + argocd_application.secrets_db.metadata[0].name, + argocd_application.llm_db.metadata[0].name, + argocd_application.agents_db.metadata[0].name, + argocd_application.ziti_management_db.metadata[0].name, + argocd_application.users_db.metadata[0].name, + argocd_application.expose_db.metadata[0].name, + argocd_application.organizations_db.metadata[0].name, + argocd_application.agents_orchestrator_db.metadata[0].name, + argocd_application.identity_db.metadata[0].name, + argocd_application.runners_db.metadata[0].name, argocd_application.apps_db.metadata[0].name, argocd_application.ncps.metadata[0].name, - argocd_application.tracing.metadata[0].name, - argocd_application.authorization.metadata[0].name, - argocd_application.token_counting.metadata[0].name, - argocd_application.notifications_redis.metadata[0].name, - argocd_application.notifications.metadata[0].name, - argocd_application.expose.metadata[0].name, - argocd_application.files.metadata[0].name, - argocd_application.media_proxy.metadata[0].name, - argocd_application.apps.metadata[0].name, - argocd_application.chat_app.metadata[0].name, - argocd_application.console_app.metadata[0].name, - argocd_application.tracing_app.metadata[0].name, + argocd_application.platform.metadata[0].name, ] } @@ -26,21 +28,23 @@ output "platform_app_ids" { value = [ argocd_application.registry_mirror.id, argocd_application.platform_db.id, + argocd_application.threads_db.id, + argocd_application.metering_db.id, + argocd_application.chat_db.id, argocd_application.tracing_db.id, + argocd_application.secrets_db.id, + argocd_application.llm_db.id, + argocd_application.agents_db.id, + argocd_application.ziti_management_db.id, + argocd_application.users_db.id, + argocd_application.expose_db.id, + argocd_application.organizations_db.id, + argocd_application.agents_orchestrator_db.id, + argocd_application.identity_db.id, + argocd_application.runners_db.id, argocd_application.apps_db.id, argocd_application.ncps.id, - argocd_application.tracing.id, - argocd_application.authorization.id, - argocd_application.token_counting.id, - argocd_application.notifications_redis.id, - argocd_application.notifications.id, - argocd_application.expose.id, - argocd_application.files.id, - argocd_application.media_proxy.id, - argocd_application.apps.id, - argocd_application.chat_app.id, - argocd_application.console_app.id, - argocd_application.tracing_app.id, + argocd_application.platform.id, ] } diff --git a/stacks/platform/variables.tf b/stacks/platform/variables.tf index c85f0d0..cb67fb3 100644 --- a/stacks/platform/variables.tf +++ b/stacks/platform/variables.tf @@ -30,6 +30,12 @@ variable "ghcr_token" { sensitive = true } +variable "platform_chart_version" { + type = string + description = "Version of the agyn-platform umbrella Helm chart published to GHCR" + default = "0.1.0" +} + variable "gateway_chart_version" { type = string description = "Version of the gateway Helm chart published to GHCR"