From a681a9ae8161dfac04d9df3b07b5e09c223d6980 Mon Sep 17 00:00:00 2001 From: Danijel Simeunovic Date: Wed, 18 Mar 2026 21:01:50 +0100 Subject: [PATCH 1/4] multi cluster --- _app-of-apps.yaml => _app-of-apps-eu.yaml | 2 +- _app-of-apps-us.yaml | 32 +++++ apps/{ => base}/argo-mcp.yaml | 0 apps/{ => base}/dot-ai-stack.yaml | 28 ++-- apps/base/kustomization.yaml | 8 ++ apps/{ => base}/mcp10x.yaml | 0 apps/{ => base}/mcpcoder.yaml | 0 apps/{ => base}/musicman.yaml | 0 apps/overlays/eu/kustomization.yaml | 7 + apps/overlays/us/kustomization.yaml | 14 ++ bootstrap.sh | 17 ++- clusters/eu.yaml | 10 ++ clusters/us.yaml | 10 ++ .../{ => base}/cert-manager-application.yaml | 0 .../cluster-resources-application.yaml | 0 infra/{ => base}/enterprise-apps.yaml | 2 +- infra/{ => base}/fluent-bit.yaml | 2 +- infra/{ => base}/grafana.yaml | 3 +- infra/{ => base}/keycloak.yaml | 3 +- infra/base/kustomization.yaml | 17 +++ infra/{ => base}/kyverno-policies.yaml | 0 infra/{ => base}/kyverno.yaml | 0 infra/{ => base}/loki.yaml | 2 +- infra/{ => base}/prometheus.yaml | 2 +- infra/{ => base}/sealedsecrets.yaml | 0 infra/{ => base}/secrets.yaml | 2 +- infra/base/traefik-application.yaml | 51 +++++++ infra/{ => base}/trivy.yaml | 0 infra/overlays/eu/kustomization.yaml | 7 + infra/overlays/us/kustomization.yaml | 50 +++++++ infra/traefik-application.yaml | 130 ------------------ infra/values/{ => base}/argocd-values.yaml | 6 - infra/values/base/dot-ai-stack-values.yaml | 11 ++ .../values/{ => base}/fluent-bit-values.yaml | 0 infra/values/{ => base}/grafana-values.yaml | 2 - infra/values/{ => base}/keycloak-values.yaml | 2 - infra/values/{ => base}/loki-values.yaml | 0 .../values/{ => base}/prometheus-values.yaml | 0 infra/values/base/traefik-values.yaml | 50 +++++++ infra/values/eu/argocd-values.yaml | 5 + infra/values/eu/dot-ai-stack-values.yaml | 8 ++ infra/values/eu/grafana-values.yaml | 3 + infra/values/eu/keycloak-values.yaml | 2 + infra/values/eu/traefik-values.yaml | 40 ++++++ infra/values/us/argocd-values.yaml | 5 + infra/values/us/dot-ai-stack-values.yaml | 8 ++ infra/values/us/grafana-values.yaml | 3 + infra/values/us/keycloak-values.yaml | 2 + infra/values/us/traefik-values.yaml | 13 ++ secrets/{ => eu}/argocd-mcp-credentials.yaml | 0 .../{ => eu}/argocdmcp-auth-oidc-sealed.yaml | 0 secrets/{ => eu}/dot-ai-secrets.yaml | 0 .../forte10x-app-credentials-sealed.yaml | 0 .../{ => eu}/keycloak-credentials-sealed.yaml | 0 secrets/{ => eu}/musicman-credentials.yaml | 0 55 files changed, 387 insertions(+), 172 deletions(-) rename _app-of-apps.yaml => _app-of-apps-eu.yaml (96%) create mode 100644 _app-of-apps-us.yaml rename apps/{ => base}/argo-mcp.yaml (100%) rename apps/{ => base}/dot-ai-stack.yaml (73%) create mode 100644 apps/base/kustomization.yaml rename apps/{ => base}/mcp10x.yaml (100%) rename apps/{ => base}/mcpcoder.yaml (100%) rename apps/{ => base}/musicman.yaml (100%) create mode 100644 apps/overlays/eu/kustomization.yaml create mode 100644 apps/overlays/us/kustomization.yaml create mode 100644 clusters/eu.yaml create mode 100644 clusters/us.yaml rename infra/{ => base}/cert-manager-application.yaml (100%) rename infra/{ => base}/cluster-resources-application.yaml (100%) rename infra/{ => base}/enterprise-apps.yaml (96%) rename infra/{ => base}/fluent-bit.yaml (94%) rename infra/{ => base}/grafana.yaml (89%) rename infra/{ => base}/keycloak.yaml (89%) create mode 100644 infra/base/kustomization.yaml rename infra/{ => base}/kyverno-policies.yaml (100%) rename infra/{ => base}/kyverno.yaml (100%) rename infra/{ => base}/loki.yaml (94%) rename infra/{ => base}/prometheus.yaml (94%) rename infra/{ => base}/sealedsecrets.yaml (100%) rename infra/{ => base}/secrets.yaml (97%) create mode 100644 infra/base/traefik-application.yaml rename infra/{ => base}/trivy.yaml (100%) create mode 100644 infra/overlays/eu/kustomization.yaml create mode 100644 infra/overlays/us/kustomization.yaml delete mode 100644 infra/traefik-application.yaml rename infra/values/{ => base}/argocd-values.yaml (94%) create mode 100644 infra/values/base/dot-ai-stack-values.yaml rename infra/values/{ => base}/fluent-bit-values.yaml (100%) rename infra/values/{ => base}/grafana-values.yaml (99%) rename infra/values/{ => base}/keycloak-values.yaml (95%) rename infra/values/{ => base}/loki-values.yaml (100%) rename infra/values/{ => base}/prometheus-values.yaml (100%) create mode 100644 infra/values/base/traefik-values.yaml create mode 100644 infra/values/eu/argocd-values.yaml create mode 100644 infra/values/eu/dot-ai-stack-values.yaml create mode 100644 infra/values/eu/grafana-values.yaml create mode 100644 infra/values/eu/keycloak-values.yaml create mode 100644 infra/values/eu/traefik-values.yaml create mode 100644 infra/values/us/argocd-values.yaml create mode 100644 infra/values/us/dot-ai-stack-values.yaml create mode 100644 infra/values/us/grafana-values.yaml create mode 100644 infra/values/us/keycloak-values.yaml create mode 100644 infra/values/us/traefik-values.yaml rename secrets/{ => eu}/argocd-mcp-credentials.yaml (100%) rename secrets/{ => eu}/argocdmcp-auth-oidc-sealed.yaml (100%) rename secrets/{ => eu}/dot-ai-secrets.yaml (100%) rename secrets/{ => eu}/forte10x-app-credentials-sealed.yaml (100%) rename secrets/{ => eu}/keycloak-credentials-sealed.yaml (100%) rename secrets/{ => eu}/musicman-credentials.yaml (100%) diff --git a/_app-of-apps.yaml b/_app-of-apps-eu.yaml similarity index 96% rename from _app-of-apps.yaml rename to _app-of-apps-eu.yaml index 3e4fb9e..311556d 100644 --- a/_app-of-apps.yaml +++ b/_app-of-apps-eu.yaml @@ -20,7 +20,7 @@ spec: source: repoURL: git@github.com:fortedigital/sturdy-adventure.git targetRevision: HEAD - path: infra + path: infra/overlays/eu destination: server: https://kubernetes.default.svc namespace: default diff --git a/_app-of-apps-us.yaml b/_app-of-apps-us.yaml new file mode 100644 index 0000000..95317b3 --- /dev/null +++ b/_app-of-apps-us.yaml @@ -0,0 +1,32 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: monitoring + annotations: + argocd.argoproj.io/sync-wave: "-1" +--- +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: infrastructure-apps + namespace: argocd + labels: + app.kubernetes.io/name: infrastructure-apps + app.kubernetes.io/part-of: platform + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + project: default + source: + repoURL: git@github.com:fortedigital/sturdy-adventure.git + targetRevision: HEAD + path: infra/overlays/us + destination: + server: https://kubernetes.default.svc + namespace: default + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/apps/argo-mcp.yaml b/apps/base/argo-mcp.yaml similarity index 100% rename from apps/argo-mcp.yaml rename to apps/base/argo-mcp.yaml diff --git a/apps/dot-ai-stack.yaml b/apps/base/dot-ai-stack.yaml similarity index 73% rename from apps/dot-ai-stack.yaml rename to apps/base/dot-ai-stack.yaml index b048233..f322e35 100644 --- a/apps/dot-ai-stack.yaml +++ b/apps/base/dot-ai-stack.yaml @@ -27,29 +27,19 @@ metadata: spec: project: default - source: - repoURL: ghcr.io/vfarcic/dot-ai-stack/charts + sources: + - repoURL: ghcr.io/vfarcic/dot-ai-stack/charts chart: dot-ai-stack targetRevision: "0.56.0" - helm: releaseName: dot-ai-stack - values: | - dot-ai: - ingress: - enabled: true - className: traefik - host: kubemcp.forteapps.net - webUI: - baseUrl: http://kubemcpui.forteapps.net - dot-ai-ui: - uiAuth: - secretRef: - name: dot-ai-secrets - ingress: - enabled: true - className: traefik - host: kubemcpui.forteapps.net + valueFiles: + - $values/infra/values/base/dot-ai-stack-values.yaml + - $values/infra/values/eu/dot-ai-stack-values.yaml + + - repoURL: git@github.com:fortedigital/sturdy-adventure.git + targetRevision: HEAD + ref: values destination: server: https://kubernetes.default.svc diff --git a/apps/base/kustomization.yaml b/apps/base/kustomization.yaml new file mode 100644 index 0000000..3cc3d12 --- /dev/null +++ b/apps/base/kustomization.yaml @@ -0,0 +1,8 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- dot-ai-stack.yaml +- mcp10x.yaml +- musicman.yaml +- mcpcoder.yaml +- argo-mcp.yaml diff --git a/apps/mcp10x.yaml b/apps/base/mcp10x.yaml similarity index 100% rename from apps/mcp10x.yaml rename to apps/base/mcp10x.yaml diff --git a/apps/mcpcoder.yaml b/apps/base/mcpcoder.yaml similarity index 100% rename from apps/mcpcoder.yaml rename to apps/base/mcpcoder.yaml diff --git a/apps/musicman.yaml b/apps/base/musicman.yaml similarity index 100% rename from apps/musicman.yaml rename to apps/base/musicman.yaml diff --git a/apps/overlays/eu/kustomization.yaml b/apps/overlays/eu/kustomization.yaml new file mode 100644 index 0000000..ea393bf --- /dev/null +++ b/apps/overlays/eu/kustomization.yaml @@ -0,0 +1,7 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- ../../base + +# No patches needed — base already has "eu" paths +# EU is the default/base cluster diff --git a/apps/overlays/us/kustomization.yaml b/apps/overlays/us/kustomization.yaml new file mode 100644 index 0000000..0c93339 --- /dev/null +++ b/apps/overlays/us/kustomization.yaml @@ -0,0 +1,14 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- ../../base + +patches: +# dot-ai-stack: swap eu → us +- target: + kind: Application + name: dot-ai-stack + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/us/dot-ai-stack-values.yaml diff --git a/bootstrap.sh b/bootstrap.sh index 88c4473..381dfbd 100644 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -2,7 +2,14 @@ # in case of $'\r': command not found error, run command below first # sed -i 's/\r$//' ./bootstrap.sh -echo "running $0..." +CLUSTER="${1:?Usage: ./bootstrap.sh (eu|us)}" + +echo "running $0 for cluster: ${CLUSTER}..." + +# Source cluster config +eval $(yq e 'to_entries | .[] | "export " + .key + "=\"" + .value + "\""' "clusters/${CLUSTER}.yaml") + +echo "Bootstrapping cluster: ${clusterName} (${CLUSTER})..." ############################################################ # Bootstrap # @@ -31,15 +38,15 @@ ArgoCd() { # install argocd echo "Installing ArgoCD..." - CLUSTER_NAME="${CLUSTER_NAME:-dev-fd-no-svg1}" helm upgrade --install argocd argo-cd \ --repo https://argoproj.github.io/argo-helm \ --namespace argocd --create-namespace \ - --values infra/values/argocd-values.yaml \ - --set notifications.context.clusterName="$CLUSTER_NAME" \ + --values infra/values/base/argocd-values.yaml \ + --values "infra/values/${CLUSTER}/argocd-values.yaml" \ + --set notifications.context.clusterName="${clusterName}" \ --timeout 60s --atomic - kubectl apply -f _app-of-apps.yaml -n argocd + kubectl apply -f "_app-of-apps-${CLUSTER}.yaml" -n argocd } Bootstrap diff --git a/clusters/eu.yaml b/clusters/eu.yaml new file mode 100644 index 0000000..8c02662 --- /dev/null +++ b/clusters/eu.yaml @@ -0,0 +1,10 @@ +clusterName: dev-fd-eu-no-svg1 +domain: forteapps.net +argocdDomain: argocd.127.0.0.1.nip.io +grafanaDomain: grafana.forteapps.net +keycloakDomain: id.forteapps.net +dotaiDomain: kubemcp.forteapps.net +dotaiUiDomain: kubemcpui.forteapps.net +letsencryptEmail: danijels@gmail.com +trustedIPs: "172.16.1.0/24" +cloudProvider: upcloud diff --git a/clusters/us.yaml b/clusters/us.yaml new file mode 100644 index 0000000..98a3a3c --- /dev/null +++ b/clusters/us.yaml @@ -0,0 +1,10 @@ +clusterName: dev-fd-us-east1 +domain: us.forteapps.net +argocdDomain: argocd.us.forteapps.net +grafanaDomain: grafana.us.forteapps.net +keycloakDomain: id.us.forteapps.net +dotaiDomain: kubemcp.us.forteapps.net +dotaiUiDomain: kubemcpui.us.forteapps.net +letsencryptEmail: danijels@gmail.com +trustedIPs: "10.0.0.0/16" +cloudProvider: tbd diff --git a/infra/cert-manager-application.yaml b/infra/base/cert-manager-application.yaml similarity index 100% rename from infra/cert-manager-application.yaml rename to infra/base/cert-manager-application.yaml diff --git a/infra/cluster-resources-application.yaml b/infra/base/cluster-resources-application.yaml similarity index 100% rename from infra/cluster-resources-application.yaml rename to infra/base/cluster-resources-application.yaml diff --git a/infra/enterprise-apps.yaml b/infra/base/enterprise-apps.yaml similarity index 96% rename from infra/enterprise-apps.yaml rename to infra/base/enterprise-apps.yaml index 0cce61e..5d0b5c3 100644 --- a/infra/enterprise-apps.yaml +++ b/infra/base/enterprise-apps.yaml @@ -18,7 +18,7 @@ spec: source: repoURL: git@github.com:fortedigital/sturdy-adventure.git targetRevision: HEAD - path: apps + path: apps/overlays/eu destination: server: https://kubernetes.default.svc namespace: apps diff --git a/infra/fluent-bit.yaml b/infra/base/fluent-bit.yaml similarity index 94% rename from infra/fluent-bit.yaml rename to infra/base/fluent-bit.yaml index 462665f..51cf40e 100644 --- a/infra/fluent-bit.yaml +++ b/infra/base/fluent-bit.yaml @@ -21,7 +21,7 @@ spec: helm: releaseName: fluent-bit valueFiles: - - $values/infra/values/fluent-bit-values.yaml + - $values/infra/values/base/fluent-bit-values.yaml - repoURL: git@github.com:fortedigital/sturdy-adventure.git targetRevision: HEAD diff --git a/infra/grafana.yaml b/infra/base/grafana.yaml similarity index 89% rename from infra/grafana.yaml rename to infra/base/grafana.yaml index 43d87c7..3261109 100644 --- a/infra/grafana.yaml +++ b/infra/base/grafana.yaml @@ -21,7 +21,8 @@ spec: helm: releaseName: grafana valueFiles: - - $values/infra/values/grafana-values.yaml + - $values/infra/values/base/grafana-values.yaml + - $values/infra/values/eu/grafana-values.yaml - repoURL: git@github.com:fortedigital/sturdy-adventure.git targetRevision: HEAD diff --git a/infra/keycloak.yaml b/infra/base/keycloak.yaml similarity index 89% rename from infra/keycloak.yaml rename to infra/base/keycloak.yaml index b5e00a0..a5f753f 100644 --- a/infra/keycloak.yaml +++ b/infra/base/keycloak.yaml @@ -21,7 +21,8 @@ spec: helm: releaseName: keycloak valueFiles: - - $values/infra/values/keycloak-values.yaml + - $values/infra/values/base/keycloak-values.yaml + - $values/infra/values/eu/keycloak-values.yaml - repoURL: git@github.com:fortedigital/sturdy-adventure.git targetRevision: HEAD diff --git a/infra/base/kustomization.yaml b/infra/base/kustomization.yaml new file mode 100644 index 0000000..adb38e1 --- /dev/null +++ b/infra/base/kustomization.yaml @@ -0,0 +1,17 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- traefik-application.yaml +- keycloak.yaml +- grafana.yaml +- cert-manager-application.yaml +- kyverno.yaml +- sealedsecrets.yaml +- prometheus.yaml +- loki.yaml +- fluent-bit.yaml +- trivy.yaml +- enterprise-apps.yaml +- cluster-resources-application.yaml +- kyverno-policies.yaml +- secrets.yaml diff --git a/infra/kyverno-policies.yaml b/infra/base/kyverno-policies.yaml similarity index 100% rename from infra/kyverno-policies.yaml rename to infra/base/kyverno-policies.yaml diff --git a/infra/kyverno.yaml b/infra/base/kyverno.yaml similarity index 100% rename from infra/kyverno.yaml rename to infra/base/kyverno.yaml diff --git a/infra/loki.yaml b/infra/base/loki.yaml similarity index 94% rename from infra/loki.yaml rename to infra/base/loki.yaml index 6d53444..9d90348 100644 --- a/infra/loki.yaml +++ b/infra/base/loki.yaml @@ -21,7 +21,7 @@ spec: helm: releaseName: loki valueFiles: - - $values/infra/values/loki-values.yaml + - $values/infra/values/base/loki-values.yaml - repoURL: git@github.com:fortedigital/sturdy-adventure.git targetRevision: HEAD diff --git a/infra/prometheus.yaml b/infra/base/prometheus.yaml similarity index 94% rename from infra/prometheus.yaml rename to infra/base/prometheus.yaml index b17436c..b6f01d0 100644 --- a/infra/prometheus.yaml +++ b/infra/base/prometheus.yaml @@ -21,7 +21,7 @@ spec: helm: releaseName: prometheus valueFiles: - - $values/infra/values/prometheus-values.yaml + - $values/infra/values/base/prometheus-values.yaml - repoURL: git@github.com:fortedigital/sturdy-adventure.git targetRevision: HEAD diff --git a/infra/sealedsecrets.yaml b/infra/base/sealedsecrets.yaml similarity index 100% rename from infra/sealedsecrets.yaml rename to infra/base/sealedsecrets.yaml diff --git a/infra/secrets.yaml b/infra/base/secrets.yaml similarity index 97% rename from infra/secrets.yaml rename to infra/base/secrets.yaml index ad1d8e9..8143603 100644 --- a/infra/secrets.yaml +++ b/infra/base/secrets.yaml @@ -18,7 +18,7 @@ spec: project: default source: repoURL: git@github.com:fortedigital/sturdy-adventure.git - path: secrets + path: secrets/eu destination: server: https://kubernetes.default.svc namespace: secrets diff --git a/infra/base/traefik-application.yaml b/infra/base/traefik-application.yaml new file mode 100644 index 0000000..b502e56 --- /dev/null +++ b/infra/base/traefik-application.yaml @@ -0,0 +1,51 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: traefik-system + annotations: + argocd.argoproj.io/sync-wave: "-1" +--- +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: traefik + namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "1" + labels: + app.kubernetes.io/name: traefik + app.kubernetes.io/part-of: platform + app.kubernetes.io/managed-by: argocd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + project: default + + sources: + - repoURL: https://traefik.github.io/charts + chart: traefik + targetRevision: "28.0.0" + helm: + releaseName: traefik + valueFiles: + - $values/infra/values/base/traefik-values.yaml + - $values/infra/values/eu/traefik-values.yaml + + - repoURL: git@github.com:fortedigital/sturdy-adventure.git + targetRevision: HEAD + ref: values + + destination: + server: https://kubernetes.default.svc + namespace: traefik-system + + syncPolicy: + automated: + prune: true + selfHeal: true + allowEmpty: false + + syncOptions: + - CreateNamespace=true + - Validate=true + - ServerSideApply=true diff --git a/infra/trivy.yaml b/infra/base/trivy.yaml similarity index 100% rename from infra/trivy.yaml rename to infra/base/trivy.yaml diff --git a/infra/overlays/eu/kustomization.yaml b/infra/overlays/eu/kustomization.yaml new file mode 100644 index 0000000..ea393bf --- /dev/null +++ b/infra/overlays/eu/kustomization.yaml @@ -0,0 +1,7 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- ../../base + +# No patches needed — base already has "eu" paths +# EU is the default/base cluster diff --git a/infra/overlays/us/kustomization.yaml b/infra/overlays/us/kustomization.yaml new file mode 100644 index 0000000..902ae74 --- /dev/null +++ b/infra/overlays/us/kustomization.yaml @@ -0,0 +1,50 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- ../../base + +patches: +# Traefik: swap eu → us in valueFiles +- target: + kind: Application + name: traefik + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/us/traefik-values.yaml + +# Keycloak: swap eu → us +- target: + kind: Application + name: keycloak + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/us/keycloak-values.yaml + +# Grafana: swap eu → us +- target: + kind: Application + name: grafana + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/us/grafana-values.yaml + +# Secrets: change path to us +- target: + kind: Application + name: secrets + patch: | + - op: replace + path: /spec/source/path + value: secrets/us + +# Enterprise-apps: point to us overlay +- target: + kind: Application + name: enterprise-apps + patch: | + - op: replace + path: /spec/source/path + value: apps/overlays/us diff --git a/infra/traefik-application.yaml b/infra/traefik-application.yaml deleted file mode 100644 index 5369608..0000000 --- a/infra/traefik-application.yaml +++ /dev/null @@ -1,130 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: traefik-system - annotations: - argocd.argoproj.io/sync-wave: "-1" ---- -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: - name: traefik - namespace: argocd - annotations: - argocd.argoproj.io/sync-wave: "1" - labels: - app.kubernetes.io/name: traefik - app.kubernetes.io/part-of: platform - app.kubernetes.io/managed-by: argocd - finalizers: - - resources-finalizer.argocd.argoproj.io -spec: - project: default - - source: - repoURL: https://traefik.github.io/charts - chart: traefik - targetRevision: "28.0.0" - - helm: - values: | - providers: - kubernetesIngress: - publishedService: # Fixes ArgoCD health checks for LoadBalancer services - enabled: true - deployment: - replicas: 2 - - ingressRoute: - dashboard: - enabled: true - # Optional: specify entrypoint - entrypoint: traefik - - api: - dashboard: true - debug: false - - service: - type: LoadBalancer - annotations: - traefik.ingress.kubernetes.io/router.entrypoints: websecure - traefik.ingress.kubernetes.io/router.priority: "42" - traefik.ingress.kubernetes.io/router.tls: "true" - service.beta.kubernetes.io/upcloud-load-balancer-config: | - { - "frontends": [ - { - "name": "web", - "mode": "tcp" - }, - { - "name": "websecure", - "mode": "tcp" - } - ], - "backends": [ - { - "name": "web", - "properties": { - "outbound_proxy_protocol": "v2" - } - }, - { - "name": "websecure", - "properties": { - "outbound_proxy_protocol": "v2" - } - } - ] - } - - ingressClass: - enabled: true - isDefaultClass: true - - # Configure entry points - ports: - metrics: - expose: - default: true - observability: - accessLogs: true - metrics: true - tracing: true - traceVerbosity: detailed - web: - proxyProtocol: - trustedIPs: "172.16.1.0/24" - forwardedHeaders: - trustedIPs: "172.16.1.0/24" - http: - redirections: - entrypoint: - to: websecure - scheme: https - - websecure: - proxyProtocol: - trustedIPs: "172.16.1.0/24" - forwardedHeaders: - trustedIPs: "172.16.1.0/24" - observability: - accessLogs: true - metrics: true - tracing: true - - destination: - server: https://kubernetes.default.svc - namespace: traefik-system - - syncPolicy: - automated: - prune: true - selfHeal: true - allowEmpty: false - - syncOptions: - - CreateNamespace=true - - Validate=true - - ServerSideApply=true diff --git a/infra/values/argocd-values.yaml b/infra/values/base/argocd-values.yaml similarity index 94% rename from infra/values/argocd-values.yaml rename to infra/values/base/argocd-values.yaml index fe5976e..f9a65f9 100644 --- a/infra/values/argocd-values.yaml +++ b/infra/values/base/argocd-values.yaml @@ -1,5 +1,3 @@ -global: - domain: argocd.127.0.0.1.nip.io configs: secret: createSecret: true @@ -26,10 +24,6 @@ notifications: secret: create: false - # Shared context variables available in all templates - context: - clusterName: "dev-fd-no-svg1" - # Define notification templates templates: template.app-syncing: | diff --git a/infra/values/base/dot-ai-stack-values.yaml b/infra/values/base/dot-ai-stack-values.yaml new file mode 100644 index 0000000..1d64e0a --- /dev/null +++ b/infra/values/base/dot-ai-stack-values.yaml @@ -0,0 +1,11 @@ +dot-ai: + ingress: + enabled: true + className: traefik +dot-ai-ui: + uiAuth: + secretRef: + name: dot-ai-secrets + ingress: + enabled: true + className: traefik diff --git a/infra/values/fluent-bit-values.yaml b/infra/values/base/fluent-bit-values.yaml similarity index 100% rename from infra/values/fluent-bit-values.yaml rename to infra/values/base/fluent-bit-values.yaml diff --git a/infra/values/grafana-values.yaml b/infra/values/base/grafana-values.yaml similarity index 99% rename from infra/values/grafana-values.yaml rename to infra/values/base/grafana-values.yaml index a83bff9..b2c8f48 100644 --- a/infra/values/grafana-values.yaml +++ b/infra/values/base/grafana-values.yaml @@ -1,7 +1,5 @@ ingress: enabled: true - hosts: - - grafana.127.0.0.1.nip.io resources: requests: cpu: 100m diff --git a/infra/values/keycloak-values.yaml b/infra/values/base/keycloak-values.yaml similarity index 95% rename from infra/values/keycloak-values.yaml rename to infra/values/base/keycloak-values.yaml index 4e0e61f..5047ee5 100644 --- a/infra/values/keycloak-values.yaml +++ b/infra/values/base/keycloak-values.yaml @@ -1,5 +1,4 @@ # Bitnami Keycloak Helm Chart Values -# Host: id.forteapps.net # Chart version: 25.2.0 image: @@ -15,7 +14,6 @@ auth: ingress: enabled: true - hostname: id.forteapps.net tls: true ingressClassName: traefik annotations: diff --git a/infra/values/loki-values.yaml b/infra/values/base/loki-values.yaml similarity index 100% rename from infra/values/loki-values.yaml rename to infra/values/base/loki-values.yaml diff --git a/infra/values/prometheus-values.yaml b/infra/values/base/prometheus-values.yaml similarity index 100% rename from infra/values/prometheus-values.yaml rename to infra/values/base/prometheus-values.yaml diff --git a/infra/values/base/traefik-values.yaml b/infra/values/base/traefik-values.yaml new file mode 100644 index 0000000..0df67ba --- /dev/null +++ b/infra/values/base/traefik-values.yaml @@ -0,0 +1,50 @@ +providers: + kubernetesIngress: + publishedService: # Fixes ArgoCD health checks for LoadBalancer services + enabled: true +deployment: + replicas: 2 + +ingressRoute: + dashboard: + enabled: true + # Optional: specify entrypoint + entrypoint: traefik + +api: + dashboard: true + debug: false + +service: + type: LoadBalancer + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.priority: "42" + traefik.ingress.kubernetes.io/router.tls: "true" + +ingressClass: + enabled: true + isDefaultClass: true + +# Configure entry points +ports: + metrics: + expose: + default: true + observability: + accessLogs: true + metrics: true + tracing: true + traceVerbosity: detailed + web: + http: + redirections: + entrypoint: + to: websecure + scheme: https + + websecure: + observability: + accessLogs: true + metrics: true + tracing: true diff --git a/infra/values/eu/argocd-values.yaml b/infra/values/eu/argocd-values.yaml new file mode 100644 index 0000000..6ed9cea --- /dev/null +++ b/infra/values/eu/argocd-values.yaml @@ -0,0 +1,5 @@ +global: + domain: argocd.127.0.0.1.nip.io +notifications: + context: + clusterName: "dev-fd-eu-no-svg1" diff --git a/infra/values/eu/dot-ai-stack-values.yaml b/infra/values/eu/dot-ai-stack-values.yaml new file mode 100644 index 0000000..f96ad02 --- /dev/null +++ b/infra/values/eu/dot-ai-stack-values.yaml @@ -0,0 +1,8 @@ +dot-ai: + ingress: + host: kubemcp.forteapps.net + webUI: + baseUrl: http://kubemcpui.forteapps.net +dot-ai-ui: + ingress: + host: kubemcpui.forteapps.net diff --git a/infra/values/eu/grafana-values.yaml b/infra/values/eu/grafana-values.yaml new file mode 100644 index 0000000..fbbe9fd --- /dev/null +++ b/infra/values/eu/grafana-values.yaml @@ -0,0 +1,3 @@ +ingress: + hosts: + - grafana.forteapps.net diff --git a/infra/values/eu/keycloak-values.yaml b/infra/values/eu/keycloak-values.yaml new file mode 100644 index 0000000..ecc2905 --- /dev/null +++ b/infra/values/eu/keycloak-values.yaml @@ -0,0 +1,2 @@ +ingress: + hostname: id.forteapps.net diff --git a/infra/values/eu/traefik-values.yaml b/infra/values/eu/traefik-values.yaml new file mode 100644 index 0000000..31f07f4 --- /dev/null +++ b/infra/values/eu/traefik-values.yaml @@ -0,0 +1,40 @@ +service: + annotations: + service.beta.kubernetes.io/upcloud-load-balancer-config: | + { + "frontends": [ + { + "name": "web", + "mode": "tcp" + }, + { + "name": "websecure", + "mode": "tcp" + } + ], + "backends": [ + { + "name": "web", + "properties": { + "outbound_proxy_protocol": "v2" + } + }, + { + "name": "websecure", + "properties": { + "outbound_proxy_protocol": "v2" + } + } + ] + } +ports: + web: + proxyProtocol: + trustedIPs: "172.16.1.0/24" + forwardedHeaders: + trustedIPs: "172.16.1.0/24" + websecure: + proxyProtocol: + trustedIPs: "172.16.1.0/24" + forwardedHeaders: + trustedIPs: "172.16.1.0/24" diff --git a/infra/values/us/argocd-values.yaml b/infra/values/us/argocd-values.yaml new file mode 100644 index 0000000..e183032 --- /dev/null +++ b/infra/values/us/argocd-values.yaml @@ -0,0 +1,5 @@ +global: + domain: argocd.us.forteapps.net +notifications: + context: + clusterName: "dev-fd-us-east1" diff --git a/infra/values/us/dot-ai-stack-values.yaml b/infra/values/us/dot-ai-stack-values.yaml new file mode 100644 index 0000000..c429d3b --- /dev/null +++ b/infra/values/us/dot-ai-stack-values.yaml @@ -0,0 +1,8 @@ +dot-ai: + ingress: + host: kubemcp.us.forteapps.net + webUI: + baseUrl: http://kubemcpui.us.forteapps.net +dot-ai-ui: + ingress: + host: kubemcpui.us.forteapps.net diff --git a/infra/values/us/grafana-values.yaml b/infra/values/us/grafana-values.yaml new file mode 100644 index 0000000..417c8c4 --- /dev/null +++ b/infra/values/us/grafana-values.yaml @@ -0,0 +1,3 @@ +ingress: + hosts: + - grafana.us.forteapps.net diff --git a/infra/values/us/keycloak-values.yaml b/infra/values/us/keycloak-values.yaml new file mode 100644 index 0000000..df05358 --- /dev/null +++ b/infra/values/us/keycloak-values.yaml @@ -0,0 +1,2 @@ +ingress: + hostname: id.us.forteapps.net diff --git a/infra/values/us/traefik-values.yaml b/infra/values/us/traefik-values.yaml new file mode 100644 index 0000000..06a9076 --- /dev/null +++ b/infra/values/us/traefik-values.yaml @@ -0,0 +1,13 @@ +service: + annotations: {} +ports: + web: + proxyProtocol: + trustedIPs: "10.0.0.0/16" + forwardedHeaders: + trustedIPs: "10.0.0.0/16" + websecure: + proxyProtocol: + trustedIPs: "10.0.0.0/16" + forwardedHeaders: + trustedIPs: "10.0.0.0/16" diff --git a/secrets/argocd-mcp-credentials.yaml b/secrets/eu/argocd-mcp-credentials.yaml similarity index 100% rename from secrets/argocd-mcp-credentials.yaml rename to secrets/eu/argocd-mcp-credentials.yaml diff --git a/secrets/argocdmcp-auth-oidc-sealed.yaml b/secrets/eu/argocdmcp-auth-oidc-sealed.yaml similarity index 100% rename from secrets/argocdmcp-auth-oidc-sealed.yaml rename to secrets/eu/argocdmcp-auth-oidc-sealed.yaml diff --git a/secrets/dot-ai-secrets.yaml b/secrets/eu/dot-ai-secrets.yaml similarity index 100% rename from secrets/dot-ai-secrets.yaml rename to secrets/eu/dot-ai-secrets.yaml diff --git a/secrets/forte10x-app-credentials-sealed.yaml b/secrets/eu/forte10x-app-credentials-sealed.yaml similarity index 100% rename from secrets/forte10x-app-credentials-sealed.yaml rename to secrets/eu/forte10x-app-credentials-sealed.yaml diff --git a/secrets/keycloak-credentials-sealed.yaml b/secrets/eu/keycloak-credentials-sealed.yaml similarity index 100% rename from secrets/keycloak-credentials-sealed.yaml rename to secrets/eu/keycloak-credentials-sealed.yaml diff --git a/secrets/musicman-credentials.yaml b/secrets/eu/musicman-credentials.yaml similarity index 100% rename from secrets/musicman-credentials.yaml rename to secrets/eu/musicman-credentials.yaml -- 2.49.1 From ac0f464b2a6d772ba77c14d8b32d099c0d5c2d98 Mon Sep 17 00:00:00 2001 From: Danijel Simeunovic Date: Thu, 19 Mar 2026 15:42:41 +0100 Subject: [PATCH 2/4] fixes --- bootstrap.sh | 8 ++++---- clusters/eu.yaml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bootstrap.sh b/bootstrap.sh index 381dfbd..89b3010 100644 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -7,7 +7,7 @@ CLUSTER="${1:?Usage: ./bootstrap.sh (eu|us)}" echo "running $0 for cluster: ${CLUSTER}..." # Source cluster config -eval $(yq e 'to_entries | .[] | "export " + .key + "=\"" + .value + "\""' "clusters/${CLUSTER}.yaml") +eval $(yq -r 'to_entries[] | "export \(.key)=\"\(.value)\""' "clusters/${CLUSTER}.yaml") echo "Bootstrapping cluster: ${clusterName} (${CLUSTER})..." @@ -27,8 +27,8 @@ Bootstrap() Github() { echo "Installing secret..." - kubectl apply -f private/github.yaml - kubectl apply -f private/main.key + kubectl apply -f private/github-${CLUSTER}.yaml + kubectl apply -f private/main-${CLUSTER}.key } ############################################################ @@ -49,4 +49,4 @@ ArgoCd() kubectl apply -f "_app-of-apps-${CLUSTER}.yaml" -n argocd } -Bootstrap +# Bootstrap diff --git a/clusters/eu.yaml b/clusters/eu.yaml index 8c02662..4813591 100644 --- a/clusters/eu.yaml +++ b/clusters/eu.yaml @@ -1,4 +1,4 @@ -clusterName: dev-fd-eu-no-svg1 +clusterName: dev-fd-no-svg1 domain: forteapps.net argocdDomain: argocd.127.0.0.1.nip.io grafanaDomain: grafana.forteapps.net -- 2.49.1 From ae1c60cee354a686589d0f80ea0617429c39cb9d Mon Sep 17 00:00:00 2001 From: Danijel Simeunovic Date: Sat, 18 Apr 2026 19:26:51 +0200 Subject: [PATCH 3/4] multi-cluster --- README.md | 38 +++-- ...-apps-eu.yaml => _app-of-apps-upc-dev.yaml | 2 +- ...apps-us.yaml => _app-of-apps-upc-prod.yaml | 2 +- apps/base/dot-ai-stack.yaml | 2 +- apps/overlays/eu/kustomization.yaml | 7 - apps/overlays/upc-dev/kustomization.yaml | 7 + .../{us => upc-prod}/kustomization.yaml | 4 +- docs/DEVELOPER-GUIDE.md | 4 +- docs/GITOPS-ARCHITECTURE.md | 146 ++++++++++-------- docs/OPERATIONS-RUNBOOK.md | 63 ++++---- docs/README.md | 4 +- docs/REFERENCE.md | 19 +-- infra/base/enterprise-apps.yaml | 2 +- infra/{ => base}/gitea-actions.yaml | 2 +- infra/{ => base}/gitea.yaml | 2 +- infra/{ => base}/grafana-dashboards.yaml | 0 infra/base/grafana.yaml | 2 +- infra/base/keycloak.yaml | 2 +- infra/base/kustomization.yaml | 6 + .../network-policies-application.yaml | 0 infra/{ => base}/renovate.yaml | 2 +- infra/base/secrets.yaml | 2 +- infra/{ => base}/tempo.yaml | 2 +- infra/base/traefik-application.yaml | 2 +- infra/overlays/eu/kustomization.yaml | 7 - infra/overlays/upc-dev/kustomization.yaml | 7 + .../{us => upc-prod}/kustomization.yaml | 20 +-- .../{ => base}/gitea-actions-values.yaml | 0 infra/values/{ => base}/gitea-values.yaml | 0 infra/values/{ => base}/opencost-values.yaml | 0 infra/values/{ => base}/renovate-values.yaml | 0 infra/values/{ => base}/tempo-values.yaml | 0 .../values/{eu => upc-dev}/argocd-values.yaml | 0 .../{eu => upc-dev}/dot-ai-stack-values.yaml | 0 .../{eu => upc-dev}/grafana-values.yaml | 0 .../{eu => upc-dev}/keycloak-values.yaml | 0 .../{eu => upc-dev}/traefik-values.yaml | 0 .../{us => upc-prod}/argocd-values.yaml | 0 .../{us => upc-prod}/dot-ai-stack-values.yaml | 0 .../{us => upc-prod}/grafana-values.yaml | 0 .../{us => upc-prod}/keycloak-values.yaml | 0 .../{us => upc-prod}/traefik-values.yaml | 0 .../argocd-mcp-credentials.yaml | 0 .../argocdmcp-auth-oidc-sealed.yaml | 0 secrets/{eu => upc-dev}/dot-ai-secrets.yaml | 0 .../forte10x-app-credentials-sealed.yaml | 0 .../keycloak-credentials-sealed.yaml | 0 .../{eu => upc-dev}/musicman-credentials.yaml | 0 48 files changed, 200 insertions(+), 156 deletions(-) rename _app-of-apps-eu.yaml => _app-of-apps-upc-dev.yaml (95%) rename _app-of-apps-us.yaml => _app-of-apps-upc-prod.yaml (95%) delete mode 100644 apps/overlays/eu/kustomization.yaml create mode 100644 apps/overlays/upc-dev/kustomization.yaml rename apps/overlays/{us => upc-prod}/kustomization.yaml (67%) rename infra/{ => base}/gitea-actions.yaml (94%) rename infra/{ => base}/gitea.yaml (95%) rename infra/{ => base}/grafana-dashboards.yaml (100%) rename infra/{ => base}/network-policies-application.yaml (100%) rename infra/{ => base}/renovate.yaml (94%) rename infra/{ => base}/tempo.yaml (94%) delete mode 100644 infra/overlays/eu/kustomization.yaml create mode 100644 infra/overlays/upc-dev/kustomization.yaml rename infra/overlays/{us => upc-prod}/kustomization.yaml (60%) rename infra/values/{ => base}/gitea-actions-values.yaml (100%) rename infra/values/{ => base}/gitea-values.yaml (100%) rename infra/values/{ => base}/opencost-values.yaml (100%) rename infra/values/{ => base}/renovate-values.yaml (100%) rename infra/values/{ => base}/tempo-values.yaml (100%) rename infra/values/{eu => upc-dev}/argocd-values.yaml (100%) rename infra/values/{eu => upc-dev}/dot-ai-stack-values.yaml (100%) rename infra/values/{eu => upc-dev}/grafana-values.yaml (100%) rename infra/values/{eu => upc-dev}/keycloak-values.yaml (100%) rename infra/values/{eu => upc-dev}/traefik-values.yaml (100%) rename infra/values/{us => upc-prod}/argocd-values.yaml (100%) rename infra/values/{us => upc-prod}/dot-ai-stack-values.yaml (100%) rename infra/values/{us => upc-prod}/grafana-values.yaml (100%) rename infra/values/{us => upc-prod}/keycloak-values.yaml (100%) rename infra/values/{us => upc-prod}/traefik-values.yaml (100%) rename secrets/{eu => upc-dev}/argocd-mcp-credentials.yaml (100%) rename secrets/{eu => upc-dev}/argocdmcp-auth-oidc-sealed.yaml (100%) rename secrets/{eu => upc-dev}/dot-ai-secrets.yaml (100%) rename secrets/{eu => upc-dev}/forte10x-app-credentials-sealed.yaml (100%) rename secrets/{eu => upc-dev}/keycloak-credentials-sealed.yaml (100%) rename secrets/{eu => upc-dev}/musicman-credentials.yaml (100%) diff --git a/README.md b/README.md index 1dea06c..9095ee0 100644 --- a/README.md +++ b/README.md @@ -83,20 +83,26 @@ This repository contains the complete GitOps configuration for our Kubernetes cl ├── bootstrap.sh # Cluster initialization script ├── _app-of-apps.yaml # Root ArgoCD Application (App-of-Apps pattern) │ -├── infra/ # Infrastructure ArgoCD Applications -│ ├── enterprise-apps.yaml # Manages all apps in apps/ folder -│ ├── traefik-application.yaml -│ ├── cert-manager-application.yaml -│ ├── kyverno.yaml -│ ├── prometheus.yaml -│ ├── grafana.yaml -│ ├── loki.yaml -│ ├── tempo.yaml -│ ├── fluent-bit.yaml -│ ├── trivy.yaml -│ ├── sealedsecrets.yaml -│ ├── renovate.yaml +├── infra/ # Infrastructure ArgoCD Applications (Kustomize multi-cluster) +│ ├── base/ # Base ArgoCD Application manifests (EU defaults) +│ │ ├── kustomization.yaml +│ │ ├── traefik-application.yaml +│ │ ├── keycloak.yaml +│ │ ├── grafana.yaml +│ │ ├── gitea.yaml +│ │ ├── gitea-actions.yaml +│ │ ├── tempo.yaml +│ │ ├── renovate.yaml +│ │ ├── ... # All other Application manifests +│ │ └── secrets.yaml +│ ├── overlays/ # Per-cluster overrides +│ │ ├── upc-dev/ # UpCloud Dev cluster (uses base as-is) +│ │ └── upc-prod/ # UpCloud Prod cluster (patches value paths) +│ ├── dashboards/ # Grafana dashboard ConfigMaps │ └── values/ # Helm value overrides +│ ├── base/ # Shared values (all clusters) +│ ├── upc-dev/ # UpCloud Dev-specific values +│ └── upc-prod/ # UpCloud Prod-specific values │ ├── apps/ # Business Applications │ ├── mcp10x.yaml @@ -355,7 +361,7 @@ kubectl patch application myapp -n argocd \ ## 📖 Key Concepts ### App-of-Apps Pattern -`_app-of-apps.yaml` is the root Application that manages all other Applications in `infra/`. Each YAML in `infra/` becomes a child Application managed by ArgoCD. +`_app-of-apps.yaml` is the root Application that manages all other Applications in `infra/`. Kustomize overlays in `infra/overlays/{upc-dev,upc-prod}/` render the base Applications with per-cluster patches (e.g., swapping value file paths from `upc-dev` to `upc-prod`). ### Multi-Source Pattern Applications reference both: @@ -454,14 +460,14 @@ Documentation lives in `docs/`. To update: ### Current Environment - **Provider**: UpCloud Managed Kubernetes - **Environment**: Production (internal use only) -- **Cluster**: Single cluster +- **Clusters**: Multi-cluster (upc-dev, upc-prod) via Kustomize overlays - **Auth**: Disabled for ArgoCD (internal access) - **Backup**: None (cluster rebuildable via GitOps) ### Known Limitations - No automated backups (yet) - Secret rotation not automated -- Single cluster (no multi-cluster setup) +- Multi-cluster limited to upc-dev and upc-prod environments - DNS management is manual **Future improvements**: See [Operations Runbook - Disaster Recovery](docs/OPERATIONS-RUNBOOK.md#disaster-recovery) diff --git a/_app-of-apps-eu.yaml b/_app-of-apps-upc-dev.yaml similarity index 95% rename from _app-of-apps-eu.yaml rename to _app-of-apps-upc-dev.yaml index f38ebde..b352c3d 100644 --- a/_app-of-apps-eu.yaml +++ b/_app-of-apps-upc-dev.yaml @@ -20,7 +20,7 @@ spec: source: repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git targetRevision: HEAD - path: infra/overlays/eu + path: infra/overlays/upc-dev destination: server: https://kubernetes.default.svc namespace: default diff --git a/_app-of-apps-us.yaml b/_app-of-apps-upc-prod.yaml similarity index 95% rename from _app-of-apps-us.yaml rename to _app-of-apps-upc-prod.yaml index 95317b3..f5ccaca 100644 --- a/_app-of-apps-us.yaml +++ b/_app-of-apps-upc-prod.yaml @@ -20,7 +20,7 @@ spec: source: repoURL: git@github.com:fortedigital/sturdy-adventure.git targetRevision: HEAD - path: infra/overlays/us + path: infra/overlays/upc-prod destination: server: https://kubernetes.default.svc namespace: default diff --git a/apps/base/dot-ai-stack.yaml b/apps/base/dot-ai-stack.yaml index f322e35..3fd1284 100644 --- a/apps/base/dot-ai-stack.yaml +++ b/apps/base/dot-ai-stack.yaml @@ -35,7 +35,7 @@ spec: releaseName: dot-ai-stack valueFiles: - $values/infra/values/base/dot-ai-stack-values.yaml - - $values/infra/values/eu/dot-ai-stack-values.yaml + - $values/infra/values/upc-dev/dot-ai-stack-values.yaml - repoURL: git@github.com:fortedigital/sturdy-adventure.git targetRevision: HEAD diff --git a/apps/overlays/eu/kustomization.yaml b/apps/overlays/eu/kustomization.yaml deleted file mode 100644 index ea393bf..0000000 --- a/apps/overlays/eu/kustomization.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: -- ../../base - -# No patches needed — base already has "eu" paths -# EU is the default/base cluster diff --git a/apps/overlays/upc-dev/kustomization.yaml b/apps/overlays/upc-dev/kustomization.yaml new file mode 100644 index 0000000..1895aac --- /dev/null +++ b/apps/overlays/upc-dev/kustomization.yaml @@ -0,0 +1,7 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- ../../base + +# No patches needed — base already has "upc-dev" paths +# upc-dev is the default/base cluster diff --git a/apps/overlays/us/kustomization.yaml b/apps/overlays/upc-prod/kustomization.yaml similarity index 67% rename from apps/overlays/us/kustomization.yaml rename to apps/overlays/upc-prod/kustomization.yaml index 0c93339..79e912b 100644 --- a/apps/overlays/us/kustomization.yaml +++ b/apps/overlays/upc-prod/kustomization.yaml @@ -4,11 +4,11 @@ resources: - ../../base patches: -# dot-ai-stack: swap eu → us +# dot-ai-stack: swap upc-dev → upc-prod - target: kind: Application name: dot-ai-stack patch: | - op: replace path: /spec/sources/0/helm/valueFiles/1 - value: $values/infra/values/us/dot-ai-stack-values.yaml + value: $values/infra/values/upc-prod/dot-ai-stack-values.yaml diff --git a/docs/DEVELOPER-GUIDE.md b/docs/DEVELOPER-GUIDE.md index 27b7ddc..9a2f127 100644 --- a/docs/DEVELOPER-GUIDE.md +++ b/docs/DEVELOPER-GUIDE.md @@ -1364,7 +1364,7 @@ Existing clients (like Gitea) are defined directly in `forte-realm.json` inside #### Step 1: Add Client to Realm Config -In `infra/values/keycloak-values.yaml`, add a new entry to the `clients` array in `forte-realm.json`: +In `infra/values/base/keycloak-values.yaml`, add a new entry to the `clients` array in `forte-realm.json`: ```json { @@ -1404,7 +1404,7 @@ existingSecret: myapp-oidc-credentials ```bash cd ~/dev/k8s/launchpad -git add infra/values/keycloak-values.yaml +git add infra/values/base/keycloak-values.yaml git commit -m "Add myapp Keycloak client with auto-sync" git push ``` diff --git a/docs/GITOPS-ARCHITECTURE.md b/docs/GITOPS-ARCHITECTURE.md index e663979..c1e3207 100644 --- a/docs/GITOPS-ARCHITECTURE.md +++ b/docs/GITOPS-ARCHITECTURE.md @@ -16,7 +16,7 @@ This Kubernetes cluster uses a **GitOps approach** powered by **ArgoCD**, where ### Key Characteristics - **Environment**: Production (internal use only) -- **Cluster Type**: Single cluster, single environment +- **Cluster Type**: Multi-cluster (upc-dev, upc-prod) via Kustomize overlays - **GitOps Tool**: ArgoCD - **Deployment Pattern**: App-of-Apps - **Secret Management**: Sealed Secrets (kubeseal) @@ -62,8 +62,8 @@ This Kubernetes cluster uses a **GitOps approach** powered by **ArgoCD**, where │ ▼ ┌────────────────────────────────┐ - │ Kubernetes Cluster │ - │ (UpCloud Managed) │ + │ Kubernetes Clusters │ + │ (UpCloud: upc-dev, upc-prod) │ │ │ │ ┌──────────────────────────┐ │ │ │ ArgoCD │ │ @@ -116,74 +116,68 @@ This Kubernetes cluster uses a **GitOps approach** powered by **ArgoCD**, where ``` launchpad/ ├── bootstrap.sh # Cluster initialization script -├── _app-of-apps.yaml # Root ArgoCD Application (App-of-Apps pattern) +├── _app-of-apps-upc-dev.yaml # Root ArgoCD Application (upc-dev cluster) +├── _app-of-apps-upc-prod.yaml # Root ArgoCD Application (upc-prod cluster) │ -├── infra/ # Infrastructure ArgoCD Applications -│ ├── enterprise-apps.yaml # Parent app managing all apps in apps/ -│ ├── cluster-resources-application.yaml -│ ├── traefik-application.yaml -│ ├── cert-manager-application.yaml -│ ├── kyverno.yaml -│ ├── kyverno-policies.yaml -│ ├── prometheus.yaml -│ ├── grafana.yaml -│ ├── loki.yaml -│ ├── tempo.yaml -│ ├── fluent-bit.yaml -│ ├── trivy.yaml -│ ├── sealedsecrets.yaml -│ ├── secrets.yaml +├── infra/ # Infrastructure ArgoCD Applications (Kustomize) +│ ├── base/ # Base Application manifests (upc-dev defaults) +│ │ ├── kustomization.yaml +│ │ ├── traefik-application.yaml +│ │ ├── keycloak.yaml +│ │ ├── grafana.yaml +│ │ ├── gitea.yaml +│ │ ├── gitea-actions.yaml +│ │ ├── tempo.yaml +│ │ ├── renovate.yaml +│ │ ├── ... # All other Application manifests +│ │ └── secrets.yaml +│ ├── overlays/ # Per-cluster overrides +│ │ ├── upc-dev/ # UpCloud Dev (uses base as-is) +│ │ └── upc-prod/ # UpCloud Prod (patches value paths) +│ ├── dashboards/ # Grafana dashboard ConfigMaps │ └── values/ # Helm value overrides for infra -│ ├── argocd-values.yaml -│ ├── prometheus-values.yaml -│ ├── grafana-values.yaml -│ ├── loki-values.yaml -│ ├── tempo-values.yaml -│ └── fluent-bit-values.yaml +│ ├── base/ # Shared values (all clusters) +│ │ ├── traefik-values.yaml +│ │ ├── keycloak-values.yaml +│ │ ├── grafana-values.yaml +│ │ ├── prometheus-values.yaml +│ │ ├── gitea-values.yaml +│ │ └── ... +│ ├── upc-dev/ # upc-dev cluster-specific values +│ │ ├── traefik-values.yaml +│ │ ├── keycloak-values.yaml +│ │ └── grafana-values.yaml +│ └── upc-prod/ # upc-prod cluster-specific values +│ ├── traefik-values.yaml +│ ├── keycloak-values.yaml +│ └── grafana-values.yaml │ -├── apps/ # Business Application ArgoCD manifests -│ ├── mcp10x.yaml # MCP 10X application -│ ├── musicman.yaml # Music Man application -│ ├── dot-ai-stack.yaml # Dot AI Stack -│ └── argo-mcp.yaml # ArgoCD MCP server +├── apps/ # Business Application ArgoCD manifests (Kustomize) +│ ├── base/ # Base app manifests +│ │ ├── kustomization.yaml +│ │ ├── dot-ai-stack.yaml +│ │ └── ... +│ └── overlays/ +│ ├── upc-dev/ # Uses base as-is +│ └── upc-prod/ # Patches value paths │ ├── cluster-resources/ # Cluster-wide Kubernetes resources -│ ├── cert-manager-namespace.yaml -│ ├── secrets-namespace.yaml -│ ├── letsencrypt-issuer.yaml # Let's Encrypt ClusterIssuer -│ ├── kyverno-config.yaml -│ ├── argocd-notifications-secret-sealed.yaml -│ ├── forte10x-repo-credentials-sealed.yaml -│ ├── mcp10x-repo-credentials-sealed.yaml +│ ├── ... │ └── policies/ # Kyverno policies -│ ├── deployment-verifier.yaml -│ ├── label-checker.yaml -│ ├── bare-pod-cleaner.yaml -│ ├── replicaset-cleaner.yaml -│ ├── default-ns-blocker.yaml -│ ├── secret-cloner.yaml -│ └── auth-sidecar-injector.yaml │ -├── secrets/ # Application secrets (sealed) -│ ├── argocd-mcp-credentials.yaml -│ ├── dot-ai-secrets.yaml -│ ├── mcp10x-credentials-sealed.yaml -│ └── musicman-credentials.yaml +├── secrets/ # Application secrets (sealed, per-cluster) +│ └── upc-dev/ # Secrets for upc-dev cluster │ ├── private/ # Local-only files (NOT in Git) -│ ├── *.yaml # Unsealed secrets -│ └── *.sh # Helper scripts │ └── docs/ # Documentation - ├── GITOPS-ARCHITECTURE.md # This file - ├── DEVELOPER-GUIDE.md - ├── OPERATIONS-RUNBOOK.md - └── REFERENCE.md ``` **Key Points**: -- `_app-of-apps.yaml` is the root Application that ArgoCD monitors -- `infra/enterprise-apps.yaml` auto-discovers all apps in `apps/` folder +- `_app-of-apps-upc-dev.yaml` and `_app-of-apps-upc-prod.yaml` are the per-cluster root Applications +- Kustomize overlays in `infra/overlays/` render base Applications with per-cluster patches +- Helm values are split: `values/base/` (shared) + `values/upc-dev/` or `values/upc-prod/` (cluster-specific) +- `apps/` follows the same base/overlays pattern for business applications - Changes pushed to this repo trigger automatic syncs in ArgoCD - `private/` folder contains local-only files (Git-ignored) @@ -295,7 +289,7 @@ app-repository/ ### The App-of-Apps Pattern ``` -_app-of-apps.yaml (Root) +_app-of-apps-{upc-dev,upc-prod}.yaml (Root, per cluster) │ ├── infrastructure-apps (manages infra/) │ ├── cluster-resources-application @@ -315,10 +309,10 @@ _app-of-apps.yaml (Root) ``` **How It Works**: -1. Bootstrap script installs ArgoCD and applies `_app-of-apps.yaml` -2. ArgoCD creates the root Application which monitors `infra/` folder -3. Each YAML in `infra/` becomes a child Application -4. `enterprise-apps.yaml` monitors `apps/` folder and auto-discovers applications +1. Bootstrap script installs ArgoCD and applies `_app-of-apps-upc-dev.yaml` (or `upc-prod`) +2. ArgoCD creates the root Application which monitors the appropriate `infra/overlays/` folder +3. Kustomize renders base Applications with cluster-specific patches +4. `enterprise-apps` Application monitors the cluster's `apps/overlays/` folder 5. ArgoCD continuously syncs (every 60s) and auto-heals drift ### Sync Waves & Ordering @@ -363,6 +357,34 @@ spec: - Easy to update all apps by changing the chart - Environment-specific values isolated in separate repo +### Multi-Cluster Pattern + +Kustomize overlays enable deploying the same Applications across clusters with different configurations: + +```yaml +# infra/base/ contains default (upc-dev) Applications +# Helm values are layered: base + cluster-specific +valueFiles: +- $values/infra/values/base/traefik-values.yaml # Shared config +- $values/infra/values/upc-dev/traefik-values.yaml # Cluster-specific + +# infra/overlays/upc-prod/kustomization.yaml patches the second valueFile +patches: +- target: + kind: Application + name: traefik + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/upc-prod/traefik-values.yaml +``` + +**Benefits**: +- Single source of truth for Application definitions +- Cluster-specific values isolated per overlay +- Easy to add new clusters by creating a new overlay +- Base values shared across all clusters reduce duplication + --- ## CI/CD Pipeline diff --git a/docs/OPERATIONS-RUNBOOK.md b/docs/OPERATIONS-RUNBOOK.md index 9ff6f9f..822ba97 100644 --- a/docs/OPERATIONS-RUNBOOK.md +++ b/docs/OPERATIONS-RUNBOOK.md @@ -207,7 +207,7 @@ kubectl get secrets -n argocd -l argocd.argoproj.io/secret-type=repository # Settings → Repositories → Should show "Successful" status # Test by creating an application -kubectl apply -f _app-of-apps.yaml +kubectl apply -f _app-of-apps-upc-dev.yaml # or _app-of-apps-upc-prod.yaml # Check application sync status kubectl get applications -n argocd @@ -1352,13 +1352,13 @@ kubectl get deployment argocd-server -n argocd \ -o jsonpath='{.spec.template.spec.containers[0].image}' # Update version in values -vim infra/values/argocd-values.yaml +vim infra/values/base/argocd-values.yaml # Or upgrade via Helm directly helm upgrade argocd argo-cd \ --repo https://argoproj.github.io/argo-helm \ --namespace argocd \ - --values infra/values/argocd-values.yaml \ + --values infra/values/base/argocd-values.yaml \ --version 6.0.0 # New version # Verify @@ -1454,8 +1454,8 @@ kubectl top pods --all-namespaces --sort-by=cpu Example: Adding Redis ```bash -# 1. Create application manifest -cat > infra/redis-application.yaml < infra/base/redis-application.yaml < infra/values/base/redis-values.yaml < -n keycloak -o jsonpath='{.metadata.ann **Configuration**: ```yaml -# infra/renovate.yaml + infra/values/renovate-values.yaml +# infra/base/renovate.yaml + infra/values/base/renovate-values.yaml cronjob: schedule: "@daily" concurrencyPolicy: Forbid diff --git a/infra/base/enterprise-apps.yaml b/infra/base/enterprise-apps.yaml index d843b39..40763cb 100644 --- a/infra/base/enterprise-apps.yaml +++ b/infra/base/enterprise-apps.yaml @@ -18,7 +18,7 @@ spec: source: repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git targetRevision: HEAD - path: apps/overlays/eu + path: apps/overlays/upc-dev destination: server: https://kubernetes.default.svc namespace: apps diff --git a/infra/gitea-actions.yaml b/infra/base/gitea-actions.yaml similarity index 94% rename from infra/gitea-actions.yaml rename to infra/base/gitea-actions.yaml index 1531d69..ae29f29 100644 --- a/infra/gitea-actions.yaml +++ b/infra/base/gitea-actions.yaml @@ -21,7 +21,7 @@ spec: helm: releaseName: gitea-actions valueFiles: - - $values/infra/values/gitea-actions-values.yaml + - $values/infra/values/base/gitea-actions-values.yaml - repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git targetRevision: HEAD diff --git a/infra/gitea.yaml b/infra/base/gitea.yaml similarity index 95% rename from infra/gitea.yaml rename to infra/base/gitea.yaml index f0c5209..ba806f5 100644 --- a/infra/gitea.yaml +++ b/infra/base/gitea.yaml @@ -21,7 +21,7 @@ spec: helm: releaseName: gitea valueFiles: - - $values/infra/values/gitea-values.yaml + - $values/infra/values/base/gitea-values.yaml - repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git targetRevision: HEAD diff --git a/infra/grafana-dashboards.yaml b/infra/base/grafana-dashboards.yaml similarity index 100% rename from infra/grafana-dashboards.yaml rename to infra/base/grafana-dashboards.yaml diff --git a/infra/base/grafana.yaml b/infra/base/grafana.yaml index 5f18399..3e17373 100644 --- a/infra/base/grafana.yaml +++ b/infra/base/grafana.yaml @@ -22,7 +22,7 @@ spec: releaseName: grafana valueFiles: - $values/infra/values/base/grafana-values.yaml - - $values/infra/values/eu/grafana-values.yaml + - $values/infra/values/upc-dev/grafana-values.yaml - repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git targetRevision: HEAD diff --git a/infra/base/keycloak.yaml b/infra/base/keycloak.yaml index ded2964..a3234d8 100644 --- a/infra/base/keycloak.yaml +++ b/infra/base/keycloak.yaml @@ -22,7 +22,7 @@ spec: releaseName: keycloak valueFiles: - $values/infra/values/base/keycloak-values.yaml - - $values/infra/values/eu/keycloak-values.yaml + - $values/infra/values/upc-dev/keycloak-values.yaml - repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git targetRevision: HEAD diff --git a/infra/base/kustomization.yaml b/infra/base/kustomization.yaml index adb38e1..e60eb3c 100644 --- a/infra/base/kustomization.yaml +++ b/infra/base/kustomization.yaml @@ -15,3 +15,9 @@ resources: - cluster-resources-application.yaml - kyverno-policies.yaml - secrets.yaml +- gitea.yaml +- gitea-actions.yaml +- renovate.yaml +- tempo.yaml +- grafana-dashboards.yaml +- network-policies-application.yaml diff --git a/infra/network-policies-application.yaml b/infra/base/network-policies-application.yaml similarity index 100% rename from infra/network-policies-application.yaml rename to infra/base/network-policies-application.yaml diff --git a/infra/renovate.yaml b/infra/base/renovate.yaml similarity index 94% rename from infra/renovate.yaml rename to infra/base/renovate.yaml index bc1d34e..4cf87e4 100644 --- a/infra/renovate.yaml +++ b/infra/base/renovate.yaml @@ -21,7 +21,7 @@ spec: helm: releaseName: renovate valueFiles: - - $values/infra/values/renovate-values.yaml + - $values/infra/values/base/renovate-values.yaml - repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git targetRevision: HEAD diff --git a/infra/base/secrets.yaml b/infra/base/secrets.yaml index 0e14c6a..7eb57f9 100644 --- a/infra/base/secrets.yaml +++ b/infra/base/secrets.yaml @@ -18,7 +18,7 @@ spec: project: default source: repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git - path: secrets/eu + path: secrets/upc-dev destination: server: https://kubernetes.default.svc namespace: secrets diff --git a/infra/tempo.yaml b/infra/base/tempo.yaml similarity index 94% rename from infra/tempo.yaml rename to infra/base/tempo.yaml index 1ce4fbb..0a0c09b 100644 --- a/infra/tempo.yaml +++ b/infra/base/tempo.yaml @@ -21,7 +21,7 @@ spec: helm: releaseName: tempo valueFiles: - - $values/infra/values/tempo-values.yaml + - $values/infra/values/base/tempo-values.yaml - repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git targetRevision: HEAD diff --git a/infra/base/traefik-application.yaml b/infra/base/traefik-application.yaml index b502e56..eb9fd2c 100644 --- a/infra/base/traefik-application.yaml +++ b/infra/base/traefik-application.yaml @@ -29,7 +29,7 @@ spec: releaseName: traefik valueFiles: - $values/infra/values/base/traefik-values.yaml - - $values/infra/values/eu/traefik-values.yaml + - $values/infra/values/upc-dev/traefik-values.yaml - repoURL: git@github.com:fortedigital/sturdy-adventure.git targetRevision: HEAD diff --git a/infra/overlays/eu/kustomization.yaml b/infra/overlays/eu/kustomization.yaml deleted file mode 100644 index ea393bf..0000000 --- a/infra/overlays/eu/kustomization.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: -- ../../base - -# No patches needed — base already has "eu" paths -# EU is the default/base cluster diff --git a/infra/overlays/upc-dev/kustomization.yaml b/infra/overlays/upc-dev/kustomization.yaml new file mode 100644 index 0000000..1895aac --- /dev/null +++ b/infra/overlays/upc-dev/kustomization.yaml @@ -0,0 +1,7 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- ../../base + +# No patches needed — base already has "upc-dev" paths +# upc-dev is the default/base cluster diff --git a/infra/overlays/us/kustomization.yaml b/infra/overlays/upc-prod/kustomization.yaml similarity index 60% rename from infra/overlays/us/kustomization.yaml rename to infra/overlays/upc-prod/kustomization.yaml index 902ae74..ebfc179 100644 --- a/infra/overlays/us/kustomization.yaml +++ b/infra/overlays/upc-prod/kustomization.yaml @@ -4,47 +4,47 @@ resources: - ../../base patches: -# Traefik: swap eu → us in valueFiles +# Traefik: swap upc-dev → upc-prod in valueFiles - target: kind: Application name: traefik patch: | - op: replace path: /spec/sources/0/helm/valueFiles/1 - value: $values/infra/values/us/traefik-values.yaml + value: $values/infra/values/upc-prod/traefik-values.yaml -# Keycloak: swap eu → us +# Keycloak: swap upc-dev → upc-prod - target: kind: Application name: keycloak patch: | - op: replace path: /spec/sources/0/helm/valueFiles/1 - value: $values/infra/values/us/keycloak-values.yaml + value: $values/infra/values/upc-prod/keycloak-values.yaml -# Grafana: swap eu → us +# Grafana: swap upc-dev → upc-prod - target: kind: Application name: grafana patch: | - op: replace path: /spec/sources/0/helm/valueFiles/1 - value: $values/infra/values/us/grafana-values.yaml + value: $values/infra/values/upc-prod/grafana-values.yaml -# Secrets: change path to us +# Secrets: change path to upc-prod - target: kind: Application name: secrets patch: | - op: replace path: /spec/source/path - value: secrets/us + value: secrets/upc-prod -# Enterprise-apps: point to us overlay +# Enterprise-apps: point to upc-prod overlay - target: kind: Application name: enterprise-apps patch: | - op: replace path: /spec/source/path - value: apps/overlays/us + value: apps/overlays/upc-prod diff --git a/infra/values/gitea-actions-values.yaml b/infra/values/base/gitea-actions-values.yaml similarity index 100% rename from infra/values/gitea-actions-values.yaml rename to infra/values/base/gitea-actions-values.yaml diff --git a/infra/values/gitea-values.yaml b/infra/values/base/gitea-values.yaml similarity index 100% rename from infra/values/gitea-values.yaml rename to infra/values/base/gitea-values.yaml diff --git a/infra/values/opencost-values.yaml b/infra/values/base/opencost-values.yaml similarity index 100% rename from infra/values/opencost-values.yaml rename to infra/values/base/opencost-values.yaml diff --git a/infra/values/renovate-values.yaml b/infra/values/base/renovate-values.yaml similarity index 100% rename from infra/values/renovate-values.yaml rename to infra/values/base/renovate-values.yaml diff --git a/infra/values/tempo-values.yaml b/infra/values/base/tempo-values.yaml similarity index 100% rename from infra/values/tempo-values.yaml rename to infra/values/base/tempo-values.yaml diff --git a/infra/values/eu/argocd-values.yaml b/infra/values/upc-dev/argocd-values.yaml similarity index 100% rename from infra/values/eu/argocd-values.yaml rename to infra/values/upc-dev/argocd-values.yaml diff --git a/infra/values/eu/dot-ai-stack-values.yaml b/infra/values/upc-dev/dot-ai-stack-values.yaml similarity index 100% rename from infra/values/eu/dot-ai-stack-values.yaml rename to infra/values/upc-dev/dot-ai-stack-values.yaml diff --git a/infra/values/eu/grafana-values.yaml b/infra/values/upc-dev/grafana-values.yaml similarity index 100% rename from infra/values/eu/grafana-values.yaml rename to infra/values/upc-dev/grafana-values.yaml diff --git a/infra/values/eu/keycloak-values.yaml b/infra/values/upc-dev/keycloak-values.yaml similarity index 100% rename from infra/values/eu/keycloak-values.yaml rename to infra/values/upc-dev/keycloak-values.yaml diff --git a/infra/values/eu/traefik-values.yaml b/infra/values/upc-dev/traefik-values.yaml similarity index 100% rename from infra/values/eu/traefik-values.yaml rename to infra/values/upc-dev/traefik-values.yaml diff --git a/infra/values/us/argocd-values.yaml b/infra/values/upc-prod/argocd-values.yaml similarity index 100% rename from infra/values/us/argocd-values.yaml rename to infra/values/upc-prod/argocd-values.yaml diff --git a/infra/values/us/dot-ai-stack-values.yaml b/infra/values/upc-prod/dot-ai-stack-values.yaml similarity index 100% rename from infra/values/us/dot-ai-stack-values.yaml rename to infra/values/upc-prod/dot-ai-stack-values.yaml diff --git a/infra/values/us/grafana-values.yaml b/infra/values/upc-prod/grafana-values.yaml similarity index 100% rename from infra/values/us/grafana-values.yaml rename to infra/values/upc-prod/grafana-values.yaml diff --git a/infra/values/us/keycloak-values.yaml b/infra/values/upc-prod/keycloak-values.yaml similarity index 100% rename from infra/values/us/keycloak-values.yaml rename to infra/values/upc-prod/keycloak-values.yaml diff --git a/infra/values/us/traefik-values.yaml b/infra/values/upc-prod/traefik-values.yaml similarity index 100% rename from infra/values/us/traefik-values.yaml rename to infra/values/upc-prod/traefik-values.yaml diff --git a/secrets/eu/argocd-mcp-credentials.yaml b/secrets/upc-dev/argocd-mcp-credentials.yaml similarity index 100% rename from secrets/eu/argocd-mcp-credentials.yaml rename to secrets/upc-dev/argocd-mcp-credentials.yaml diff --git a/secrets/eu/argocdmcp-auth-oidc-sealed.yaml b/secrets/upc-dev/argocdmcp-auth-oidc-sealed.yaml similarity index 100% rename from secrets/eu/argocdmcp-auth-oidc-sealed.yaml rename to secrets/upc-dev/argocdmcp-auth-oidc-sealed.yaml diff --git a/secrets/eu/dot-ai-secrets.yaml b/secrets/upc-dev/dot-ai-secrets.yaml similarity index 100% rename from secrets/eu/dot-ai-secrets.yaml rename to secrets/upc-dev/dot-ai-secrets.yaml diff --git a/secrets/eu/forte10x-app-credentials-sealed.yaml b/secrets/upc-dev/forte10x-app-credentials-sealed.yaml similarity index 100% rename from secrets/eu/forte10x-app-credentials-sealed.yaml rename to secrets/upc-dev/forte10x-app-credentials-sealed.yaml diff --git a/secrets/eu/keycloak-credentials-sealed.yaml b/secrets/upc-dev/keycloak-credentials-sealed.yaml similarity index 100% rename from secrets/eu/keycloak-credentials-sealed.yaml rename to secrets/upc-dev/keycloak-credentials-sealed.yaml diff --git a/secrets/eu/musicman-credentials.yaml b/secrets/upc-dev/musicman-credentials.yaml similarity index 100% rename from secrets/eu/musicman-credentials.yaml rename to secrets/upc-dev/musicman-credentials.yaml -- 2.49.1 From 15b2fe10108dee77ca17d5a49e16ad2e76ed068b Mon Sep 17 00:00:00 2001 From: Danijel Simeunovic Date: Sat, 18 Apr 2026 19:29:59 +0200 Subject: [PATCH 4/4] clusters --- clusters/{eu.yaml => upc-dev.yaml} | 0 clusters/{us.yaml => upc-prod.yaml} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename clusters/{eu.yaml => upc-dev.yaml} (100%) rename clusters/{us.yaml => upc-prod.yaml} (100%) diff --git a/clusters/eu.yaml b/clusters/upc-dev.yaml similarity index 100% rename from clusters/eu.yaml rename to clusters/upc-dev.yaml diff --git a/clusters/us.yaml b/clusters/upc-prod.yaml similarity index 100% rename from clusters/us.yaml rename to clusters/upc-prod.yaml -- 2.49.1