From cab0866e14749b9b00efa88dfe5a740d1f9ad10e Mon Sep 17 00:00:00 2001 From: Danijel Simeunovic Date: Wed, 22 Apr 2026 13:31:09 +0200 Subject: [PATCH 1/9] multi-cloud no mcp --- README.md | 40 +++++--- _app-of-apps-aws-dev.yaml | 32 ++++++ _app-of-apps-aws-prod.yaml | 32 ++++++ _app-of-apps-azure-dev.yaml | 32 ++++++ _app-of-apps-azure-prod.yaml | 32 ++++++ _app-of-apps-gcp-dev.yaml | 32 ++++++ _app-of-apps-gcp-prod.yaml | 32 ++++++ cluster-resources/gitea-backup-cronjob.yaml | 6 +- clusters/aws-dev.yaml | 10 ++ clusters/aws-prod.yaml | 10 ++ clusters/azure-dev.yaml | 10 ++ clusters/azure-prod.yaml | 10 ++ clusters/gcp-dev.yaml | 10 ++ clusters/gcp-prod.yaml | 10 ++ docs/GITOPS-ARCHITECTURE.md | 49 +++++---- docs/OPERATIONS-RUNBOOK.md | 68 +++++++++---- docs/README.md | 11 +- docs/REFERENCE.md | 22 ++-- infra/base/gitea.yaml | 1 + infra/base/opencost.yaml | 1 + infra/overlays/aws-dev/kustomization.yaml | 35 +++++++ infra/overlays/aws-prod/kustomization.yaml | 35 +++++++ infra/overlays/azure-dev/kustomization.yaml | 35 +++++++ infra/overlays/azure-prod/kustomization.yaml | 35 +++++++ infra/overlays/gcp-dev/kustomization.yaml | 35 +++++++ infra/overlays/gcp-prod/kustomization.yaml | 35 +++++++ infra/overlays/upc-prod/kustomization.yaml | 18 ++++ infra/values/aws-dev/gitea-values.yaml | 7 ++ infra/values/aws-dev/opencost-values.yaml | 13 +++ infra/values/aws-dev/traefik-values.yaml | 18 ++++ infra/values/aws-prod/gitea-values.yaml | 7 ++ infra/values/aws-prod/opencost-values.yaml | 13 +++ infra/values/aws-prod/traefik-values.yaml | 18 ++++ infra/values/azure-dev/gitea-values.yaml | 7 ++ infra/values/azure-dev/opencost-values.yaml | 11 ++ infra/values/azure-dev/traefik-values.yaml | 16 +++ infra/values/azure-prod/gitea-values.yaml | 7 ++ infra/values/azure-prod/opencost-values.yaml | 11 ++ infra/values/azure-prod/traefik-values.yaml | 16 +++ infra/values/base/gitea-values.yaml | 2 - infra/values/base/opencost-values.yaml | 14 +-- infra/values/gcp-dev/gitea-values.yaml | 7 ++ infra/values/gcp-dev/opencost-values.yaml | 9 ++ infra/values/gcp-dev/traefik-values.yaml | 15 +++ infra/values/gcp-prod/gitea-values.yaml | 7 ++ infra/values/gcp-prod/opencost-values.yaml | 9 ++ infra/values/gcp-prod/traefik-values.yaml | 15 +++ infra/values/upc-dev/gitea-values.yaml | 7 ++ infra/values/upc-dev/opencost-values.yaml | 15 +++ infra/values/upc-prod/gitea-values.yaml | 7 ++ infra/values/upc-prod/opencost-values.yaml | 15 +++ scripts/gitea-backup-aws.sh | 94 +++++++++++++++++ scripts/gitea-backup-azure.sh | 100 +++++++++++++++++++ scripts/gitea-backup-gcp.sh | 95 ++++++++++++++++++ 54 files changed, 1150 insertions(+), 83 deletions(-) create mode 100644 _app-of-apps-aws-dev.yaml create mode 100644 _app-of-apps-aws-prod.yaml create mode 100644 _app-of-apps-azure-dev.yaml create mode 100644 _app-of-apps-azure-prod.yaml create mode 100644 _app-of-apps-gcp-dev.yaml create mode 100644 _app-of-apps-gcp-prod.yaml create mode 100644 clusters/aws-dev.yaml create mode 100644 clusters/aws-prod.yaml create mode 100644 clusters/azure-dev.yaml create mode 100644 clusters/azure-prod.yaml create mode 100644 clusters/gcp-dev.yaml create mode 100644 clusters/gcp-prod.yaml create mode 100644 infra/overlays/aws-dev/kustomization.yaml create mode 100644 infra/overlays/aws-prod/kustomization.yaml create mode 100644 infra/overlays/azure-dev/kustomization.yaml create mode 100644 infra/overlays/azure-prod/kustomization.yaml create mode 100644 infra/overlays/gcp-dev/kustomization.yaml create mode 100644 infra/overlays/gcp-prod/kustomization.yaml create mode 100644 infra/values/aws-dev/gitea-values.yaml create mode 100644 infra/values/aws-dev/opencost-values.yaml create mode 100644 infra/values/aws-dev/traefik-values.yaml create mode 100644 infra/values/aws-prod/gitea-values.yaml create mode 100644 infra/values/aws-prod/opencost-values.yaml create mode 100644 infra/values/aws-prod/traefik-values.yaml create mode 100644 infra/values/azure-dev/gitea-values.yaml create mode 100644 infra/values/azure-dev/opencost-values.yaml create mode 100644 infra/values/azure-dev/traefik-values.yaml create mode 100644 infra/values/azure-prod/gitea-values.yaml create mode 100644 infra/values/azure-prod/opencost-values.yaml create mode 100644 infra/values/azure-prod/traefik-values.yaml create mode 100644 infra/values/gcp-dev/gitea-values.yaml create mode 100644 infra/values/gcp-dev/opencost-values.yaml create mode 100644 infra/values/gcp-dev/traefik-values.yaml create mode 100644 infra/values/gcp-prod/gitea-values.yaml create mode 100644 infra/values/gcp-prod/opencost-values.yaml create mode 100644 infra/values/gcp-prod/traefik-values.yaml create mode 100644 infra/values/upc-dev/gitea-values.yaml create mode 100644 infra/values/upc-dev/opencost-values.yaml create mode 100644 infra/values/upc-prod/gitea-values.yaml create mode 100644 infra/values/upc-prod/opencost-values.yaml create mode 100755 scripts/gitea-backup-aws.sh create mode 100755 scripts/gitea-backup-azure.sh create mode 100755 scripts/gitea-backup-gcp.sh diff --git a/README.md b/README.md index d419e33..c9511e0 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # Kubernetes Cluster - GitOps Configuration -> **Kubernetes cluster bootstrapping and GitOps configuration repository** using ArgoCD for UpCloud Managed Kubernetes +> **Kubernetes cluster bootstrapping and GitOps configuration repository** using ArgoCD for multi-cloud Kubernetes (UpCloud, AWS EKS, Azure AKS, GCP GKE) [![GitOps](https://img.shields.io/badge/GitOps-ArgoCD-blue)](https://argoproj.github.io/cd/) -[![Kubernetes](https://img.shields.io/badge/Kubernetes-UpCloud-orange)](https://upcloud.com/) +[![Kubernetes](https://img.shields.io/badge/Kubernetes-Multi--Cloud-orange)]() --- @@ -95,14 +95,26 @@ This repository contains the complete GitOps configuration for our Kubernetes cl │ │ ├── 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) +│ ├── overlays/ # Per-cluster overrides (Kustomize) +│ │ ├── upc-dev/ # UpCloud Dev (uses base as-is) +│ │ ├── upc-prod/ # UpCloud Prod (patches value paths) +│ │ ├── aws-dev/ # AWS EKS Dev +│ │ ├── aws-prod/ # AWS EKS Prod +│ │ ├── azure-dev/ # Azure AKS Dev +│ │ ├── azure-prod/ # Azure AKS Prod +│ │ ├── gcp-dev/ # GCP GKE Dev +│ │ └── gcp-prod/ # GCP GKE Prod │ ├── 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 +│ ├── base/ # Shared cloud-agnostic values +│ ├── upc-dev/ # UpCloud Dev (storage, LB, pricing) +│ ├── upc-prod/ # UpCloud Prod +│ ├── aws-dev/ # AWS EKS Dev +│ ├── aws-prod/ # AWS EKS Prod +│ ├── azure-dev/ # Azure AKS Dev +│ ├── azure-prod/ # Azure AKS Prod +│ ├── gcp-dev/ # GCP GKE Dev +│ └── gcp-prod/ # GCP GKE Prod │ ├── apps/ # Business Applications │ ├── mcp10x.yaml @@ -361,7 +373,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/`. 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`). +`_app-of-apps-{cluster}.yaml` is the root Application that manages all other Applications in `infra/`. Kustomize overlays in `infra/overlays/{cluster}/` render the base Applications with per-cluster patches (e.g., swapping value file paths). Supported clusters: `upc-dev`, `upc-prod`, `aws-dev`, `aws-prod`, `azure-dev`, `azure-prod`, `gcp-dev`, `gcp-prod`. ### Multi-Source Pattern Applications reference both: @@ -458,16 +470,14 @@ Documentation lives in `docs/`. To update: ## 📝 Notes ### Current Environment -- **Provider**: UpCloud Managed Kubernetes +- **Provider**: Multi-cloud (UpCloud, AWS EKS, Azure AKS, GCP GKE) +- **Active clusters**: UpCloud (upc-dev, upc-prod) - **Environment**: Production (internal use only) -- **Clusters**: Multi-cluster (upc-dev, upc-prod) via Kustomize overlays - **Auth**: Disabled for ArgoCD (internal access) -- **Backup**: None (cluster rebuildable via GitOps) +- **Backup**: Gitea daily backup to S3-compatible storage ### Known Limitations -- No automated backups (yet) - Secret rotation not automated -- 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) @@ -504,7 +514,7 @@ Internal use only. Not for public distribution. --- -**Last Updated**: 2026-03-16 +**Last Updated**: 2026-04-22 **Documentation Version**: 1.0.0 **🚀 Ready to get started? Check out the [Documentation Index](docs/README.md)!** diff --git a/_app-of-apps-aws-dev.yaml b/_app-of-apps-aws-dev.yaml new file mode 100644 index 0000000..061d19b --- /dev/null +++ b/_app-of-apps-aws-dev.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/aws-dev + destination: + server: https://kubernetes.default.svc + namespace: default + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/_app-of-apps-aws-prod.yaml b/_app-of-apps-aws-prod.yaml new file mode 100644 index 0000000..62fd689 --- /dev/null +++ b/_app-of-apps-aws-prod.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/aws-prod + destination: + server: https://kubernetes.default.svc + namespace: default + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/_app-of-apps-azure-dev.yaml b/_app-of-apps-azure-dev.yaml new file mode 100644 index 0000000..deeaefa --- /dev/null +++ b/_app-of-apps-azure-dev.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/azure-dev + destination: + server: https://kubernetes.default.svc + namespace: default + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/_app-of-apps-azure-prod.yaml b/_app-of-apps-azure-prod.yaml new file mode 100644 index 0000000..9794896 --- /dev/null +++ b/_app-of-apps-azure-prod.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/azure-prod + destination: + server: https://kubernetes.default.svc + namespace: default + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/_app-of-apps-gcp-dev.yaml b/_app-of-apps-gcp-dev.yaml new file mode 100644 index 0000000..63843ce --- /dev/null +++ b/_app-of-apps-gcp-dev.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/gcp-dev + destination: + server: https://kubernetes.default.svc + namespace: default + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/_app-of-apps-gcp-prod.yaml b/_app-of-apps-gcp-prod.yaml new file mode 100644 index 0000000..32ae05f --- /dev/null +++ b/_app-of-apps-gcp-prod.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/gcp-prod + destination: + server: https://kubernetes.default.svc + namespace: default + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/cluster-resources/gitea-backup-cronjob.yaml b/cluster-resources/gitea-backup-cronjob.yaml index d05ec17..e8a6fa4 100644 --- a/cluster-resources/gitea-backup-cronjob.yaml +++ b/cluster-resources/gitea-backup-cronjob.yaml @@ -57,17 +57,17 @@ spec: - sh - -c - | - mc alias set upcloud "${S3_ENDPOINT}" "${AWS_ACCESS_KEY_ID}" "${AWS_SECRET_ACCESS_KEY}" + mc alias set s3 "${S3_ENDPOINT}" "${AWS_ACCESS_KEY_ID}" "${AWS_SECRET_ACCESS_KEY}" TIMESTAMP=$(date +%Y%m%d-%H%M%S) KEY="gitea-dump-${TIMESTAMP}.zip" echo "Uploading ${KEY}..." - mc cp /backup/gitea-dump.zip "upcloud/${S3_BUCKET}/${KEY}" && \ + mc cp /backup/gitea-dump.zip "s3/${S3_BUCKET}/${KEY}" && \ echo "Upload complete." # Prune backups older than 7 days echo "Pruning backups older than 7 days..." - mc rm --older-than 7d --force "upcloud/${S3_BUCKET}/" 2>&1 || true + mc rm --older-than 7d --force "s3/${S3_BUCKET}/" 2>&1 || true echo "Pruning complete." envFrom: - secretRef: diff --git a/clusters/aws-dev.yaml b/clusters/aws-dev.yaml new file mode 100644 index 0000000..02f3034 --- /dev/null +++ b/clusters/aws-dev.yaml @@ -0,0 +1,10 @@ +clusterName: dev-eks # <- adjust to your EKS cluster name +domain: example.com # <- adjust to your domain +argocdDomain: argocd.example.com +grafanaDomain: grafana.example.com +keycloakDomain: id.example.com +dotaiDomain: kubemcp.example.com +dotaiUiDomain: kubemcpui.example.com +letsencryptEmail: admin@example.com # <- adjust +trustedIPs: "10.0.0.0/8" # <- adjust to your VPC CIDR +cloudProvider: aws diff --git a/clusters/aws-prod.yaml b/clusters/aws-prod.yaml new file mode 100644 index 0000000..c5973f9 --- /dev/null +++ b/clusters/aws-prod.yaml @@ -0,0 +1,10 @@ +clusterName: prod-eks # <- adjust to your EKS cluster name +domain: example.com # <- adjust to your domain +argocdDomain: argocd.example.com +grafanaDomain: grafana.example.com +keycloakDomain: id.example.com +dotaiDomain: kubemcp.example.com +dotaiUiDomain: kubemcpui.example.com +letsencryptEmail: admin@example.com # <- adjust +trustedIPs: "10.0.0.0/8" # <- adjust to your VPC CIDR +cloudProvider: aws diff --git a/clusters/azure-dev.yaml b/clusters/azure-dev.yaml new file mode 100644 index 0000000..5a3ace2 --- /dev/null +++ b/clusters/azure-dev.yaml @@ -0,0 +1,10 @@ +clusterName: dev-aks # <- adjust to your AKS cluster name +domain: example.com # <- adjust to your domain +argocdDomain: argocd.example.com +grafanaDomain: grafana.example.com +keycloakDomain: id.example.com +dotaiDomain: kubemcp.example.com +dotaiUiDomain: kubemcpui.example.com +letsencryptEmail: admin@example.com # <- adjust +trustedIPs: "10.0.0.0/8,168.63.129.16/32" # <- VNet CIDR + Azure health probe +cloudProvider: azure diff --git a/clusters/azure-prod.yaml b/clusters/azure-prod.yaml new file mode 100644 index 0000000..0be858e --- /dev/null +++ b/clusters/azure-prod.yaml @@ -0,0 +1,10 @@ +clusterName: prod-aks # <- adjust to your AKS cluster name +domain: example.com # <- adjust to your domain +argocdDomain: argocd.example.com +grafanaDomain: grafana.example.com +keycloakDomain: id.example.com +dotaiDomain: kubemcp.example.com +dotaiUiDomain: kubemcpui.example.com +letsencryptEmail: admin@example.com # <- adjust +trustedIPs: "10.0.0.0/8,168.63.129.16/32" # <- VNet CIDR + Azure health probe +cloudProvider: azure diff --git a/clusters/gcp-dev.yaml b/clusters/gcp-dev.yaml new file mode 100644 index 0000000..43f3861 --- /dev/null +++ b/clusters/gcp-dev.yaml @@ -0,0 +1,10 @@ +clusterName: dev-gke # <- adjust to your GKE cluster name +domain: example.com # <- adjust to your domain +argocdDomain: argocd.example.com +grafanaDomain: grafana.example.com +keycloakDomain: id.example.com +dotaiDomain: kubemcp.example.com +dotaiUiDomain: kubemcpui.example.com +letsencryptEmail: admin@example.com # <- adjust +trustedIPs: "10.0.0.0/8,35.191.0.0/16,130.211.0.0/22" # <- subnet CIDR + GCP health checks +cloudProvider: gcp diff --git a/clusters/gcp-prod.yaml b/clusters/gcp-prod.yaml new file mode 100644 index 0000000..ec814f7 --- /dev/null +++ b/clusters/gcp-prod.yaml @@ -0,0 +1,10 @@ +clusterName: prod-gke # <- adjust to your GKE cluster name +domain: example.com # <- adjust to your domain +argocdDomain: argocd.example.com +grafanaDomain: grafana.example.com +keycloakDomain: id.example.com +dotaiDomain: kubemcp.example.com +dotaiUiDomain: kubemcpui.example.com +letsencryptEmail: admin@example.com # <- adjust +trustedIPs: "10.0.0.0/8,35.191.0.0/16,130.211.0.0/22" # <- subnet CIDR + GCP health checks +cloudProvider: gcp diff --git a/docs/GITOPS-ARCHITECTURE.md b/docs/GITOPS-ARCHITECTURE.md index ec9769f..a57fb4b 100644 --- a/docs/GITOPS-ARCHITECTURE.md +++ b/docs/GITOPS-ARCHITECTURE.md @@ -12,11 +12,11 @@ ## Overview -This Kubernetes cluster uses a **GitOps approach** powered by **ArgoCD**, where Git repositories serve as the single source of truth for both infrastructure and application deployments. The cluster is running on **UpCloud Managed Kubernetes** but is designed to be cloud-agnostic. +This Kubernetes cluster uses a **GitOps approach** powered by **ArgoCD**, where Git repositories serve as the single source of truth for both infrastructure and application deployments. The cluster setup is **cloud-agnostic**, with ready-to-use configurations for **UpCloud**, **AWS EKS**, **Azure AKS**, and **GCP GKE**. ### Key Characteristics - **Environment**: Production (internal use only) -- **Cluster Type**: Multi-cluster (upc-dev, upc-prod) via Kustomize overlays +- **Cluster Type**: Multi-cloud, multi-cluster via Kustomize overlays (UpCloud, AWS, Azure, GCP) - **GitOps Tool**: ArgoCD - **Deployment Pattern**: App-of-Apps - **Secret Management**: Sealed Secrets (kubeseal) @@ -63,7 +63,7 @@ This Kubernetes cluster uses a **GitOps approach** powered by **ArgoCD**, where ▼ ┌────────────────────────────────┐ │ Kubernetes Clusters │ - │ (UpCloud: upc-dev, upc-prod) │ + │ (UpCloud, AWS, Azure, GCP) │ │ │ │ ┌──────────────────────────┐ │ │ │ ArgoCD │ │ @@ -131,26 +131,22 @@ launchpad/ │ │ ├── renovate.yaml │ │ ├── ... # All other Application manifests │ │ └── secrets.yaml -│ ├── overlays/ # Per-cluster overrides +│ ├── overlays/ # Per-cluster Kustomize overrides │ │ ├── upc-dev/ # UpCloud Dev (uses base as-is) -│ │ └── upc-prod/ # UpCloud Prod (patches value paths) +│ │ ├── upc-prod/ # UpCloud Prod (patches value paths) +│ │ ├── aws-dev/ # AWS EKS Dev +│ │ ├── aws-prod/ # AWS EKS Prod +│ │ ├── azure-dev/ # Azure AKS Dev +│ │ ├── azure-prod/ # Azure AKS Prod +│ │ ├── gcp-dev/ # GCP GKE Dev +│ │ └── gcp-prod/ # GCP GKE Prod │ ├── dashboards/ # Grafana dashboard ConfigMaps │ └── values/ # Helm value overrides for infra -│ ├── 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 +│ ├── base/ # Cloud-agnostic shared values +│ ├── upc-{dev,prod}/ # UpCloud: storage class, LB, pricing +│ ├── aws-{dev,prod}/ # AWS: gp3, NLB, CUR pricing +│ ├── azure-{dev,prod}/ # Azure: managed-csi-premium, Standard LB +│ └── gcp-{dev,prod}/ # GCP: premium-rwo, L4 LB │ ├── apps/ # Business Application ArgoCD manifests (Kustomize) │ ├── base/ # Base app manifests @@ -287,7 +283,7 @@ app-repository/ ### The App-of-Apps Pattern ``` -_app-of-apps-{upc-dev,upc-prod}.yaml (Root, per cluster) +_app-of-apps-{cluster}.yaml (Root, per cluster — e.g. upc-dev, aws-prod, gcp-dev) │ ├── infrastructure-apps (manages infra/) │ ├── cluster-resources-application @@ -377,6 +373,15 @@ patches: value: $values/infra/values/upc-prod/traefik-values.yaml ``` +Cloud-specific values (storage classes, load balancer annotations, cost model) are isolated in per-cluster value files. Base values are fully cloud-agnostic: + +| Cloud | Storage Class | Load Balancer | OpenCost Provider | +|-------|--------------|---------------|-------------------| +| **UpCloud** | `upcloud-block-storage-maxiops` | UpCloud LB (ProxyProtocol v2) | Custom pricing | +| **AWS EKS** | `gp3` (EBS CSI) | NLB (ProxyProtocol v2) | AWS CUR | +| **Azure AKS** | `managed-csi-premium` | Standard LB (`externalTrafficPolicy: Local`) | Azure Billing API | +| **GCP GKE** | `premium-rwo` (PD CSI) | L4 passthrough NLB | GCP Cloud Billing | + **Benefits**: - Single source of truth for Application definitions - Cluster-specific values isolated per overlay @@ -658,6 +663,6 @@ Notifications include: --- -**Last Updated**: 2026-03-16 +**Last Updated**: 2026-04-22 **Maintained By**: Platform Team **Questions?**: Contact #platform-support on Slack diff --git a/docs/OPERATIONS-RUNBOOK.md b/docs/OPERATIONS-RUNBOOK.md index a02a239..03ea097 100644 --- a/docs/OPERATIONS-RUNBOOK.md +++ b/docs/OPERATIONS-RUNBOOK.md @@ -37,7 +37,7 @@ Bootstrap a new cluster from scratch: #### Prerequisites -1. **Kubernetes cluster running** (UpCloud or any K8s cluster) +1. **Kubernetes cluster running** (UpCloud, AWS EKS, Azure AKS, GCP GKE, or any K8s cluster) 2. **kubectl configured** with admin access 3. **Repositories cloned** locally @@ -54,11 +54,13 @@ kubectl get nodes git clone https://git.forteapps.net/Forte/launchpad cd launchpad -# 2. Set cluster name (optional) -export CLUSTER_NAME="prod-cluster-01" +# 2. Run bootstrap script with cluster target +# Available clusters: upc-dev, upc-prod, aws-dev, aws-prod, +# azure-dev, azure-prod, gcp-dev, gcp-prod +./bootstrap.sh upc-dev -# 3. Run bootstrap script -./bootstrap.sh +# Cluster config is loaded from clusters/.yaml +# (cloudProvider, trustedIPs, domain, etc.) ``` **What Happens:** @@ -1262,13 +1264,21 @@ spec: ### Backup Strategy -**Current State**: No automated backups +**Current State**: Gitea daily backups to S3-compatible storage -**What Needs Backup**: -- ❌ Cluster state (not backed up - recreate via GitOps) -- ❌ Persistent volumes (currently not critical) -- ✅ Git repositories (Gitea provides backup) -- ⚠️ Secrets (sealed secrets in Git, unseal keys need safekeeping) +**What Is Backed Up**: +- ✅ Gitea repositories + database: Daily CronJob (`cluster-resources/gitea-backup-cronjob.yaml`) uploads to S3-compatible storage with 7-day retention +- ✅ Git repositories: Full cluster config recoverable from Git +- ⚠️ Secrets: Sealed secrets in Git; unseal keys need safekeeping + +**What Is NOT Backed Up**: +- ❌ Cluster state (recreate via GitOps) +- ❌ Other persistent volumes (Prometheus, Loki, Tempo data) + +**Per-cloud backup scripts** (manual restore helpers): +- UpCloud/AWS: `scripts/gitea-backup.sh` / `scripts/gitea-backup-aws.sh` (MinIO CLI, S3-compatible) +- Azure: `scripts/gitea-backup-azure.sh` (Azure CLI + Blob Storage) +- GCP: `scripts/gitea-backup-gcp.sh` (gsutil + GCS) ### Cluster Rebuild @@ -1370,6 +1380,9 @@ kubectl get pods -n argocd ```bash # UpCloud: Upgrade via control panel or CLI +# AWS EKS: eksctl upgrade cluster / AWS Console +# Azure AKS: az aks upgrade / Azure Portal +# GCP GKE: gcloud container clusters upgrade / Cloud Console # After upgrade, verify cluster kubectl version @@ -1507,18 +1520,35 @@ git push ### Multi-Cluster Setup -The repository supports multiple clusters via Kustomize overlays: +The repository supports multiple clusters across multiple clouds via Kustomize overlays: +**Active clusters:** - **upc-dev** (default): `infra/overlays/upc-dev/` — uses base Applications as-is - **upc-prod**: `infra/overlays/upc-prod/` — patches value file paths from `upc-dev` to `upc-prod` -Each cluster has its own: -- Root app-of-apps file: `_app-of-apps-upc-dev.yaml` / `_app-of-apps-upc-prod.yaml` -- Cluster-specific Helm values: `infra/values/upc-dev/` / `infra/values/upc-prod/` -- Sealed secrets: `secrets/upc-dev/` (others as needed) -- Apps overlay: `apps/overlays/upc-dev/` / `apps/overlays/upc-prod/` +**Cloud-ready templates (fill in `clusters/*.yaml` before use):** +- **aws-dev** / **aws-prod**: AWS EKS with NLB, gp3 storage, AWS CUR pricing +- **azure-dev** / **azure-prod**: Azure AKS with Standard LB, managed-csi-premium storage +- **gcp-dev** / **gcp-prod**: GCP GKE with L4 LB, premium-rwo storage -To add a new cluster, create a new overlay directory (e.g., `infra/overlays/upc-staging/`) with patches that swap the value file paths. +Each cluster has its own: +- Root app-of-apps: `_app-of-apps-{cluster}.yaml` +- Cluster config: `clusters/{cluster}.yaml` (domain, trustedIPs, cloudProvider) +- Kustomize overlay: `infra/overlays/{cluster}/kustomization.yaml` +- Helm value overrides: `infra/values/{cluster}/` (traefik, gitea, opencost) +- Sealed secrets: `secrets/{cluster}/` (as needed) +- Apps overlay: `apps/overlays/{cluster}/` + +Cloud-specific values handled per-cluster: + +| Concern | UpCloud | AWS EKS | Azure AKS | GCP GKE | +|---------|---------|---------|-----------|---------| +| **Storage class** | `upcloud-block-storage-maxiops` | `gp3` | `managed-csi-premium` | `premium-rwo` | +| **Load balancer** | UpCloud LB + ProxyProtocol v2 | NLB + ProxyProtocol v2 | Standard LB + `externalTrafficPolicy: Local` | L4 passthrough NLB | +| **Cost monitoring** | Custom pricing | AWS CUR | Azure Billing API | GCP Cloud Billing | +| **Backup storage** | UpCloud S3-compat | AWS S3 (native) | Azure Blob Storage | GCS | + +To add a new cluster, create a new overlay directory (e.g., `infra/overlays/aws-staging/`) with patches that swap the value file paths, and a matching `clusters/aws-staging.yaml`. ### Blue-Green Deployments @@ -1661,6 +1691,6 @@ echo "Remember to delete: $SECRET_FILE" --- -**Last Updated**: 2026-03-16 +**Last Updated**: 2026-04-22 **Maintained By**: Platform Team **Emergency Contact**: #platform-support on Slack diff --git a/docs/README.md b/docs/README.md index 47a394e..6b48500 100644 --- a/docs/README.md +++ b/docs/README.md @@ -180,7 +180,7 @@ Reference for: │ ▼ ┌──────────────────────────────────────────────────────────────┐ -│ Kubernetes Clusters (UpCloud: upc-dev, upc-prod) │ +│ Kubernetes Clusters (UpCloud, AWS, Azure, GCP) │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ Infrastructure: Traefik, Cert-Manager, Kyverno │ │ │ ├──────────────────────────────────────────────────────┤ │ @@ -194,7 +194,7 @@ Reference for: ### Key Technologies - **GitOps**: ArgoCD -- **Kubernetes**: UpCloud Managed Kubernetes (multi-cluster: upc-dev, upc-prod) +- **Kubernetes**: Multi-cloud (UpCloud, AWS EKS, Azure AKS, GCP GKE) - **Ingress**: Traefik v2 - **Certificates**: Cert-Manager + Let's Encrypt - **Policies**: Kyverno @@ -299,11 +299,16 @@ docs/ ## 🔄 Documentation Versions **Current Version**: 1.0.0 -**Last Updated**: 2026-03-16 +**Last Updated**: 2026-04-22 **Maintained By**: Platform Team ### Changelog +- **v1.1.0 (2026-04-22)**: Multi-cloud support + - Cloud-agnostic base values (storage, LB, pricing moved to per-cluster overlays) + - Added AWS EKS, Azure AKS, GCP GKE configurations + - Per-cloud backup scripts + - Updated all documentation - **v1.0.0 (2026-03-16)**: Initial comprehensive documentation release - GitOps Architecture guide - Developer Onboarding guide diff --git a/docs/REFERENCE.md b/docs/REFERENCE.md index 5ba17aa..f5be8f5 100644 --- a/docs/REFERENCE.md +++ b/docs/REFERENCE.md @@ -19,9 +19,9 @@ | Component | Value | |-----------|-------| -| **Provider** | UpCloud Managed Kubernetes | -| **Environment** | Production (internal use) | -| **Cluster Count** | Multi-cluster (upc-dev, upc-prod) | +| **Provider** | Multi-cloud (UpCloud, AWS EKS, Azure AKS, GCP GKE) | +| **Active clusters** | UpCloud (upc-dev, upc-prod) | +| **Cloud-ready templates** | AWS, Azure, GCP (dev + prod each) | | **GitOps Tool** | ArgoCD | | **Ingress Controller** | Traefik v2 | | **Certificate Management** | Cert-Manager + Let's Encrypt | @@ -42,7 +42,7 @@ Internet [DNS: *.forteapps.net] │ ▼ -[UpCloud LoadBalancer] +[Cloud Load Balancer] │ ▼ [Traefik Ingress Controller] @@ -1470,14 +1470,22 @@ Recommended resource allocation: ### Storage Classes -Default storage class used: **UpCloud default** (varies by provider) +Storage classes are cloud-specific and configured in per-cluster value overrides (`infra/values/{cluster}/gitea-values.yaml`): + +| Cloud | Storage Class | Driver | +|-------|--------------|--------| +| **UpCloud** | `upcloud-block-storage-maxiops` | UpCloud CSI | +| **AWS EKS** | `gp3` | EBS CSI | +| **Azure AKS** | `managed-csi-premium` | Azure Disk CSI | +| **GCP GKE** | `premium-rwo` | PD CSI | ```yaml +# Example: base values omit storageClass (set in per-cluster overlay) persistence: enabled: true - storageClass: "" # Uses default accessMode: ReadWriteOnce size: 5Gi + # storageClass set by infra/values/{cluster}/gitea-values.yaml ``` --- @@ -1673,6 +1681,6 @@ team: platform --- -**Last Updated**: 2026-04-16 +**Last Updated**: 2026-04-22 **Maintained By**: Platform Team **Version**: 1.0.0 diff --git a/infra/base/gitea.yaml b/infra/base/gitea.yaml index ba806f5..cc4f60f 100644 --- a/infra/base/gitea.yaml +++ b/infra/base/gitea.yaml @@ -22,6 +22,7 @@ spec: releaseName: gitea valueFiles: - $values/infra/values/base/gitea-values.yaml + - $values/infra/values/upc-dev/gitea-values.yaml - repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git targetRevision: HEAD diff --git a/infra/base/opencost.yaml b/infra/base/opencost.yaml index 6984f3b..a102906 100644 --- a/infra/base/opencost.yaml +++ b/infra/base/opencost.yaml @@ -22,6 +22,7 @@ spec: releaseName: opencost valueFiles: - $values/infra/values/base/opencost-values.yaml + - $values/infra/values/upc-dev/opencost-values.yaml - repoURL: git@github.com:fortedigital/sturdy-adventure.git targetRevision: HEAD diff --git a/infra/overlays/aws-dev/kustomization.yaml b/infra/overlays/aws-dev/kustomization.yaml new file mode 100644 index 0000000..4be71fc --- /dev/null +++ b/infra/overlays/aws-dev/kustomization.yaml @@ -0,0 +1,35 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- ../../base + +patches: +# Traefik: swap upc-dev → aws-dev +- target: + kind: Application + name: traefik + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/aws-dev/traefik-values.yaml + +# Gitea: swap upc-dev → aws-dev +- target: + kind: Application + name: gitea + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/aws-dev/gitea-values.yaml + +# OpenCost: swap upc-dev → aws-dev +- target: + kind: Application + name: opencost + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/aws-dev/opencost-values.yaml + +# TODO: add patches for keycloak, grafana, secrets, enterprise-apps +# when deploying to this cluster (these are deployment-specific, not cloud-specific) diff --git a/infra/overlays/aws-prod/kustomization.yaml b/infra/overlays/aws-prod/kustomization.yaml new file mode 100644 index 0000000..ce22faf --- /dev/null +++ b/infra/overlays/aws-prod/kustomization.yaml @@ -0,0 +1,35 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- ../../base + +patches: +# Traefik: swap upc-dev → aws-prod +- target: + kind: Application + name: traefik + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/aws-prod/traefik-values.yaml + +# Gitea: swap upc-dev → aws-prod +- target: + kind: Application + name: gitea + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/aws-prod/gitea-values.yaml + +# OpenCost: swap upc-dev → aws-prod +- target: + kind: Application + name: opencost + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/aws-prod/opencost-values.yaml + +# TODO: add patches for keycloak, grafana, secrets, enterprise-apps +# when deploying to this cluster (these are deployment-specific, not cloud-specific) diff --git a/infra/overlays/azure-dev/kustomization.yaml b/infra/overlays/azure-dev/kustomization.yaml new file mode 100644 index 0000000..d7a014d --- /dev/null +++ b/infra/overlays/azure-dev/kustomization.yaml @@ -0,0 +1,35 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- ../../base + +patches: +# Traefik: swap upc-dev → azure-dev +- target: + kind: Application + name: traefik + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/azure-dev/traefik-values.yaml + +# Gitea: swap upc-dev → azure-dev +- target: + kind: Application + name: gitea + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/azure-dev/gitea-values.yaml + +# OpenCost: swap upc-dev → azure-dev +- target: + kind: Application + name: opencost + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/azure-dev/opencost-values.yaml + +# TODO: add patches for keycloak, grafana, secrets, enterprise-apps +# when deploying to this cluster (these are deployment-specific, not cloud-specific) diff --git a/infra/overlays/azure-prod/kustomization.yaml b/infra/overlays/azure-prod/kustomization.yaml new file mode 100644 index 0000000..4a9d6cf --- /dev/null +++ b/infra/overlays/azure-prod/kustomization.yaml @@ -0,0 +1,35 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- ../../base + +patches: +# Traefik: swap upc-dev → azure-prod +- target: + kind: Application + name: traefik + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/azure-prod/traefik-values.yaml + +# Gitea: swap upc-dev → azure-prod +- target: + kind: Application + name: gitea + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/azure-prod/gitea-values.yaml + +# OpenCost: swap upc-dev → azure-prod +- target: + kind: Application + name: opencost + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/azure-prod/opencost-values.yaml + +# TODO: add patches for keycloak, grafana, secrets, enterprise-apps +# when deploying to this cluster (these are deployment-specific, not cloud-specific) diff --git a/infra/overlays/gcp-dev/kustomization.yaml b/infra/overlays/gcp-dev/kustomization.yaml new file mode 100644 index 0000000..491065e --- /dev/null +++ b/infra/overlays/gcp-dev/kustomization.yaml @@ -0,0 +1,35 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- ../../base + +patches: +# Traefik: swap upc-dev → gcp-dev +- target: + kind: Application + name: traefik + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/gcp-dev/traefik-values.yaml + +# Gitea: swap upc-dev → gcp-dev +- target: + kind: Application + name: gitea + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/gcp-dev/gitea-values.yaml + +# OpenCost: swap upc-dev → gcp-dev +- target: + kind: Application + name: opencost + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/gcp-dev/opencost-values.yaml + +# TODO: add patches for keycloak, grafana, secrets, enterprise-apps +# when deploying to this cluster (these are deployment-specific, not cloud-specific) diff --git a/infra/overlays/gcp-prod/kustomization.yaml b/infra/overlays/gcp-prod/kustomization.yaml new file mode 100644 index 0000000..9971aa9 --- /dev/null +++ b/infra/overlays/gcp-prod/kustomization.yaml @@ -0,0 +1,35 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- ../../base + +patches: +# Traefik: swap upc-dev → gcp-prod +- target: + kind: Application + name: traefik + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/gcp-prod/traefik-values.yaml + +# Gitea: swap upc-dev → gcp-prod +- target: + kind: Application + name: gitea + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/gcp-prod/gitea-values.yaml + +# OpenCost: swap upc-dev → gcp-prod +- target: + kind: Application + name: opencost + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/gcp-prod/opencost-values.yaml + +# TODO: add patches for keycloak, grafana, secrets, enterprise-apps +# when deploying to this cluster (these are deployment-specific, not cloud-specific) diff --git a/infra/overlays/upc-prod/kustomization.yaml b/infra/overlays/upc-prod/kustomization.yaml index ebfc179..5a6c53d 100644 --- a/infra/overlays/upc-prod/kustomization.yaml +++ b/infra/overlays/upc-prod/kustomization.yaml @@ -48,3 +48,21 @@ patches: - op: replace path: /spec/source/path value: apps/overlays/upc-prod + +# Gitea: swap upc-dev → upc-prod +- target: + kind: Application + name: gitea + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/upc-prod/gitea-values.yaml + +# OpenCost: swap upc-dev → upc-prod +- target: + kind: Application + name: opencost + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/upc-prod/opencost-values.yaml diff --git a/infra/values/aws-dev/gitea-values.yaml b/infra/values/aws-dev/gitea-values.yaml new file mode 100644 index 0000000..597af4f --- /dev/null +++ b/infra/values/aws-dev/gitea-values.yaml @@ -0,0 +1,7 @@ +# AWS EBS gp3 storage class (requires EBS CSI driver) +persistence: + storageClass: gp3 +postgresql: + primary: + persistence: + storageClass: gp3 diff --git a/infra/values/aws-dev/opencost-values.yaml b/infra/values/aws-dev/opencost-values.yaml new file mode 100644 index 0000000..93ff67a --- /dev/null +++ b/infra/values/aws-dev/opencost-values.yaml @@ -0,0 +1,13 @@ +# AWS native pricing via Cost and Usage Reports +opencost: + exporter: + customPricing: + enabled: true + provider: aws + aws: + service_key_name: "" # <- populate or use IRSA + service_key_secret: "" + spot_data_region: "" + spot_data_bucket: "" + spot_data_prefix: "" + account_id: "" diff --git a/infra/values/aws-dev/traefik-values.yaml b/infra/values/aws-dev/traefik-values.yaml new file mode 100644 index 0000000..34306f7 --- /dev/null +++ b/infra/values/aws-dev/traefik-values.yaml @@ -0,0 +1,18 @@ +# AWS EKS — NLB with Proxy Protocol v2 for real client IPs +service: + annotations: + service.beta.kubernetes.io/aws-load-balancer-type: "external" + service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip" + service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing" + service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*" +ports: + web: + proxyProtocol: + trustedIPs: "10.0.0.0/8" # <- adjust to your VPC CIDR + forwardedHeaders: + trustedIPs: "10.0.0.0/8" + websecure: + proxyProtocol: + trustedIPs: "10.0.0.0/8" + forwardedHeaders: + trustedIPs: "10.0.0.0/8" diff --git a/infra/values/aws-prod/gitea-values.yaml b/infra/values/aws-prod/gitea-values.yaml new file mode 100644 index 0000000..597af4f --- /dev/null +++ b/infra/values/aws-prod/gitea-values.yaml @@ -0,0 +1,7 @@ +# AWS EBS gp3 storage class (requires EBS CSI driver) +persistence: + storageClass: gp3 +postgresql: + primary: + persistence: + storageClass: gp3 diff --git a/infra/values/aws-prod/opencost-values.yaml b/infra/values/aws-prod/opencost-values.yaml new file mode 100644 index 0000000..93ff67a --- /dev/null +++ b/infra/values/aws-prod/opencost-values.yaml @@ -0,0 +1,13 @@ +# AWS native pricing via Cost and Usage Reports +opencost: + exporter: + customPricing: + enabled: true + provider: aws + aws: + service_key_name: "" # <- populate or use IRSA + service_key_secret: "" + spot_data_region: "" + spot_data_bucket: "" + spot_data_prefix: "" + account_id: "" diff --git a/infra/values/aws-prod/traefik-values.yaml b/infra/values/aws-prod/traefik-values.yaml new file mode 100644 index 0000000..34306f7 --- /dev/null +++ b/infra/values/aws-prod/traefik-values.yaml @@ -0,0 +1,18 @@ +# AWS EKS — NLB with Proxy Protocol v2 for real client IPs +service: + annotations: + service.beta.kubernetes.io/aws-load-balancer-type: "external" + service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip" + service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing" + service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*" +ports: + web: + proxyProtocol: + trustedIPs: "10.0.0.0/8" # <- adjust to your VPC CIDR + forwardedHeaders: + trustedIPs: "10.0.0.0/8" + websecure: + proxyProtocol: + trustedIPs: "10.0.0.0/8" + forwardedHeaders: + trustedIPs: "10.0.0.0/8" diff --git a/infra/values/azure-dev/gitea-values.yaml b/infra/values/azure-dev/gitea-values.yaml new file mode 100644 index 0000000..5bb20ff --- /dev/null +++ b/infra/values/azure-dev/gitea-values.yaml @@ -0,0 +1,7 @@ +# Azure Managed Disk (Premium SSD via CSI driver) +persistence: + storageClass: managed-csi-premium +postgresql: + primary: + persistence: + storageClass: managed-csi-premium diff --git a/infra/values/azure-dev/opencost-values.yaml b/infra/values/azure-dev/opencost-values.yaml new file mode 100644 index 0000000..98b30cd --- /dev/null +++ b/infra/values/azure-dev/opencost-values.yaml @@ -0,0 +1,11 @@ +# Azure native pricing via Billing API +opencost: + exporter: + customPricing: + enabled: true + provider: azure + azure: + subscriptionID: "" # <- populate + clientID: "" + clientSecret: "" + tenantID: "" diff --git a/infra/values/azure-dev/traefik-values.yaml b/infra/values/azure-dev/traefik-values.yaml new file mode 100644 index 0000000..7efa198 --- /dev/null +++ b/infra/values/azure-dev/traefik-values.yaml @@ -0,0 +1,16 @@ +# Azure AKS — Standard Load Balancer +# Note: Azure Standard LB does not support Proxy Protocol. +# Use externalTrafficPolicy: Local on the Traefik service to preserve +# client IPs, or deploy behind Azure Application Gateway. +service: + annotations: + service.beta.kubernetes.io/azure-load-balancer-health-probe-request-path: "/ping" + spec: + externalTrafficPolicy: Local +ports: + web: + forwardedHeaders: + trustedIPs: "10.0.0.0/8,168.63.129.16/32" # <- VNet CIDR + Azure health probe + websecure: + forwardedHeaders: + trustedIPs: "10.0.0.0/8,168.63.129.16/32" diff --git a/infra/values/azure-prod/gitea-values.yaml b/infra/values/azure-prod/gitea-values.yaml new file mode 100644 index 0000000..5bb20ff --- /dev/null +++ b/infra/values/azure-prod/gitea-values.yaml @@ -0,0 +1,7 @@ +# Azure Managed Disk (Premium SSD via CSI driver) +persistence: + storageClass: managed-csi-premium +postgresql: + primary: + persistence: + storageClass: managed-csi-premium diff --git a/infra/values/azure-prod/opencost-values.yaml b/infra/values/azure-prod/opencost-values.yaml new file mode 100644 index 0000000..98b30cd --- /dev/null +++ b/infra/values/azure-prod/opencost-values.yaml @@ -0,0 +1,11 @@ +# Azure native pricing via Billing API +opencost: + exporter: + customPricing: + enabled: true + provider: azure + azure: + subscriptionID: "" # <- populate + clientID: "" + clientSecret: "" + tenantID: "" diff --git a/infra/values/azure-prod/traefik-values.yaml b/infra/values/azure-prod/traefik-values.yaml new file mode 100644 index 0000000..7efa198 --- /dev/null +++ b/infra/values/azure-prod/traefik-values.yaml @@ -0,0 +1,16 @@ +# Azure AKS — Standard Load Balancer +# Note: Azure Standard LB does not support Proxy Protocol. +# Use externalTrafficPolicy: Local on the Traefik service to preserve +# client IPs, or deploy behind Azure Application Gateway. +service: + annotations: + service.beta.kubernetes.io/azure-load-balancer-health-probe-request-path: "/ping" + spec: + externalTrafficPolicy: Local +ports: + web: + forwardedHeaders: + trustedIPs: "10.0.0.0/8,168.63.129.16/32" # <- VNet CIDR + Azure health probe + websecure: + forwardedHeaders: + trustedIPs: "10.0.0.0/8,168.63.129.16/32" diff --git a/infra/values/base/gitea-values.yaml b/infra/values/base/gitea-values.yaml index e34f256..75c2e72 100644 --- a/infra/values/base/gitea-values.yaml +++ b/infra/values/base/gitea-values.yaml @@ -127,7 +127,6 @@ persistence: size: 10Gi accessModes: - ReadWriteOnce - storageClass: upcloud-block-storage-maxiops # -- Recreate strategy to avoid Multi-Attach errors with RWO volumes strategy: @@ -153,7 +152,6 @@ postgresql: persistence: enabled: true size: 8Gi - storageClass: upcloud-block-storage-maxiops resources: requests: cpu: 100m diff --git a/infra/values/base/opencost-values.yaml b/infra/values/base/opencost-values.yaml index 39d73cc..dde13fb 100644 --- a/infra/values/base/opencost-values.yaml +++ b/infra/values/base/opencost-values.yaml @@ -10,18 +10,8 @@ opencost: serviceName: prometheus-server namespaceName: monitoring port: 80 - customPricing: - enabled: true - provider: custom - costModel: - description: "UpCloud 4-node cluster pricing" - CPU: "5.86" - RAM: "1.46" - GPU: "0" - storage: "0.34" - zoneNetworkEgress: "0" - regionNetworkEgress: "0" - internetNetworkEgress: "0" + # Cloud-specific pricing is in per-cluster value overrides + # (e.g. infra/values/upc-dev/opencost-values.yaml) ui: enabled: false service: diff --git a/infra/values/gcp-dev/gitea-values.yaml b/infra/values/gcp-dev/gitea-values.yaml new file mode 100644 index 0000000..b825aee --- /dev/null +++ b/infra/values/gcp-dev/gitea-values.yaml @@ -0,0 +1,7 @@ +# GCP Persistent Disk (SSD via CSI driver) +persistence: + storageClass: premium-rwo +postgresql: + primary: + persistence: + storageClass: premium-rwo diff --git a/infra/values/gcp-dev/opencost-values.yaml b/infra/values/gcp-dev/opencost-values.yaml new file mode 100644 index 0000000..f3ea481 --- /dev/null +++ b/infra/values/gcp-dev/opencost-values.yaml @@ -0,0 +1,9 @@ +# GCP native pricing via Cloud Billing API +opencost: + exporter: + customPricing: + enabled: true + provider: gcp + gcp: + projectID: "" # <- populate with your GCP project ID + key: "" # <- or use Workload Identity diff --git a/infra/values/gcp-dev/traefik-values.yaml b/infra/values/gcp-dev/traefik-values.yaml new file mode 100644 index 0000000..55351c0 --- /dev/null +++ b/infra/values/gcp-dev/traefik-values.yaml @@ -0,0 +1,15 @@ +# GCP GKE — External passthrough Network Load Balancer +service: + annotations: + cloud.google.com/l4-rbs: "enabled" +ports: + web: + proxyProtocol: + trustedIPs: "10.0.0.0/8,35.191.0.0/16,130.211.0.0/22" # <- subnet CIDR + GCP health checks + forwardedHeaders: + trustedIPs: "10.0.0.0/8,35.191.0.0/16,130.211.0.0/22" + websecure: + proxyProtocol: + trustedIPs: "10.0.0.0/8,35.191.0.0/16,130.211.0.0/22" + forwardedHeaders: + trustedIPs: "10.0.0.0/8,35.191.0.0/16,130.211.0.0/22" diff --git a/infra/values/gcp-prod/gitea-values.yaml b/infra/values/gcp-prod/gitea-values.yaml new file mode 100644 index 0000000..b825aee --- /dev/null +++ b/infra/values/gcp-prod/gitea-values.yaml @@ -0,0 +1,7 @@ +# GCP Persistent Disk (SSD via CSI driver) +persistence: + storageClass: premium-rwo +postgresql: + primary: + persistence: + storageClass: premium-rwo diff --git a/infra/values/gcp-prod/opencost-values.yaml b/infra/values/gcp-prod/opencost-values.yaml new file mode 100644 index 0000000..f3ea481 --- /dev/null +++ b/infra/values/gcp-prod/opencost-values.yaml @@ -0,0 +1,9 @@ +# GCP native pricing via Cloud Billing API +opencost: + exporter: + customPricing: + enabled: true + provider: gcp + gcp: + projectID: "" # <- populate with your GCP project ID + key: "" # <- or use Workload Identity diff --git a/infra/values/gcp-prod/traefik-values.yaml b/infra/values/gcp-prod/traefik-values.yaml new file mode 100644 index 0000000..55351c0 --- /dev/null +++ b/infra/values/gcp-prod/traefik-values.yaml @@ -0,0 +1,15 @@ +# GCP GKE — External passthrough Network Load Balancer +service: + annotations: + cloud.google.com/l4-rbs: "enabled" +ports: + web: + proxyProtocol: + trustedIPs: "10.0.0.0/8,35.191.0.0/16,130.211.0.0/22" # <- subnet CIDR + GCP health checks + forwardedHeaders: + trustedIPs: "10.0.0.0/8,35.191.0.0/16,130.211.0.0/22" + websecure: + proxyProtocol: + trustedIPs: "10.0.0.0/8,35.191.0.0/16,130.211.0.0/22" + forwardedHeaders: + trustedIPs: "10.0.0.0/8,35.191.0.0/16,130.211.0.0/22" diff --git a/infra/values/upc-dev/gitea-values.yaml b/infra/values/upc-dev/gitea-values.yaml new file mode 100644 index 0000000..ef1f8eb --- /dev/null +++ b/infra/values/upc-dev/gitea-values.yaml @@ -0,0 +1,7 @@ +# UpCloud storage class for Gitea and its embedded PostgreSQL +persistence: + storageClass: upcloud-block-storage-maxiops +postgresql: + primary: + persistence: + storageClass: upcloud-block-storage-maxiops diff --git a/infra/values/upc-dev/opencost-values.yaml b/infra/values/upc-dev/opencost-values.yaml new file mode 100644 index 0000000..06a7488 --- /dev/null +++ b/infra/values/upc-dev/opencost-values.yaml @@ -0,0 +1,15 @@ +# UpCloud custom pricing (no native OpenCost integration) +opencost: + exporter: + customPricing: + enabled: true + provider: custom + costModel: + description: "UpCloud 4-node cluster pricing" + CPU: "5.86" + RAM: "1.46" + GPU: "0" + storage: "0.34" + zoneNetworkEgress: "0" + regionNetworkEgress: "0" + internetNetworkEgress: "0" diff --git a/infra/values/upc-prod/gitea-values.yaml b/infra/values/upc-prod/gitea-values.yaml new file mode 100644 index 0000000..ef1f8eb --- /dev/null +++ b/infra/values/upc-prod/gitea-values.yaml @@ -0,0 +1,7 @@ +# UpCloud storage class for Gitea and its embedded PostgreSQL +persistence: + storageClass: upcloud-block-storage-maxiops +postgresql: + primary: + persistence: + storageClass: upcloud-block-storage-maxiops diff --git a/infra/values/upc-prod/opencost-values.yaml b/infra/values/upc-prod/opencost-values.yaml new file mode 100644 index 0000000..06a7488 --- /dev/null +++ b/infra/values/upc-prod/opencost-values.yaml @@ -0,0 +1,15 @@ +# UpCloud custom pricing (no native OpenCost integration) +opencost: + exporter: + customPricing: + enabled: true + provider: custom + costModel: + description: "UpCloud 4-node cluster pricing" + CPU: "5.86" + RAM: "1.46" + GPU: "0" + storage: "0.34" + zoneNetworkEgress: "0" + regionNetworkEgress: "0" + internetNetworkEgress: "0" diff --git a/scripts/gitea-backup-aws.sh b/scripts/gitea-backup-aws.sh new file mode 100755 index 0000000..ebf0894 --- /dev/null +++ b/scripts/gitea-backup-aws.sh @@ -0,0 +1,94 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Gitea backup helper for AWS S3 +# Uses the gitea-backup-s3 secret in the gitea namespace +# (same secret schema: S3_ENDPOINT, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, S3_BUCKET) +# +# For AWS, S3_ENDPOINT is typically https://s3..amazonaws.com +# +# Usage: +# ./scripts/gitea-backup-aws.sh list # list all backups +# ./scripts/gitea-backup-aws.sh download # download a backup to current dir +# ./scripts/gitea-backup-aws.sh download latest # download the most recent backup + +NAMESPACE="gitea" +SECRET="gitea-backup-s3" +IMAGE="minio/mc:latest" +POD_NAME="gitea-backup-helper" +ALIAS_CMD='mc alias set s3 ${S3_ENDPOINT} ${AWS_ACCESS_KEY_ID} ${AWS_SECRET_ACCESS_KEY} > /dev/null' + +cleanup() { + kubectl -n "$NAMESPACE" delete pod "$POD_NAME" --ignore-not-found --grace-period=0 > /dev/null 2>&1 || true +} + +mc_run() { + cleanup + kubectl -n "$NAMESPACE" run "$POD_NAME" --restart=Never \ + --image="$IMAGE" \ + --overrides="{ + \"spec\":{\"containers\":[{ + \"name\":\"$POD_NAME\", + \"image\":\"$IMAGE\", + \"env\":[{\"name\":\"HOME\",\"value\":\"/tmp\"}], + \"command\":[\"sh\",\"-c\",\"${ALIAS_CMD}; $1\"], + \"envFrom\":[{\"secretRef\":{\"name\":\"$SECRET\"}}] + }]} + }" > /dev/null 2>&1 + + kubectl -n "$NAMESPACE" wait --for=jsonpath='{.status.phase}'=Succeeded "pod/$POD_NAME" --timeout=120s > /dev/null 2>&1 + kubectl -n "$NAMESPACE" logs "$POD_NAME" + cleanup +} + +case "${1:-help}" in + list) + echo "Listing backups..." + mc_run 'mc ls s3/${S3_BUCKET}/' + ;; + + download) + FILE="${2:?Usage: $0 download }" + + if [ "$FILE" = "latest" ]; then + echo "Finding latest backup..." + FILE=$(mc_run 'mc ls s3/${S3_BUCKET}/' | sort | tail -1 | awk '{print $NF}' | tr -d '[:space:]') + if [ -z "$FILE" ]; then + echo "No backups found." + exit 1 + fi + echo "Latest: $FILE" + fi + + echo "Downloading $FILE..." + cleanup + kubectl -n "$NAMESPACE" run "$POD_NAME" --restart=Never \ + --image="$IMAGE" \ + --overrides="{ + \"spec\":{\"containers\":[{ + \"name\":\"$POD_NAME\", + \"image\":\"$IMAGE\", + \"env\":[{\"name\":\"HOME\",\"value\":\"/tmp\"}], + \"command\":[\"sh\",\"-c\",\"sleep 300\"], + \"envFrom\":[{\"secretRef\":{\"name\":\"$SECRET\"}}] + }]} + }" > /dev/null 2>&1 + + kubectl -n "$NAMESPACE" wait --for=condition=Ready "pod/$POD_NAME" --timeout=60s > /dev/null 2>&1 + + echo "Saving to ./$FILE ..." + kubectl -n "$NAMESPACE" exec "$POD_NAME" -- sh -c "${ALIAS_CMD} && mc cat s3/\${S3_BUCKET}/$FILE" > "./$FILE" + cleanup + + echo "Downloaded: ./$FILE" + ;; + + *) + echo "Gitea backup helper (AWS S3)" + echo "" + echo "Usage:" + echo " $0 list List all backups in S3" + echo " $0 download Download a specific backup" + echo " $0 download latest Download the most recent backup" + ;; +esac diff --git a/scripts/gitea-backup-azure.sh b/scripts/gitea-backup-azure.sh new file mode 100755 index 0000000..e2f14d7 --- /dev/null +++ b/scripts/gitea-backup-azure.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Gitea backup helper for Azure Blob Storage +# Uses the gitea-backup-azure secret in the gitea namespace +# Required secret keys: +# AZURE_STORAGE_ACCOUNT — storage account name +# AZURE_STORAGE_KEY — storage account key +# AZURE_CONTAINER — blob container name +# +# Usage: +# ./scripts/gitea-backup-azure.sh list # list all backups +# ./scripts/gitea-backup-azure.sh download # download a backup +# ./scripts/gitea-backup-azure.sh download latest # download the most recent backup + +NAMESPACE="gitea" +SECRET="gitea-backup-azure" +IMAGE="mcr.microsoft.com/azure-cli:latest" +POD_NAME="gitea-backup-helper" + +cleanup() { + kubectl -n "$NAMESPACE" delete pod "$POD_NAME" --ignore-not-found --grace-period=0 > /dev/null 2>&1 || true +} + +az_run() { + cleanup + kubectl -n "$NAMESPACE" run "$POD_NAME" --restart=Never \ + --image="$IMAGE" \ + --overrides="{ + \"spec\":{\"containers\":[{ + \"name\":\"$POD_NAME\", + \"image\":\"$IMAGE\", + \"env\":[{\"name\":\"HOME\",\"value\":\"/tmp\"}], + \"command\":[\"sh\",\"-c\",\"$1\"], + \"envFrom\":[{\"secretRef\":{\"name\":\"$SECRET\"}}] + }]} + }" > /dev/null 2>&1 + + kubectl -n "$NAMESPACE" wait --for=jsonpath='{.status.phase}'=Succeeded "pod/$POD_NAME" --timeout=120s > /dev/null 2>&1 + kubectl -n "$NAMESPACE" logs "$POD_NAME" + cleanup +} + +case "${1:-help}" in + list) + echo "Listing backups..." + az_run 'az storage blob list --account-name ${AZURE_STORAGE_ACCOUNT} --account-key ${AZURE_STORAGE_KEY} --container-name ${AZURE_CONTAINER} --output table --query "[].{Name:name, Size:properties.contentLength, Modified:properties.lastModified}"' + ;; + + download) + FILE="${2:?Usage: $0 download }" + + if [ "$FILE" = "latest" ]; then + echo "Finding latest backup..." + FILE=$(az_run 'az storage blob list --account-name ${AZURE_STORAGE_ACCOUNT} --account-key ${AZURE_STORAGE_KEY} --container-name ${AZURE_CONTAINER} --query "sort_by([], &properties.lastModified)[-1].name" -o tsv' | tr -d '[:space:]') + if [ -z "$FILE" ]; then + echo "No backups found." + exit 1 + fi + echo "Latest: $FILE" + fi + + echo "Downloading $FILE..." + cleanup + kubectl -n "$NAMESPACE" run "$POD_NAME" --restart=Never \ + --image="$IMAGE" \ + --overrides="{ + \"spec\":{\"containers\":[{ + \"name\":\"$POD_NAME\", + \"image\":\"$IMAGE\", + \"env\":[{\"name\":\"HOME\",\"value\":\"/tmp\"}], + \"command\":[\"sh\",\"-c\",\"sleep 300\"], + \"envFrom\":[{\"secretRef\":{\"name\":\"$SECRET\"}}] + }]} + }" > /dev/null 2>&1 + + kubectl -n "$NAMESPACE" wait --for=condition=Ready "pod/$POD_NAME" --timeout=60s > /dev/null 2>&1 + + echo "Saving to ./$FILE ..." + kubectl -n "$NAMESPACE" exec "$POD_NAME" -- \ + az storage blob download \ + --account-name "\${AZURE_STORAGE_ACCOUNT}" \ + --account-key "\${AZURE_STORAGE_KEY}" \ + --container-name "\${AZURE_CONTAINER}" \ + --name "$FILE" \ + --file /dev/stdout 2>/dev/null > "./$FILE" + cleanup + + echo "Downloaded: ./$FILE" + ;; + + *) + echo "Gitea backup helper (Azure Blob Storage)" + echo "" + echo "Usage:" + echo " $0 list List all backups in Azure Blob" + echo " $0 download Download a specific backup" + echo " $0 download latest Download the most recent backup" + ;; +esac diff --git a/scripts/gitea-backup-gcp.sh b/scripts/gitea-backup-gcp.sh new file mode 100755 index 0000000..54fb7ef --- /dev/null +++ b/scripts/gitea-backup-gcp.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Gitea backup helper for Google Cloud Storage +# Uses the gitea-backup-gcs secret in the gitea namespace +# Required secret keys: +# GCS_BUCKET — bucket name (without gs:// prefix) +# GOOGLE_APPLICATION_CREDENTIALS_JSON — service account key JSON +# (alternatively, use Workload Identity and omit the key) +# +# Usage: +# ./scripts/gitea-backup-gcp.sh list # list all backups +# ./scripts/gitea-backup-gcp.sh download # download a backup +# ./scripts/gitea-backup-gcp.sh download latest # download the most recent backup + +NAMESPACE="gitea" +SECRET="gitea-backup-gcs" +IMAGE="gcr.io/google.com/cloudsdktool/google-cloud-cli:slim" +POD_NAME="gitea-backup-helper" +AUTH_CMD='if [ -n "${GOOGLE_APPLICATION_CREDENTIALS_JSON:-}" ]; then echo "${GOOGLE_APPLICATION_CREDENTIALS_JSON}" > /tmp/gcs-key.json && gcloud auth activate-service-account --key-file=/tmp/gcs-key.json > /dev/null 2>&1; fi' + +cleanup() { + kubectl -n "$NAMESPACE" delete pod "$POD_NAME" --ignore-not-found --grace-period=0 > /dev/null 2>&1 || true +} + +gcs_run() { + cleanup + kubectl -n "$NAMESPACE" run "$POD_NAME" --restart=Never \ + --image="$IMAGE" \ + --overrides="{ + \"spec\":{\"containers\":[{ + \"name\":\"$POD_NAME\", + \"image\":\"$IMAGE\", + \"env\":[{\"name\":\"HOME\",\"value\":\"/tmp\"}], + \"command\":[\"sh\",\"-c\",\"${AUTH_CMD}; $1\"], + \"envFrom\":[{\"secretRef\":{\"name\":\"$SECRET\"}}] + }]} + }" > /dev/null 2>&1 + + kubectl -n "$NAMESPACE" wait --for=jsonpath='{.status.phase}'=Succeeded "pod/$POD_NAME" --timeout=120s > /dev/null 2>&1 + kubectl -n "$NAMESPACE" logs "$POD_NAME" + cleanup +} + +case "${1:-help}" in + list) + echo "Listing backups..." + gcs_run 'gsutil ls -l gs://${GCS_BUCKET}/' + ;; + + download) + FILE="${2:?Usage: $0 download }" + + if [ "$FILE" = "latest" ]; then + echo "Finding latest backup..." + FILE=$(gcs_run 'gsutil ls gs://${GCS_BUCKET}/' | grep -v '^$' | grep -v 'TOTAL' | sort | tail -1 | xargs -I{} basename {} | tr -d '[:space:]') + if [ -z "$FILE" ]; then + echo "No backups found." + exit 1 + fi + echo "Latest: $FILE" + fi + + echo "Downloading $FILE..." + cleanup + kubectl -n "$NAMESPACE" run "$POD_NAME" --restart=Never \ + --image="$IMAGE" \ + --overrides="{ + \"spec\":{\"containers\":[{ + \"name\":\"$POD_NAME\", + \"image\":\"$IMAGE\", + \"env\":[{\"name\":\"HOME\",\"value\":\"/tmp\"}], + \"command\":[\"sh\",\"-c\",\"sleep 300\"], + \"envFrom\":[{\"secretRef\":{\"name\":\"$SECRET\"}}] + }]} + }" > /dev/null 2>&1 + + kubectl -n "$NAMESPACE" wait --for=condition=Ready "pod/$POD_NAME" --timeout=60s > /dev/null 2>&1 + + echo "Saving to ./$FILE ..." + kubectl -n "$NAMESPACE" exec "$POD_NAME" -- sh -c "${AUTH_CMD} && gsutil cat gs://\${GCS_BUCKET}/$FILE" > "./$FILE" + cleanup + + echo "Downloaded: ./$FILE" + ;; + + *) + echo "Gitea backup helper (Google Cloud Storage)" + echo "" + echo "Usage:" + echo " $0 list List all backups in GCS" + echo " $0 download Download a specific backup" + echo " $0 download latest Download the most recent backup" + ;; +esac From 4144b1c1ac1f2500ba7bff386982adbd1efab483 Mon Sep 17 00:00:00 2001 From: Danijel Simeunovic Date: Wed, 22 Apr 2026 13:39:43 +0200 Subject: [PATCH 2/9] token --- .gitea/workflows/ai-review.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitea/workflows/ai-review.yaml b/.gitea/workflows/ai-review.yaml index 808bb33..178a0ad 100644 --- a/.gitea/workflows/ai-review.yaml +++ b/.gitea/workflows/ai-review.yaml @@ -34,6 +34,7 @@ jobs: with: submodules: true fetch-depth: 0 + token: ${{ secrets.AI_REVIEW_TOKEN }} - name: Run inline review uses: docker://nikitafilonov/ai-review:v0.64.0 From dea54e469e8ab46436f9147fe0a677512016f1b9 Mon Sep 17 00:00:00 2001 From: Danijel Simeunovic Date: Wed, 22 Apr 2026 14:34:20 +0200 Subject: [PATCH 3/9] repo url --- _app-of-apps-aws-dev.yaml | 2 +- _app-of-apps-aws-prod.yaml | 2 +- _app-of-apps-azure-dev.yaml | 2 +- _app-of-apps-azure-prod.yaml | 2 +- _app-of-apps-gcp-dev.yaml | 2 +- _app-of-apps-gcp-prod.yaml | 2 +- _app-of-apps-upc-prod.yaml | 2 +- apps/base/dot-ai-stack.yaml | 2 +- infra/base/opencost.yaml | 2 +- infra/base/traefik-application.yaml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/_app-of-apps-aws-dev.yaml b/_app-of-apps-aws-dev.yaml index 061d19b..fa364c8 100644 --- a/_app-of-apps-aws-dev.yaml +++ b/_app-of-apps-aws-dev.yaml @@ -18,7 +18,7 @@ metadata: spec: project: default source: - repoURL: git@github.com:fortedigital/sturdy-adventure.git + repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git targetRevision: HEAD path: infra/overlays/aws-dev destination: diff --git a/_app-of-apps-aws-prod.yaml b/_app-of-apps-aws-prod.yaml index 62fd689..9922276 100644 --- a/_app-of-apps-aws-prod.yaml +++ b/_app-of-apps-aws-prod.yaml @@ -18,7 +18,7 @@ metadata: spec: project: default source: - repoURL: git@github.com:fortedigital/sturdy-adventure.git + repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git targetRevision: HEAD path: infra/overlays/aws-prod destination: diff --git a/_app-of-apps-azure-dev.yaml b/_app-of-apps-azure-dev.yaml index deeaefa..bd8ab3c 100644 --- a/_app-of-apps-azure-dev.yaml +++ b/_app-of-apps-azure-dev.yaml @@ -18,7 +18,7 @@ metadata: spec: project: default source: - repoURL: git@github.com:fortedigital/sturdy-adventure.git + repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git targetRevision: HEAD path: infra/overlays/azure-dev destination: diff --git a/_app-of-apps-azure-prod.yaml b/_app-of-apps-azure-prod.yaml index 9794896..1a9721f 100644 --- a/_app-of-apps-azure-prod.yaml +++ b/_app-of-apps-azure-prod.yaml @@ -18,7 +18,7 @@ metadata: spec: project: default source: - repoURL: git@github.com:fortedigital/sturdy-adventure.git + repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git targetRevision: HEAD path: infra/overlays/azure-prod destination: diff --git a/_app-of-apps-gcp-dev.yaml b/_app-of-apps-gcp-dev.yaml index 63843ce..d3ed8f7 100644 --- a/_app-of-apps-gcp-dev.yaml +++ b/_app-of-apps-gcp-dev.yaml @@ -18,7 +18,7 @@ metadata: spec: project: default source: - repoURL: git@github.com:fortedigital/sturdy-adventure.git + repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git targetRevision: HEAD path: infra/overlays/gcp-dev destination: diff --git a/_app-of-apps-gcp-prod.yaml b/_app-of-apps-gcp-prod.yaml index 32ae05f..51b3b90 100644 --- a/_app-of-apps-gcp-prod.yaml +++ b/_app-of-apps-gcp-prod.yaml @@ -18,7 +18,7 @@ metadata: spec: project: default source: - repoURL: git@github.com:fortedigital/sturdy-adventure.git + repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git targetRevision: HEAD path: infra/overlays/gcp-prod destination: diff --git a/_app-of-apps-upc-prod.yaml b/_app-of-apps-upc-prod.yaml index f5ccaca..64624f9 100644 --- a/_app-of-apps-upc-prod.yaml +++ b/_app-of-apps-upc-prod.yaml @@ -18,7 +18,7 @@ metadata: spec: project: default source: - repoURL: git@github.com:fortedigital/sturdy-adventure.git + repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git targetRevision: HEAD path: infra/overlays/upc-prod destination: diff --git a/apps/base/dot-ai-stack.yaml b/apps/base/dot-ai-stack.yaml index 3fd1284..23c93dc 100644 --- a/apps/base/dot-ai-stack.yaml +++ b/apps/base/dot-ai-stack.yaml @@ -37,7 +37,7 @@ spec: - $values/infra/values/base/dot-ai-stack-values.yaml - $values/infra/values/upc-dev/dot-ai-stack-values.yaml - - repoURL: git@github.com:fortedigital/sturdy-adventure.git + - repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git targetRevision: HEAD ref: values diff --git a/infra/base/opencost.yaml b/infra/base/opencost.yaml index a102906..c379cbf 100644 --- a/infra/base/opencost.yaml +++ b/infra/base/opencost.yaml @@ -24,7 +24,7 @@ spec: - $values/infra/values/base/opencost-values.yaml - $values/infra/values/upc-dev/opencost-values.yaml - - repoURL: git@github.com:fortedigital/sturdy-adventure.git + - repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git targetRevision: HEAD ref: values diff --git a/infra/base/traefik-application.yaml b/infra/base/traefik-application.yaml index eb9fd2c..8d585c8 100644 --- a/infra/base/traefik-application.yaml +++ b/infra/base/traefik-application.yaml @@ -31,7 +31,7 @@ spec: - $values/infra/values/base/traefik-values.yaml - $values/infra/values/upc-dev/traefik-values.yaml - - repoURL: git@github.com:fortedigital/sturdy-adventure.git + - repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git targetRevision: HEAD ref: values From 79f9c62012f861e2b307a5c60c1b535fe6cf5a2a Mon Sep 17 00:00:00 2001 From: Danijel Simeunovic Date: Wed, 22 Apr 2026 14:35:59 +0200 Subject: [PATCH 4/9] azure>aks --- README.md | 10 +++++----- ...-apps-azure-dev.yaml => _app-of-apps-aks-dev.yaml | 2 +- ...pps-azure-prod.yaml => _app-of-apps-aks-prod.yaml | 2 +- docs/GITOPS-ARCHITECTURE.md | 4 ++-- docs/OPERATIONS-RUNBOOK.md | 4 ++-- infra/overlays/azure-dev/kustomization.yaml | 12 ++++++------ infra/overlays/azure-prod/kustomization.yaml | 12 ++++++------ 7 files changed, 23 insertions(+), 23 deletions(-) rename _app-of-apps-azure-dev.yaml => _app-of-apps-aks-dev.yaml (95%) rename _app-of-apps-azure-prod.yaml => _app-of-apps-aks-prod.yaml (95%) diff --git a/README.md b/README.md index c9511e0..0727622 100644 --- a/README.md +++ b/README.md @@ -100,8 +100,8 @@ This repository contains the complete GitOps configuration for our Kubernetes cl │ │ ├── upc-prod/ # UpCloud Prod (patches value paths) │ │ ├── aws-dev/ # AWS EKS Dev │ │ ├── aws-prod/ # AWS EKS Prod -│ │ ├── azure-dev/ # Azure AKS Dev -│ │ ├── azure-prod/ # Azure AKS Prod +│ │ ├── aks-dev/ # Azure AKS Dev +│ │ ├── aks-prod/ # Azure AKS Prod │ │ ├── gcp-dev/ # GCP GKE Dev │ │ └── gcp-prod/ # GCP GKE Prod │ ├── dashboards/ # Grafana dashboard ConfigMaps @@ -111,8 +111,8 @@ This repository contains the complete GitOps configuration for our Kubernetes cl │ ├── upc-prod/ # UpCloud Prod │ ├── aws-dev/ # AWS EKS Dev │ ├── aws-prod/ # AWS EKS Prod -│ ├── azure-dev/ # Azure AKS Dev -│ ├── azure-prod/ # Azure AKS Prod +│ ├── aks-dev/ # Azure AKS Dev +│ ├── aks-prod/ # Azure AKS Prod │ ├── gcp-dev/ # GCP GKE Dev │ └── gcp-prod/ # GCP GKE Prod │ @@ -373,7 +373,7 @@ kubectl patch application myapp -n argocd \ ## 📖 Key Concepts ### App-of-Apps Pattern -`_app-of-apps-{cluster}.yaml` is the root Application that manages all other Applications in `infra/`. Kustomize overlays in `infra/overlays/{cluster}/` render the base Applications with per-cluster patches (e.g., swapping value file paths). Supported clusters: `upc-dev`, `upc-prod`, `aws-dev`, `aws-prod`, `azure-dev`, `azure-prod`, `gcp-dev`, `gcp-prod`. +`_app-of-apps-{cluster}.yaml` is the root Application that manages all other Applications in `infra/`. Kustomize overlays in `infra/overlays/{cluster}/` render the base Applications with per-cluster patches (e.g., swapping value file paths). Supported clusters: `upc-dev`, `upc-prod`, `aws-dev`, `aws-prod`, `aks-dev`, `aks-prod`, `gcp-dev`, `gcp-prod`. ### Multi-Source Pattern Applications reference both: diff --git a/_app-of-apps-azure-dev.yaml b/_app-of-apps-aks-dev.yaml similarity index 95% rename from _app-of-apps-azure-dev.yaml rename to _app-of-apps-aks-dev.yaml index bd8ab3c..9547bfe 100644 --- a/_app-of-apps-azure-dev.yaml +++ b/_app-of-apps-aks-dev.yaml @@ -20,7 +20,7 @@ spec: source: repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git targetRevision: HEAD - path: infra/overlays/azure-dev + path: infra/overlays/aks-dev destination: server: https://kubernetes.default.svc namespace: default diff --git a/_app-of-apps-azure-prod.yaml b/_app-of-apps-aks-prod.yaml similarity index 95% rename from _app-of-apps-azure-prod.yaml rename to _app-of-apps-aks-prod.yaml index 1a9721f..8b0b817 100644 --- a/_app-of-apps-azure-prod.yaml +++ b/_app-of-apps-aks-prod.yaml @@ -20,7 +20,7 @@ spec: source: repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git targetRevision: HEAD - path: infra/overlays/azure-prod + path: infra/overlays/aks-prod destination: server: https://kubernetes.default.svc namespace: default diff --git a/docs/GITOPS-ARCHITECTURE.md b/docs/GITOPS-ARCHITECTURE.md index a57fb4b..d811340 100644 --- a/docs/GITOPS-ARCHITECTURE.md +++ b/docs/GITOPS-ARCHITECTURE.md @@ -136,8 +136,8 @@ launchpad/ │ │ ├── upc-prod/ # UpCloud Prod (patches value paths) │ │ ├── aws-dev/ # AWS EKS Dev │ │ ├── aws-prod/ # AWS EKS Prod -│ │ ├── azure-dev/ # Azure AKS Dev -│ │ ├── azure-prod/ # Azure AKS Prod +│ │ ├── aks-dev/ # Azure AKS Dev +│ │ ├── aks-prod/ # Azure AKS Prod │ │ ├── gcp-dev/ # GCP GKE Dev │ │ └── gcp-prod/ # GCP GKE Prod │ ├── dashboards/ # Grafana dashboard ConfigMaps diff --git a/docs/OPERATIONS-RUNBOOK.md b/docs/OPERATIONS-RUNBOOK.md index 03ea097..dee0280 100644 --- a/docs/OPERATIONS-RUNBOOK.md +++ b/docs/OPERATIONS-RUNBOOK.md @@ -56,7 +56,7 @@ cd launchpad # 2. Run bootstrap script with cluster target # Available clusters: upc-dev, upc-prod, aws-dev, aws-prod, -# azure-dev, azure-prod, gcp-dev, gcp-prod +# aks-dev, aks-prod, gcp-dev, gcp-prod ./bootstrap.sh upc-dev # Cluster config is loaded from clusters/.yaml @@ -1528,7 +1528,7 @@ The repository supports multiple clusters across multiple clouds via Kustomize o **Cloud-ready templates (fill in `clusters/*.yaml` before use):** - **aws-dev** / **aws-prod**: AWS EKS with NLB, gp3 storage, AWS CUR pricing -- **azure-dev** / **azure-prod**: Azure AKS with Standard LB, managed-csi-premium storage +- **aks-dev** / **aks-prod**: Azure AKS with Standard LB, managed-csi-premium storage - **gcp-dev** / **gcp-prod**: GCP GKE with L4 LB, premium-rwo storage Each cluster has its own: diff --git a/infra/overlays/azure-dev/kustomization.yaml b/infra/overlays/azure-dev/kustomization.yaml index d7a014d..c230763 100644 --- a/infra/overlays/azure-dev/kustomization.yaml +++ b/infra/overlays/azure-dev/kustomization.yaml @@ -4,32 +4,32 @@ resources: - ../../base patches: -# Traefik: swap upc-dev → azure-dev +# Traefik: swap upc-dev → aks-dev - target: kind: Application name: traefik patch: | - op: replace path: /spec/sources/0/helm/valueFiles/1 - value: $values/infra/values/azure-dev/traefik-values.yaml + value: $values/infra/values/aks-dev/traefik-values.yaml -# Gitea: swap upc-dev → azure-dev +# Gitea: swap upc-dev → aks-dev - target: kind: Application name: gitea patch: | - op: replace path: /spec/sources/0/helm/valueFiles/1 - value: $values/infra/values/azure-dev/gitea-values.yaml + value: $values/infra/values/aks-dev/gitea-values.yaml -# OpenCost: swap upc-dev → azure-dev +# OpenCost: swap upc-dev → aks-dev - target: kind: Application name: opencost patch: | - op: replace path: /spec/sources/0/helm/valueFiles/1 - value: $values/infra/values/azure-dev/opencost-values.yaml + value: $values/infra/values/aks-dev/opencost-values.yaml # TODO: add patches for keycloak, grafana, secrets, enterprise-apps # when deploying to this cluster (these are deployment-specific, not cloud-specific) diff --git a/infra/overlays/azure-prod/kustomization.yaml b/infra/overlays/azure-prod/kustomization.yaml index 4a9d6cf..5cadfd5 100644 --- a/infra/overlays/azure-prod/kustomization.yaml +++ b/infra/overlays/azure-prod/kustomization.yaml @@ -4,32 +4,32 @@ resources: - ../../base patches: -# Traefik: swap upc-dev → azure-prod +# Traefik: swap upc-dev → aks-prod - target: kind: Application name: traefik patch: | - op: replace path: /spec/sources/0/helm/valueFiles/1 - value: $values/infra/values/azure-prod/traefik-values.yaml + value: $values/infra/values/aks-prod/traefik-values.yaml -# Gitea: swap upc-dev → azure-prod +# Gitea: swap upc-dev → aks-prod - target: kind: Application name: gitea patch: | - op: replace path: /spec/sources/0/helm/valueFiles/1 - value: $values/infra/values/azure-prod/gitea-values.yaml + value: $values/infra/values/aks-prod/gitea-values.yaml -# OpenCost: swap upc-dev → azure-prod +# OpenCost: swap upc-dev → aks-prod - target: kind: Application name: opencost patch: | - op: replace path: /spec/sources/0/helm/valueFiles/1 - value: $values/infra/values/azure-prod/opencost-values.yaml + value: $values/infra/values/aks-prod/opencost-values.yaml # TODO: add patches for keycloak, grafana, secrets, enterprise-apps # when deploying to this cluster (these are deployment-specific, not cloud-specific) From 7d2fb8bc0c04a639295c4f057375d6aeba70ec32 Mon Sep 17 00:00:00 2001 From: Danijel Simeunovic Date: Wed, 22 Apr 2026 14:41:42 +0200 Subject: [PATCH 5/9] azure>aks --- clusters/{azure-dev.yaml => aks-dev.yaml} | 0 clusters/{azure-prod.yaml => aks-prod.yaml} | 0 .../overlays/{azure-dev => aks-dev}/kustomization.yaml | 0 .../{azure-prod => aks-prod}/kustomization.yaml | 0 infra/values/{azure-dev => aks-dev}/gitea-values.yaml | 0 .../values/{azure-dev => aks-dev}/opencost-values.yaml | 0 .../values/{azure-dev => aks-dev}/traefik-values.yaml | 0 .../values/{azure-prod => aks-prod}/gitea-values.yaml | 0 .../{azure-prod => aks-prod}/opencost-values.yaml | 0 .../{azure-prod => aks-prod}/traefik-values.yaml | 0 scripts/{gitea-backup-azure.sh => gitea-backup-aks.sh} | 10 +++++----- 11 files changed, 5 insertions(+), 5 deletions(-) rename clusters/{azure-dev.yaml => aks-dev.yaml} (100%) rename clusters/{azure-prod.yaml => aks-prod.yaml} (100%) rename infra/overlays/{azure-dev => aks-dev}/kustomization.yaml (100%) rename infra/overlays/{azure-prod => aks-prod}/kustomization.yaml (100%) rename infra/values/{azure-dev => aks-dev}/gitea-values.yaml (100%) rename infra/values/{azure-dev => aks-dev}/opencost-values.yaml (100%) rename infra/values/{azure-dev => aks-dev}/traefik-values.yaml (100%) rename infra/values/{azure-prod => aks-prod}/gitea-values.yaml (100%) rename infra/values/{azure-prod => aks-prod}/opencost-values.yaml (100%) rename infra/values/{azure-prod => aks-prod}/traefik-values.yaml (100%) rename scripts/{gitea-backup-azure.sh => gitea-backup-aks.sh} (90%) mode change 100755 => 100644 diff --git a/clusters/azure-dev.yaml b/clusters/aks-dev.yaml similarity index 100% rename from clusters/azure-dev.yaml rename to clusters/aks-dev.yaml diff --git a/clusters/azure-prod.yaml b/clusters/aks-prod.yaml similarity index 100% rename from clusters/azure-prod.yaml rename to clusters/aks-prod.yaml diff --git a/infra/overlays/azure-dev/kustomization.yaml b/infra/overlays/aks-dev/kustomization.yaml similarity index 100% rename from infra/overlays/azure-dev/kustomization.yaml rename to infra/overlays/aks-dev/kustomization.yaml diff --git a/infra/overlays/azure-prod/kustomization.yaml b/infra/overlays/aks-prod/kustomization.yaml similarity index 100% rename from infra/overlays/azure-prod/kustomization.yaml rename to infra/overlays/aks-prod/kustomization.yaml diff --git a/infra/values/azure-dev/gitea-values.yaml b/infra/values/aks-dev/gitea-values.yaml similarity index 100% rename from infra/values/azure-dev/gitea-values.yaml rename to infra/values/aks-dev/gitea-values.yaml diff --git a/infra/values/azure-dev/opencost-values.yaml b/infra/values/aks-dev/opencost-values.yaml similarity index 100% rename from infra/values/azure-dev/opencost-values.yaml rename to infra/values/aks-dev/opencost-values.yaml diff --git a/infra/values/azure-dev/traefik-values.yaml b/infra/values/aks-dev/traefik-values.yaml similarity index 100% rename from infra/values/azure-dev/traefik-values.yaml rename to infra/values/aks-dev/traefik-values.yaml diff --git a/infra/values/azure-prod/gitea-values.yaml b/infra/values/aks-prod/gitea-values.yaml similarity index 100% rename from infra/values/azure-prod/gitea-values.yaml rename to infra/values/aks-prod/gitea-values.yaml diff --git a/infra/values/azure-prod/opencost-values.yaml b/infra/values/aks-prod/opencost-values.yaml similarity index 100% rename from infra/values/azure-prod/opencost-values.yaml rename to infra/values/aks-prod/opencost-values.yaml diff --git a/infra/values/azure-prod/traefik-values.yaml b/infra/values/aks-prod/traefik-values.yaml similarity index 100% rename from infra/values/azure-prod/traefik-values.yaml rename to infra/values/aks-prod/traefik-values.yaml diff --git a/scripts/gitea-backup-azure.sh b/scripts/gitea-backup-aks.sh old mode 100755 new mode 100644 similarity index 90% rename from scripts/gitea-backup-azure.sh rename to scripts/gitea-backup-aks.sh index e2f14d7..5ab2653 --- a/scripts/gitea-backup-azure.sh +++ b/scripts/gitea-backup-aks.sh @@ -2,19 +2,19 @@ set -euo pipefail # Gitea backup helper for Azure Blob Storage -# Uses the gitea-backup-azure secret in the gitea namespace +# Uses the gitea-backup-aks secret in the gitea namespace # Required secret keys: # AZURE_STORAGE_ACCOUNT — storage account name # AZURE_STORAGE_KEY — storage account key # AZURE_CONTAINER — blob container name # # Usage: -# ./scripts/gitea-backup-azure.sh list # list all backups -# ./scripts/gitea-backup-azure.sh download # download a backup -# ./scripts/gitea-backup-azure.sh download latest # download the most recent backup +# ./scripts/gitea-backup-aks.sh list # list all backups +# ./scripts/gitea-backup-aks.sh download # download a backup +# ./scripts/gitea-backup-aks.sh download latest # download the most recent backup NAMESPACE="gitea" -SECRET="gitea-backup-azure" +SECRET="gitea-backup-aks" IMAGE="mcr.microsoft.com/azure-cli:latest" POD_NAME="gitea-backup-helper" From 92ddc22322a23dacb397d859aa94bf4882061f5f Mon Sep 17 00:00:00 2001 From: Danijel Simeunovic Date: Wed, 22 Apr 2026 14:42:02 +0200 Subject: [PATCH 6/9] azure>aks --- docs/GITOPS-ARCHITECTURE.md | 2 +- docs/OPERATIONS-RUNBOOK.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/GITOPS-ARCHITECTURE.md b/docs/GITOPS-ARCHITECTURE.md index d811340..3105321 100644 --- a/docs/GITOPS-ARCHITECTURE.md +++ b/docs/GITOPS-ARCHITECTURE.md @@ -145,7 +145,7 @@ launchpad/ │ ├── base/ # Cloud-agnostic shared values │ ├── upc-{dev,prod}/ # UpCloud: storage class, LB, pricing │ ├── aws-{dev,prod}/ # AWS: gp3, NLB, CUR pricing -│ ├── azure-{dev,prod}/ # Azure: managed-csi-premium, Standard LB +│ ├── aks-{dev,prod}/ # Azure: managed-csi-premium, Standard LB │ └── gcp-{dev,prod}/ # GCP: premium-rwo, L4 LB │ ├── apps/ # Business Application ArgoCD manifests (Kustomize) diff --git a/docs/OPERATIONS-RUNBOOK.md b/docs/OPERATIONS-RUNBOOK.md index dee0280..8d0f101 100644 --- a/docs/OPERATIONS-RUNBOOK.md +++ b/docs/OPERATIONS-RUNBOOK.md @@ -1277,7 +1277,7 @@ spec: **Per-cloud backup scripts** (manual restore helpers): - UpCloud/AWS: `scripts/gitea-backup.sh` / `scripts/gitea-backup-aws.sh` (MinIO CLI, S3-compatible) -- Azure: `scripts/gitea-backup-azure.sh` (Azure CLI + Blob Storage) +- Azure: `scripts/gitea-backup-aks.sh` (Azure CLI + Blob Storage) - GCP: `scripts/gitea-backup-gcp.sh` (gsutil + GCS) ### Cluster Rebuild From c8c2dedea5b72582af68f1dca9aa5e69db7bc7c4 Mon Sep 17 00:00:00 2001 From: Danijel Simeunovic Date: Wed, 22 Apr 2026 21:48:02 +0200 Subject: [PATCH 7/9] rename --- README.md | 18 +++++++++--------- ...s-aws-dev.yaml => _app-of-apps-eks-dev.yaml | 2 +- ...aws-prod.yaml => _app-of-apps-eks-prod.yaml | 2 +- ...s-gcp-dev.yaml => _app-of-apps-gke-dev.yaml | 2 +- ...gcp-prod.yaml => _app-of-apps-gke-prod.yaml | 2 +- clusters/{aws-dev.yaml => eks-dev.yaml} | 2 +- clusters/{aws-prod.yaml => eks-prod.yaml} | 2 +- clusters/{gcp-dev.yaml => gke-dev.yaml} | 2 +- clusters/{gcp-prod.yaml => gke-prod.yaml} | 2 +- docs/GITOPS-ARCHITECTURE.md | 10 +++++----- docs/OPERATIONS-RUNBOOK.md | 14 +++++++------- docs/REFERENCE.md | 2 +- .../{gcp-dev => eks-dev}/kustomization.yaml | 12 ++++++------ .../{gcp-prod => eks-prod}/kustomization.yaml | 12 ++++++------ .../{aws-dev => gke-dev}/kustomization.yaml | 12 ++++++------ .../{aws-prod => gke-prod}/kustomization.yaml | 12 ++++++------ .../{aws-dev => eks-dev}/gitea-values.yaml | 0 .../{aws-dev => eks-dev}/opencost-values.yaml | 0 .../{aws-dev => eks-dev}/traefik-values.yaml | 0 .../{aws-prod => eks-prod}/gitea-values.yaml | 0 .../opencost-values.yaml | 0 .../{aws-prod => eks-prod}/traefik-values.yaml | 0 .../{gcp-dev => gke-dev}/gitea-values.yaml | 0 .../{gcp-dev => gke-dev}/opencost-values.yaml | 0 .../{gcp-dev => gke-dev}/traefik-values.yaml | 0 .../{gcp-prod => gke-prod}/gitea-values.yaml | 0 .../opencost-values.yaml | 0 .../{gcp-prod => gke-prod}/traefik-values.yaml | 0 ...gitea-backup-aws.sh => gitea-backup-eks.sh} | 6 +++--- ...gitea-backup-gcp.sh => gitea-backup-gke.sh} | 6 +++--- 30 files changed, 60 insertions(+), 60 deletions(-) rename _app-of-apps-aws-dev.yaml => _app-of-apps-eks-dev.yaml (95%) rename _app-of-apps-aws-prod.yaml => _app-of-apps-eks-prod.yaml (95%) rename _app-of-apps-gcp-dev.yaml => _app-of-apps-gke-dev.yaml (95%) rename _app-of-apps-gcp-prod.yaml => _app-of-apps-gke-prod.yaml (95%) rename clusters/{aws-dev.yaml => eks-dev.yaml} (95%) rename clusters/{aws-prod.yaml => eks-prod.yaml} (95%) rename clusters/{gcp-dev.yaml => gke-dev.yaml} (95%) rename clusters/{gcp-prod.yaml => gke-prod.yaml} (95%) rename infra/overlays/{gcp-dev => eks-dev}/kustomization.yaml (68%) rename infra/overlays/{gcp-prod => eks-prod}/kustomization.yaml (67%) rename infra/overlays/{aws-dev => gke-dev}/kustomization.yaml (68%) rename infra/overlays/{aws-prod => gke-prod}/kustomization.yaml (67%) rename infra/values/{aws-dev => eks-dev}/gitea-values.yaml (100%) rename infra/values/{aws-dev => eks-dev}/opencost-values.yaml (100%) rename infra/values/{aws-dev => eks-dev}/traefik-values.yaml (100%) rename infra/values/{aws-prod => eks-prod}/gitea-values.yaml (100%) rename infra/values/{aws-prod => eks-prod}/opencost-values.yaml (100%) rename infra/values/{aws-prod => eks-prod}/traefik-values.yaml (100%) rename infra/values/{gcp-dev => gke-dev}/gitea-values.yaml (100%) rename infra/values/{gcp-dev => gke-dev}/opencost-values.yaml (100%) rename infra/values/{gcp-dev => gke-dev}/traefik-values.yaml (100%) rename infra/values/{gcp-prod => gke-prod}/gitea-values.yaml (100%) rename infra/values/{gcp-prod => gke-prod}/opencost-values.yaml (100%) rename infra/values/{gcp-prod => gke-prod}/traefik-values.yaml (100%) rename scripts/{gitea-backup-aws.sh => gitea-backup-eks.sh} (93%) mode change 100755 => 100644 rename scripts/{gitea-backup-gcp.sh => gitea-backup-gke.sh} (94%) mode change 100755 => 100644 diff --git a/README.md b/README.md index 0727622..b560f46 100644 --- a/README.md +++ b/README.md @@ -98,23 +98,23 @@ This repository contains the complete GitOps configuration for our Kubernetes cl │ ├── overlays/ # Per-cluster overrides (Kustomize) │ │ ├── upc-dev/ # UpCloud Dev (uses base as-is) │ │ ├── upc-prod/ # UpCloud Prod (patches value paths) -│ │ ├── aws-dev/ # AWS EKS Dev -│ │ ├── aws-prod/ # AWS EKS Prod +│ │ ├── eks-dev/ # AWS EKS Dev +│ │ ├── eks-prod/ # AWS EKS Prod │ │ ├── aks-dev/ # Azure AKS Dev │ │ ├── aks-prod/ # Azure AKS Prod -│ │ ├── gcp-dev/ # GCP GKE Dev -│ │ └── gcp-prod/ # GCP GKE Prod +│ │ ├── gke-dev/ # GCP GKE Dev +│ │ └── gke-prod/ # GCP GKE Prod │ ├── dashboards/ # Grafana dashboard ConfigMaps │ └── values/ # Helm value overrides │ ├── base/ # Shared cloud-agnostic values │ ├── upc-dev/ # UpCloud Dev (storage, LB, pricing) │ ├── upc-prod/ # UpCloud Prod -│ ├── aws-dev/ # AWS EKS Dev -│ ├── aws-prod/ # AWS EKS Prod +│ ├── eks-dev/ # AWS EKS Dev +│ ├── eks-prod/ # AWS EKS Prod │ ├── aks-dev/ # Azure AKS Dev │ ├── aks-prod/ # Azure AKS Prod -│ ├── gcp-dev/ # GCP GKE Dev -│ └── gcp-prod/ # GCP GKE Prod +│ ├── gke-dev/ # GCP GKE Dev +│ └── gke-prod/ # GCP GKE Prod │ ├── apps/ # Business Applications │ ├── mcp10x.yaml @@ -373,7 +373,7 @@ kubectl patch application myapp -n argocd \ ## 📖 Key Concepts ### App-of-Apps Pattern -`_app-of-apps-{cluster}.yaml` is the root Application that manages all other Applications in `infra/`. Kustomize overlays in `infra/overlays/{cluster}/` render the base Applications with per-cluster patches (e.g., swapping value file paths). Supported clusters: `upc-dev`, `upc-prod`, `aws-dev`, `aws-prod`, `aks-dev`, `aks-prod`, `gcp-dev`, `gcp-prod`. +`_app-of-apps-{cluster}.yaml` is the root Application that manages all other Applications in `infra/`. Kustomize overlays in `infra/overlays/{cluster}/` render the base Applications with per-cluster patches (e.g., swapping value file paths). Supported clusters: `upc-dev`, `upc-prod`, `eks-dev`, `eks-prod`, `aks-dev`, `aks-prod`, `gke-dev`, `gke-prod`. ### Multi-Source Pattern Applications reference both: diff --git a/_app-of-apps-aws-dev.yaml b/_app-of-apps-eks-dev.yaml similarity index 95% rename from _app-of-apps-aws-dev.yaml rename to _app-of-apps-eks-dev.yaml index fa364c8..f40e164 100644 --- a/_app-of-apps-aws-dev.yaml +++ b/_app-of-apps-eks-dev.yaml @@ -20,7 +20,7 @@ spec: source: repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git targetRevision: HEAD - path: infra/overlays/aws-dev + path: infra/overlays/eks-dev destination: server: https://kubernetes.default.svc namespace: default diff --git a/_app-of-apps-aws-prod.yaml b/_app-of-apps-eks-prod.yaml similarity index 95% rename from _app-of-apps-aws-prod.yaml rename to _app-of-apps-eks-prod.yaml index 9922276..29337cb 100644 --- a/_app-of-apps-aws-prod.yaml +++ b/_app-of-apps-eks-prod.yaml @@ -20,7 +20,7 @@ spec: source: repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git targetRevision: HEAD - path: infra/overlays/aws-prod + path: infra/overlays/eks-prod destination: server: https://kubernetes.default.svc namespace: default diff --git a/_app-of-apps-gcp-dev.yaml b/_app-of-apps-gke-dev.yaml similarity index 95% rename from _app-of-apps-gcp-dev.yaml rename to _app-of-apps-gke-dev.yaml index d3ed8f7..faf753c 100644 --- a/_app-of-apps-gcp-dev.yaml +++ b/_app-of-apps-gke-dev.yaml @@ -20,7 +20,7 @@ spec: source: repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git targetRevision: HEAD - path: infra/overlays/gcp-dev + path: infra/overlays/gke-dev destination: server: https://kubernetes.default.svc namespace: default diff --git a/_app-of-apps-gcp-prod.yaml b/_app-of-apps-gke-prod.yaml similarity index 95% rename from _app-of-apps-gcp-prod.yaml rename to _app-of-apps-gke-prod.yaml index 51b3b90..874cebd 100644 --- a/_app-of-apps-gcp-prod.yaml +++ b/_app-of-apps-gke-prod.yaml @@ -20,7 +20,7 @@ spec: source: repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git targetRevision: HEAD - path: infra/overlays/gcp-prod + path: infra/overlays/gke-prod destination: server: https://kubernetes.default.svc namespace: default diff --git a/clusters/aws-dev.yaml b/clusters/eks-dev.yaml similarity index 95% rename from clusters/aws-dev.yaml rename to clusters/eks-dev.yaml index 02f3034..55ffa95 100644 --- a/clusters/aws-dev.yaml +++ b/clusters/eks-dev.yaml @@ -7,4 +7,4 @@ dotaiDomain: kubemcp.example.com dotaiUiDomain: kubemcpui.example.com letsencryptEmail: admin@example.com # <- adjust trustedIPs: "10.0.0.0/8" # <- adjust to your VPC CIDR -cloudProvider: aws +cloudProvider: eks diff --git a/clusters/aws-prod.yaml b/clusters/eks-prod.yaml similarity index 95% rename from clusters/aws-prod.yaml rename to clusters/eks-prod.yaml index c5973f9..8dcfc90 100644 --- a/clusters/aws-prod.yaml +++ b/clusters/eks-prod.yaml @@ -7,4 +7,4 @@ dotaiDomain: kubemcp.example.com dotaiUiDomain: kubemcpui.example.com letsencryptEmail: admin@example.com # <- adjust trustedIPs: "10.0.0.0/8" # <- adjust to your VPC CIDR -cloudProvider: aws +cloudProvider: eks diff --git a/clusters/gcp-dev.yaml b/clusters/gke-dev.yaml similarity index 95% rename from clusters/gcp-dev.yaml rename to clusters/gke-dev.yaml index 43f3861..2bd2801 100644 --- a/clusters/gcp-dev.yaml +++ b/clusters/gke-dev.yaml @@ -7,4 +7,4 @@ dotaiDomain: kubemcp.example.com dotaiUiDomain: kubemcpui.example.com letsencryptEmail: admin@example.com # <- adjust trustedIPs: "10.0.0.0/8,35.191.0.0/16,130.211.0.0/22" # <- subnet CIDR + GCP health checks -cloudProvider: gcp +cloudProvider: gke diff --git a/clusters/gcp-prod.yaml b/clusters/gke-prod.yaml similarity index 95% rename from clusters/gcp-prod.yaml rename to clusters/gke-prod.yaml index ec814f7..7d8740f 100644 --- a/clusters/gcp-prod.yaml +++ b/clusters/gke-prod.yaml @@ -7,4 +7,4 @@ dotaiDomain: kubemcp.example.com dotaiUiDomain: kubemcpui.example.com letsencryptEmail: admin@example.com # <- adjust trustedIPs: "10.0.0.0/8,35.191.0.0/16,130.211.0.0/22" # <- subnet CIDR + GCP health checks -cloudProvider: gcp +cloudProvider: gke diff --git a/docs/GITOPS-ARCHITECTURE.md b/docs/GITOPS-ARCHITECTURE.md index 3105321..b199cc8 100644 --- a/docs/GITOPS-ARCHITECTURE.md +++ b/docs/GITOPS-ARCHITECTURE.md @@ -134,12 +134,12 @@ launchpad/ │ ├── overlays/ # Per-cluster Kustomize overrides │ │ ├── upc-dev/ # UpCloud Dev (uses base as-is) │ │ ├── upc-prod/ # UpCloud Prod (patches value paths) -│ │ ├── aws-dev/ # AWS EKS Dev -│ │ ├── aws-prod/ # AWS EKS Prod +│ │ ├── eks-dev/ # AWS EKS Dev +│ │ ├── eks-prod/ # AWS EKS Prod │ │ ├── aks-dev/ # Azure AKS Dev │ │ ├── aks-prod/ # Azure AKS Prod -│ │ ├── gcp-dev/ # GCP GKE Dev -│ │ └── gcp-prod/ # GCP GKE Prod +│ │ ├── gke-dev/ # GCP GKE Dev +│ │ └── gke-prod/ # GCP GKE Prod │ ├── dashboards/ # Grafana dashboard ConfigMaps │ └── values/ # Helm value overrides for infra │ ├── base/ # Cloud-agnostic shared values @@ -283,7 +283,7 @@ app-repository/ ### The App-of-Apps Pattern ``` -_app-of-apps-{cluster}.yaml (Root, per cluster — e.g. upc-dev, aws-prod, gcp-dev) +_app-of-apps-{cluster}.yaml (Root, per cluster — e.g. upc-dev, eks-prod, gke-dev) │ ├── infrastructure-apps (manages infra/) │ ├── cluster-resources-application diff --git a/docs/OPERATIONS-RUNBOOK.md b/docs/OPERATIONS-RUNBOOK.md index 8d0f101..586a806 100644 --- a/docs/OPERATIONS-RUNBOOK.md +++ b/docs/OPERATIONS-RUNBOOK.md @@ -55,8 +55,8 @@ git clone https://git.forteapps.net/Forte/launchpad cd launchpad # 2. Run bootstrap script with cluster target -# Available clusters: upc-dev, upc-prod, aws-dev, aws-prod, -# aks-dev, aks-prod, gcp-dev, gcp-prod +# Available clusters: upc-dev, upc-prod, eks-dev, eks-prod, +# aks-dev, aks-prod, gke-dev, gke-prod ./bootstrap.sh upc-dev # Cluster config is loaded from clusters/.yaml @@ -1276,9 +1276,9 @@ spec: - ❌ Other persistent volumes (Prometheus, Loki, Tempo data) **Per-cloud backup scripts** (manual restore helpers): -- UpCloud/AWS: `scripts/gitea-backup.sh` / `scripts/gitea-backup-aws.sh` (MinIO CLI, S3-compatible) +- UpCloud/AWS: `scripts/gitea-backup.sh` / `scripts/gitea-backup-eks.sh` (MinIO CLI, S3-compatible) - Azure: `scripts/gitea-backup-aks.sh` (Azure CLI + Blob Storage) -- GCP: `scripts/gitea-backup-gcp.sh` (gsutil + GCS) +- GCP: `scripts/gitea-backup-gke.sh` (gsutil + GCS) ### Cluster Rebuild @@ -1527,9 +1527,9 @@ The repository supports multiple clusters across multiple clouds via Kustomize o - **upc-prod**: `infra/overlays/upc-prod/` — patches value file paths from `upc-dev` to `upc-prod` **Cloud-ready templates (fill in `clusters/*.yaml` before use):** -- **aws-dev** / **aws-prod**: AWS EKS with NLB, gp3 storage, AWS CUR pricing +- **eks-dev** / **eks-prod**: AWS EKS with NLB, gp3 storage, AWS CUR pricing - **aks-dev** / **aks-prod**: Azure AKS with Standard LB, managed-csi-premium storage -- **gcp-dev** / **gcp-prod**: GCP GKE with L4 LB, premium-rwo storage +- **gke-dev** / **gke-prod**: GCP GKE with L4 LB, premium-rwo storage Each cluster has its own: - Root app-of-apps: `_app-of-apps-{cluster}.yaml` @@ -1548,7 +1548,7 @@ Cloud-specific values handled per-cluster: | **Cost monitoring** | Custom pricing | AWS CUR | Azure Billing API | GCP Cloud Billing | | **Backup storage** | UpCloud S3-compat | AWS S3 (native) | Azure Blob Storage | GCS | -To add a new cluster, create a new overlay directory (e.g., `infra/overlays/aws-staging/`) with patches that swap the value file paths, and a matching `clusters/aws-staging.yaml`. +To add a new cluster, create a new overlay directory (e.g., `infra/overlays/eks-staging/`) with patches that swap the value file paths, and a matching `clusters/eks-staging.yaml`. ### Blue-Green Deployments diff --git a/docs/REFERENCE.md b/docs/REFERENCE.md index 50ba6b3..029cdda 100644 --- a/docs/REFERENCE.md +++ b/docs/REFERENCE.md @@ -21,7 +21,7 @@ |-----------|-------| | **Provider** | Multi-cloud (UpCloud, AWS EKS, Azure AKS, GCP GKE) | | **Active clusters** | UpCloud (upc-dev, upc-prod) | -| **Cloud-ready templates** | AWS, Azure, GCP (dev + prod each) | +| **Cloud-ready templates** | EKS, AKS, GKE (dev + prod each) | | **GitOps Tool** | ArgoCD | | **Ingress Controller** | Traefik v2 | | **Certificate Management** | Cert-Manager + Let's Encrypt | diff --git a/infra/overlays/gcp-dev/kustomization.yaml b/infra/overlays/eks-dev/kustomization.yaml similarity index 68% rename from infra/overlays/gcp-dev/kustomization.yaml rename to infra/overlays/eks-dev/kustomization.yaml index 491065e..c8690bf 100644 --- a/infra/overlays/gcp-dev/kustomization.yaml +++ b/infra/overlays/eks-dev/kustomization.yaml @@ -4,32 +4,32 @@ resources: - ../../base patches: -# Traefik: swap upc-dev → gcp-dev +# Traefik: swap upc-dev → eks-dev - target: kind: Application name: traefik patch: | - op: replace path: /spec/sources/0/helm/valueFiles/1 - value: $values/infra/values/gcp-dev/traefik-values.yaml + value: $values/infra/values/eks-dev/traefik-values.yaml -# Gitea: swap upc-dev → gcp-dev +# Gitea: swap upc-dev → eks-dev - target: kind: Application name: gitea patch: | - op: replace path: /spec/sources/0/helm/valueFiles/1 - value: $values/infra/values/gcp-dev/gitea-values.yaml + value: $values/infra/values/eks-dev/gitea-values.yaml -# OpenCost: swap upc-dev → gcp-dev +# OpenCost: swap upc-dev → eks-dev - target: kind: Application name: opencost patch: | - op: replace path: /spec/sources/0/helm/valueFiles/1 - value: $values/infra/values/gcp-dev/opencost-values.yaml + value: $values/infra/values/eks-dev/opencost-values.yaml # TODO: add patches for keycloak, grafana, secrets, enterprise-apps # when deploying to this cluster (these are deployment-specific, not cloud-specific) diff --git a/infra/overlays/gcp-prod/kustomization.yaml b/infra/overlays/eks-prod/kustomization.yaml similarity index 67% rename from infra/overlays/gcp-prod/kustomization.yaml rename to infra/overlays/eks-prod/kustomization.yaml index 9971aa9..7ab683d 100644 --- a/infra/overlays/gcp-prod/kustomization.yaml +++ b/infra/overlays/eks-prod/kustomization.yaml @@ -4,32 +4,32 @@ resources: - ../../base patches: -# Traefik: swap upc-dev → gcp-prod +# Traefik: swap upc-dev → eks-prod - target: kind: Application name: traefik patch: | - op: replace path: /spec/sources/0/helm/valueFiles/1 - value: $values/infra/values/gcp-prod/traefik-values.yaml + value: $values/infra/values/eks-prod/traefik-values.yaml -# Gitea: swap upc-dev → gcp-prod +# Gitea: swap upc-dev → eks-prod - target: kind: Application name: gitea patch: | - op: replace path: /spec/sources/0/helm/valueFiles/1 - value: $values/infra/values/gcp-prod/gitea-values.yaml + value: $values/infra/values/eks-prod/gitea-values.yaml -# OpenCost: swap upc-dev → gcp-prod +# OpenCost: swap upc-dev → eks-prod - target: kind: Application name: opencost patch: | - op: replace path: /spec/sources/0/helm/valueFiles/1 - value: $values/infra/values/gcp-prod/opencost-values.yaml + value: $values/infra/values/eks-prod/opencost-values.yaml # TODO: add patches for keycloak, grafana, secrets, enterprise-apps # when deploying to this cluster (these are deployment-specific, not cloud-specific) diff --git a/infra/overlays/aws-dev/kustomization.yaml b/infra/overlays/gke-dev/kustomization.yaml similarity index 68% rename from infra/overlays/aws-dev/kustomization.yaml rename to infra/overlays/gke-dev/kustomization.yaml index 4be71fc..147bb76 100644 --- a/infra/overlays/aws-dev/kustomization.yaml +++ b/infra/overlays/gke-dev/kustomization.yaml @@ -4,32 +4,32 @@ resources: - ../../base patches: -# Traefik: swap upc-dev → aws-dev +# Traefik: swap upc-dev → gke-dev - target: kind: Application name: traefik patch: | - op: replace path: /spec/sources/0/helm/valueFiles/1 - value: $values/infra/values/aws-dev/traefik-values.yaml + value: $values/infra/values/gke-dev/traefik-values.yaml -# Gitea: swap upc-dev → aws-dev +# Gitea: swap upc-dev → gke-dev - target: kind: Application name: gitea patch: | - op: replace path: /spec/sources/0/helm/valueFiles/1 - value: $values/infra/values/aws-dev/gitea-values.yaml + value: $values/infra/values/gke-dev/gitea-values.yaml -# OpenCost: swap upc-dev → aws-dev +# OpenCost: swap upc-dev → gke-dev - target: kind: Application name: opencost patch: | - op: replace path: /spec/sources/0/helm/valueFiles/1 - value: $values/infra/values/aws-dev/opencost-values.yaml + value: $values/infra/values/gke-dev/opencost-values.yaml # TODO: add patches for keycloak, grafana, secrets, enterprise-apps # when deploying to this cluster (these are deployment-specific, not cloud-specific) diff --git a/infra/overlays/aws-prod/kustomization.yaml b/infra/overlays/gke-prod/kustomization.yaml similarity index 67% rename from infra/overlays/aws-prod/kustomization.yaml rename to infra/overlays/gke-prod/kustomization.yaml index ce22faf..d040c85 100644 --- a/infra/overlays/aws-prod/kustomization.yaml +++ b/infra/overlays/gke-prod/kustomization.yaml @@ -4,32 +4,32 @@ resources: - ../../base patches: -# Traefik: swap upc-dev → aws-prod +# Traefik: swap upc-dev → gke-prod - target: kind: Application name: traefik patch: | - op: replace path: /spec/sources/0/helm/valueFiles/1 - value: $values/infra/values/aws-prod/traefik-values.yaml + value: $values/infra/values/gke-prod/traefik-values.yaml -# Gitea: swap upc-dev → aws-prod +# Gitea: swap upc-dev → gke-prod - target: kind: Application name: gitea patch: | - op: replace path: /spec/sources/0/helm/valueFiles/1 - value: $values/infra/values/aws-prod/gitea-values.yaml + value: $values/infra/values/gke-prod/gitea-values.yaml -# OpenCost: swap upc-dev → aws-prod +# OpenCost: swap upc-dev → gke-prod - target: kind: Application name: opencost patch: | - op: replace path: /spec/sources/0/helm/valueFiles/1 - value: $values/infra/values/aws-prod/opencost-values.yaml + value: $values/infra/values/gke-prod/opencost-values.yaml # TODO: add patches for keycloak, grafana, secrets, enterprise-apps # when deploying to this cluster (these are deployment-specific, not cloud-specific) diff --git a/infra/values/aws-dev/gitea-values.yaml b/infra/values/eks-dev/gitea-values.yaml similarity index 100% rename from infra/values/aws-dev/gitea-values.yaml rename to infra/values/eks-dev/gitea-values.yaml diff --git a/infra/values/aws-dev/opencost-values.yaml b/infra/values/eks-dev/opencost-values.yaml similarity index 100% rename from infra/values/aws-dev/opencost-values.yaml rename to infra/values/eks-dev/opencost-values.yaml diff --git a/infra/values/aws-dev/traefik-values.yaml b/infra/values/eks-dev/traefik-values.yaml similarity index 100% rename from infra/values/aws-dev/traefik-values.yaml rename to infra/values/eks-dev/traefik-values.yaml diff --git a/infra/values/aws-prod/gitea-values.yaml b/infra/values/eks-prod/gitea-values.yaml similarity index 100% rename from infra/values/aws-prod/gitea-values.yaml rename to infra/values/eks-prod/gitea-values.yaml diff --git a/infra/values/aws-prod/opencost-values.yaml b/infra/values/eks-prod/opencost-values.yaml similarity index 100% rename from infra/values/aws-prod/opencost-values.yaml rename to infra/values/eks-prod/opencost-values.yaml diff --git a/infra/values/aws-prod/traefik-values.yaml b/infra/values/eks-prod/traefik-values.yaml similarity index 100% rename from infra/values/aws-prod/traefik-values.yaml rename to infra/values/eks-prod/traefik-values.yaml diff --git a/infra/values/gcp-dev/gitea-values.yaml b/infra/values/gke-dev/gitea-values.yaml similarity index 100% rename from infra/values/gcp-dev/gitea-values.yaml rename to infra/values/gke-dev/gitea-values.yaml diff --git a/infra/values/gcp-dev/opencost-values.yaml b/infra/values/gke-dev/opencost-values.yaml similarity index 100% rename from infra/values/gcp-dev/opencost-values.yaml rename to infra/values/gke-dev/opencost-values.yaml diff --git a/infra/values/gcp-dev/traefik-values.yaml b/infra/values/gke-dev/traefik-values.yaml similarity index 100% rename from infra/values/gcp-dev/traefik-values.yaml rename to infra/values/gke-dev/traefik-values.yaml diff --git a/infra/values/gcp-prod/gitea-values.yaml b/infra/values/gke-prod/gitea-values.yaml similarity index 100% rename from infra/values/gcp-prod/gitea-values.yaml rename to infra/values/gke-prod/gitea-values.yaml diff --git a/infra/values/gcp-prod/opencost-values.yaml b/infra/values/gke-prod/opencost-values.yaml similarity index 100% rename from infra/values/gcp-prod/opencost-values.yaml rename to infra/values/gke-prod/opencost-values.yaml diff --git a/infra/values/gcp-prod/traefik-values.yaml b/infra/values/gke-prod/traefik-values.yaml similarity index 100% rename from infra/values/gcp-prod/traefik-values.yaml rename to infra/values/gke-prod/traefik-values.yaml diff --git a/scripts/gitea-backup-aws.sh b/scripts/gitea-backup-eks.sh old mode 100755 new mode 100644 similarity index 93% rename from scripts/gitea-backup-aws.sh rename to scripts/gitea-backup-eks.sh index ebf0894..c4c5c02 --- a/scripts/gitea-backup-aws.sh +++ b/scripts/gitea-backup-eks.sh @@ -8,9 +8,9 @@ set -euo pipefail # For AWS, S3_ENDPOINT is typically https://s3..amazonaws.com # # Usage: -# ./scripts/gitea-backup-aws.sh list # list all backups -# ./scripts/gitea-backup-aws.sh download # download a backup to current dir -# ./scripts/gitea-backup-aws.sh download latest # download the most recent backup +# ./scripts/gitea-backup-eks.sh list # list all backups +# ./scripts/gitea-backup-eks.sh download # download a backup to current dir +# ./scripts/gitea-backup-eks.sh download latest # download the most recent backup NAMESPACE="gitea" SECRET="gitea-backup-s3" diff --git a/scripts/gitea-backup-gcp.sh b/scripts/gitea-backup-gke.sh old mode 100755 new mode 100644 similarity index 94% rename from scripts/gitea-backup-gcp.sh rename to scripts/gitea-backup-gke.sh index 54fb7ef..bfed6b6 --- a/scripts/gitea-backup-gcp.sh +++ b/scripts/gitea-backup-gke.sh @@ -9,9 +9,9 @@ set -euo pipefail # (alternatively, use Workload Identity and omit the key) # # Usage: -# ./scripts/gitea-backup-gcp.sh list # list all backups -# ./scripts/gitea-backup-gcp.sh download # download a backup -# ./scripts/gitea-backup-gcp.sh download latest # download the most recent backup +# ./scripts/gitea-backup-gke.sh list # list all backups +# ./scripts/gitea-backup-gke.sh download # download a backup +# ./scripts/gitea-backup-gke.sh download latest # download the most recent backup NAMESPACE="gitea" SECRET="gitea-backup-gcs" From acc9bb1a856a5567f08e307df07d02545c24fbcc Mon Sep 17 00:00:00 2001 From: Danijel Simeunovic Date: Wed, 22 Apr 2026 21:53:44 +0200 Subject: [PATCH 8/9] sync --- infra/overlays/aks-dev/kustomization.yaml | 37 ++++++++++++++++++++-- infra/overlays/aks-prod/kustomization.yaml | 37 ++++++++++++++++++++-- infra/overlays/eks-dev/kustomization.yaml | 37 ++++++++++++++++++++-- infra/overlays/eks-prod/kustomization.yaml | 37 ++++++++++++++++++++-- infra/overlays/gke-dev/kustomization.yaml | 37 ++++++++++++++++++++-- infra/overlays/gke-prod/kustomization.yaml | 37 ++++++++++++++++++++-- 6 files changed, 210 insertions(+), 12 deletions(-) diff --git a/infra/overlays/aks-dev/kustomization.yaml b/infra/overlays/aks-dev/kustomization.yaml index c230763..185869f 100644 --- a/infra/overlays/aks-dev/kustomization.yaml +++ b/infra/overlays/aks-dev/kustomization.yaml @@ -13,6 +13,24 @@ patches: path: /spec/sources/0/helm/valueFiles/1 value: $values/infra/values/aks-dev/traefik-values.yaml +# Keycloak: swap upc-dev → aks-dev +- target: + kind: Application + name: keycloak + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/aks-dev/keycloak-values.yaml + +# Grafana: swap upc-dev → aks-dev +- target: + kind: Application + name: grafana + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/aks-dev/grafana-values.yaml + # Gitea: swap upc-dev → aks-dev - target: kind: Application @@ -31,5 +49,20 @@ patches: path: /spec/sources/0/helm/valueFiles/1 value: $values/infra/values/aks-dev/opencost-values.yaml -# TODO: add patches for keycloak, grafana, secrets, enterprise-apps -# when deploying to this cluster (these are deployment-specific, not cloud-specific) +# Secrets: change path to aks-dev +- target: + kind: Application + name: secrets + patch: | + - op: replace + path: /spec/source/path + value: secrets/aks-dev + +# Enterprise-apps: point to aks-dev overlay +- target: + kind: Application + name: enterprise-apps + patch: | + - op: replace + path: /spec/source/path + value: apps/overlays/aks-dev diff --git a/infra/overlays/aks-prod/kustomization.yaml b/infra/overlays/aks-prod/kustomization.yaml index 5cadfd5..73b0aaa 100644 --- a/infra/overlays/aks-prod/kustomization.yaml +++ b/infra/overlays/aks-prod/kustomization.yaml @@ -13,6 +13,24 @@ patches: path: /spec/sources/0/helm/valueFiles/1 value: $values/infra/values/aks-prod/traefik-values.yaml +# Keycloak: swap upc-dev → aks-prod +- target: + kind: Application + name: keycloak + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/aks-prod/keycloak-values.yaml + +# Grafana: swap upc-dev → aks-prod +- target: + kind: Application + name: grafana + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/aks-prod/grafana-values.yaml + # Gitea: swap upc-dev → aks-prod - target: kind: Application @@ -31,5 +49,20 @@ patches: path: /spec/sources/0/helm/valueFiles/1 value: $values/infra/values/aks-prod/opencost-values.yaml -# TODO: add patches for keycloak, grafana, secrets, enterprise-apps -# when deploying to this cluster (these are deployment-specific, not cloud-specific) +# Secrets: change path to aks-prod +- target: + kind: Application + name: secrets + patch: | + - op: replace + path: /spec/source/path + value: secrets/aks-prod + +# Enterprise-apps: point to aks-prod overlay +- target: + kind: Application + name: enterprise-apps + patch: | + - op: replace + path: /spec/source/path + value: apps/overlays/aks-prod diff --git a/infra/overlays/eks-dev/kustomization.yaml b/infra/overlays/eks-dev/kustomization.yaml index c8690bf..16e542a 100644 --- a/infra/overlays/eks-dev/kustomization.yaml +++ b/infra/overlays/eks-dev/kustomization.yaml @@ -13,6 +13,24 @@ patches: path: /spec/sources/0/helm/valueFiles/1 value: $values/infra/values/eks-dev/traefik-values.yaml +# Keycloak: swap upc-dev → eks-dev +- target: + kind: Application + name: keycloak + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/eks-dev/keycloak-values.yaml + +# Grafana: swap upc-dev → eks-dev +- target: + kind: Application + name: grafana + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/eks-dev/grafana-values.yaml + # Gitea: swap upc-dev → eks-dev - target: kind: Application @@ -31,5 +49,20 @@ patches: path: /spec/sources/0/helm/valueFiles/1 value: $values/infra/values/eks-dev/opencost-values.yaml -# TODO: add patches for keycloak, grafana, secrets, enterprise-apps -# when deploying to this cluster (these are deployment-specific, not cloud-specific) +# Secrets: change path to eks-dev +- target: + kind: Application + name: secrets + patch: | + - op: replace + path: /spec/source/path + value: secrets/eks-dev + +# Enterprise-apps: point to eks-dev overlay +- target: + kind: Application + name: enterprise-apps + patch: | + - op: replace + path: /spec/source/path + value: apps/overlays/eks-dev diff --git a/infra/overlays/eks-prod/kustomization.yaml b/infra/overlays/eks-prod/kustomization.yaml index 7ab683d..46be9a9 100644 --- a/infra/overlays/eks-prod/kustomization.yaml +++ b/infra/overlays/eks-prod/kustomization.yaml @@ -13,6 +13,24 @@ patches: path: /spec/sources/0/helm/valueFiles/1 value: $values/infra/values/eks-prod/traefik-values.yaml +# Keycloak: swap upc-dev → eks-prod +- target: + kind: Application + name: keycloak + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/eks-prod/keycloak-values.yaml + +# Grafana: swap upc-dev → eks-prod +- target: + kind: Application + name: grafana + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/eks-prod/grafana-values.yaml + # Gitea: swap upc-dev → eks-prod - target: kind: Application @@ -31,5 +49,20 @@ patches: path: /spec/sources/0/helm/valueFiles/1 value: $values/infra/values/eks-prod/opencost-values.yaml -# TODO: add patches for keycloak, grafana, secrets, enterprise-apps -# when deploying to this cluster (these are deployment-specific, not cloud-specific) +# Secrets: change path to eks-prod +- target: + kind: Application + name: secrets + patch: | + - op: replace + path: /spec/source/path + value: secrets/eks-prod + +# Enterprise-apps: point to eks-prod overlay +- target: + kind: Application + name: enterprise-apps + patch: | + - op: replace + path: /spec/source/path + value: apps/overlays/eks-prod diff --git a/infra/overlays/gke-dev/kustomization.yaml b/infra/overlays/gke-dev/kustomization.yaml index 147bb76..4d3da3e 100644 --- a/infra/overlays/gke-dev/kustomization.yaml +++ b/infra/overlays/gke-dev/kustomization.yaml @@ -13,6 +13,24 @@ patches: path: /spec/sources/0/helm/valueFiles/1 value: $values/infra/values/gke-dev/traefik-values.yaml +# Keycloak: swap upc-dev → gke-dev +- target: + kind: Application + name: keycloak + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/gke-dev/keycloak-values.yaml + +# Grafana: swap upc-dev → gke-dev +- target: + kind: Application + name: grafana + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/gke-dev/grafana-values.yaml + # Gitea: swap upc-dev → gke-dev - target: kind: Application @@ -31,5 +49,20 @@ patches: path: /spec/sources/0/helm/valueFiles/1 value: $values/infra/values/gke-dev/opencost-values.yaml -# TODO: add patches for keycloak, grafana, secrets, enterprise-apps -# when deploying to this cluster (these are deployment-specific, not cloud-specific) +# Secrets: change path to gke-dev +- target: + kind: Application + name: secrets + patch: | + - op: replace + path: /spec/source/path + value: secrets/gke-dev + +# Enterprise-apps: point to gke-dev overlay +- target: + kind: Application + name: enterprise-apps + patch: | + - op: replace + path: /spec/source/path + value: apps/overlays/gke-dev diff --git a/infra/overlays/gke-prod/kustomization.yaml b/infra/overlays/gke-prod/kustomization.yaml index d040c85..0f4a583 100644 --- a/infra/overlays/gke-prod/kustomization.yaml +++ b/infra/overlays/gke-prod/kustomization.yaml @@ -13,6 +13,24 @@ patches: path: /spec/sources/0/helm/valueFiles/1 value: $values/infra/values/gke-prod/traefik-values.yaml +# Keycloak: swap upc-dev → gke-prod +- target: + kind: Application + name: keycloak + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/gke-prod/keycloak-values.yaml + +# Grafana: swap upc-dev → gke-prod +- target: + kind: Application + name: grafana + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/gke-prod/grafana-values.yaml + # Gitea: swap upc-dev → gke-prod - target: kind: Application @@ -31,5 +49,20 @@ patches: path: /spec/sources/0/helm/valueFiles/1 value: $values/infra/values/gke-prod/opencost-values.yaml -# TODO: add patches for keycloak, grafana, secrets, enterprise-apps -# when deploying to this cluster (these are deployment-specific, not cloud-specific) +# Secrets: change path to gke-prod +- target: + kind: Application + name: secrets + patch: | + - op: replace + path: /spec/source/path + value: secrets/gke-prod + +# Enterprise-apps: point to gke-prod overlay +- target: + kind: Application + name: enterprise-apps + patch: | + - op: replace + path: /spec/source/path + value: apps/overlays/gke-prod From f1dd61cecea913f412892162b3aa664a831012f9 Mon Sep 17 00:00:00 2001 From: Danijel Simeunovic Date: Wed, 22 Apr 2026 21:56:43 +0200 Subject: [PATCH 9/9] sync --- infra/values/aks-dev/gitea-values.yaml | 2 +- infra/values/aks-dev/grafana-values.yaml | 4 ++++ infra/values/aks-dev/keycloak-values.yaml | 3 +++ infra/values/aks-dev/opencost-values.yaml | 11 ++++------- infra/values/aks-dev/traefik-values.yaml | 13 ++++--------- infra/values/aks-prod/gitea-values.yaml | 2 +- infra/values/aks-prod/grafana-values.yaml | 4 ++++ infra/values/aks-prod/keycloak-values.yaml | 3 +++ infra/values/aks-prod/opencost-values.yaml | 11 ++++------- infra/values/aks-prod/traefik-values.yaml | 14 +++++--------- infra/values/eks-dev/gitea-values.yaml | 2 +- infra/values/eks-dev/grafana-values.yaml | 4 ++++ infra/values/eks-dev/keycloak-values.yaml | 3 +++ infra/values/eks-dev/opencost-values.yaml | 8 +++----- infra/values/eks-dev/traefik-values.yaml | 9 ++++----- infra/values/eks-prod/gitea-values.yaml | 2 +- infra/values/eks-prod/grafana-values.yaml | 4 ++++ infra/values/eks-prod/keycloak-values.yaml | 3 +++ infra/values/eks-prod/opencost-values.yaml | 8 +++----- infra/values/eks-prod/traefik-values.yaml | 10 +++++----- infra/values/gke-dev/gitea-values.yaml | 2 +- infra/values/gke-dev/grafana-values.yaml | 4 ++++ infra/values/gke-dev/keycloak-values.yaml | 3 +++ infra/values/gke-dev/opencost-values.yaml | 13 +++++++------ infra/values/gke-dev/traefik-values.yaml | 13 +++++-------- infra/values/gke-prod/gitea-values.yaml | 2 +- infra/values/gke-prod/grafana-values.yaml | 4 ++++ infra/values/gke-prod/keycloak-values.yaml | 3 +++ infra/values/gke-prod/opencost-values.yaml | 13 +++++++------ infra/values/gke-prod/traefik-values.yaml | 13 +++++-------- 30 files changed, 104 insertions(+), 86 deletions(-) create mode 100644 infra/values/aks-dev/grafana-values.yaml create mode 100644 infra/values/aks-dev/keycloak-values.yaml create mode 100644 infra/values/aks-prod/grafana-values.yaml create mode 100644 infra/values/aks-prod/keycloak-values.yaml create mode 100644 infra/values/eks-dev/grafana-values.yaml create mode 100644 infra/values/eks-dev/keycloak-values.yaml create mode 100644 infra/values/eks-prod/grafana-values.yaml create mode 100644 infra/values/eks-prod/keycloak-values.yaml create mode 100644 infra/values/gke-dev/grafana-values.yaml create mode 100644 infra/values/gke-dev/keycloak-values.yaml create mode 100644 infra/values/gke-prod/grafana-values.yaml create mode 100644 infra/values/gke-prod/keycloak-values.yaml diff --git a/infra/values/aks-dev/gitea-values.yaml b/infra/values/aks-dev/gitea-values.yaml index 5bb20ff..94e9760 100644 --- a/infra/values/aks-dev/gitea-values.yaml +++ b/infra/values/aks-dev/gitea-values.yaml @@ -1,4 +1,4 @@ -# Azure Managed Disk (Premium SSD via CSI driver) +# AKS-specific: Azure managed disk storage class persistence: storageClass: managed-csi-premium postgresql: diff --git a/infra/values/aks-dev/grafana-values.yaml b/infra/values/aks-dev/grafana-values.yaml new file mode 100644 index 0000000..3b10135 --- /dev/null +++ b/infra/values/aks-dev/grafana-values.yaml @@ -0,0 +1,4 @@ +# AKS-specific: Grafana hostname +ingress: + hosts: + - grafana.forteapps.net diff --git a/infra/values/aks-dev/keycloak-values.yaml b/infra/values/aks-dev/keycloak-values.yaml new file mode 100644 index 0000000..f66b945 --- /dev/null +++ b/infra/values/aks-dev/keycloak-values.yaml @@ -0,0 +1,3 @@ +# AKS-specific: Keycloak hostname +ingress: + hostname: id.forteapps.net diff --git a/infra/values/aks-dev/opencost-values.yaml b/infra/values/aks-dev/opencost-values.yaml index 98b30cd..64dcfa1 100644 --- a/infra/values/aks-dev/opencost-values.yaml +++ b/infra/values/aks-dev/opencost-values.yaml @@ -1,11 +1,8 @@ -# Azure native pricing via Billing API +# AKS-specific: Azure pricing via Cloud Billing API opencost: exporter: + cloudProviderApiKey: "" customPricing: - enabled: true - provider: azure + enabled: false azure: - subscriptionID: "" # <- populate - clientID: "" - clientSecret: "" - tenantID: "" + secretName: opencost-azure-billing diff --git a/infra/values/aks-dev/traefik-values.yaml b/infra/values/aks-dev/traefik-values.yaml index 7efa198..fd5c882 100644 --- a/infra/values/aks-dev/traefik-values.yaml +++ b/infra/values/aks-dev/traefik-values.yaml @@ -1,16 +1,11 @@ -# Azure AKS — Standard Load Balancer -# Note: Azure Standard LB does not support Proxy Protocol. -# Use externalTrafficPolicy: Local on the Traefik service to preserve -# client IPs, or deploy behind Azure Application Gateway. +# AKS-specific: Azure Load Balancer for Traefik service: annotations: - service.beta.kubernetes.io/azure-load-balancer-health-probe-request-path: "/ping" - spec: - externalTrafficPolicy: Local + service.beta.kubernetes.io/azure-load-balancer-health-probe-request-path: /ping ports: web: forwardedHeaders: - trustedIPs: "10.0.0.0/8,168.63.129.16/32" # <- VNet CIDR + Azure health probe + trustedIPs: "10.0.0.0/8" websecure: forwardedHeaders: - trustedIPs: "10.0.0.0/8,168.63.129.16/32" + trustedIPs: "10.0.0.0/8" diff --git a/infra/values/aks-prod/gitea-values.yaml b/infra/values/aks-prod/gitea-values.yaml index 5bb20ff..d035b5d 100644 --- a/infra/values/aks-prod/gitea-values.yaml +++ b/infra/values/aks-prod/gitea-values.yaml @@ -1,4 +1,4 @@ -# Azure Managed Disk (Premium SSD via CSI driver) +# AKS-specific: Azure managed disk storage class (prod) persistence: storageClass: managed-csi-premium postgresql: diff --git a/infra/values/aks-prod/grafana-values.yaml b/infra/values/aks-prod/grafana-values.yaml new file mode 100644 index 0000000..b1f7504 --- /dev/null +++ b/infra/values/aks-prod/grafana-values.yaml @@ -0,0 +1,4 @@ +# AKS-specific: Grafana hostname (prod) +ingress: + hosts: + - grafana.fortedigital.com diff --git a/infra/values/aks-prod/keycloak-values.yaml b/infra/values/aks-prod/keycloak-values.yaml new file mode 100644 index 0000000..97096e4 --- /dev/null +++ b/infra/values/aks-prod/keycloak-values.yaml @@ -0,0 +1,3 @@ +# AKS-specific: Keycloak hostname (prod) +ingress: + hostname: id.fortedigital.com diff --git a/infra/values/aks-prod/opencost-values.yaml b/infra/values/aks-prod/opencost-values.yaml index 98b30cd..d465129 100644 --- a/infra/values/aks-prod/opencost-values.yaml +++ b/infra/values/aks-prod/opencost-values.yaml @@ -1,11 +1,8 @@ -# Azure native pricing via Billing API +# AKS-specific: Azure pricing via Cloud Billing API (prod) opencost: exporter: + cloudProviderApiKey: "" customPricing: - enabled: true - provider: azure + enabled: false azure: - subscriptionID: "" # <- populate - clientID: "" - clientSecret: "" - tenantID: "" + secretName: opencost-azure-billing diff --git a/infra/values/aks-prod/traefik-values.yaml b/infra/values/aks-prod/traefik-values.yaml index 7efa198..469f276 100644 --- a/infra/values/aks-prod/traefik-values.yaml +++ b/infra/values/aks-prod/traefik-values.yaml @@ -1,16 +1,12 @@ -# Azure AKS — Standard Load Balancer -# Note: Azure Standard LB does not support Proxy Protocol. -# Use externalTrafficPolicy: Local on the Traefik service to preserve -# client IPs, or deploy behind Azure Application Gateway. +# AKS-specific: Azure Load Balancer for Traefik (prod) service: annotations: - service.beta.kubernetes.io/azure-load-balancer-health-probe-request-path: "/ping" - spec: - externalTrafficPolicy: Local + service.beta.kubernetes.io/azure-load-balancer-health-probe-request-path: /ping + service.beta.kubernetes.io/azure-load-balancer-internal: "false" ports: web: forwardedHeaders: - trustedIPs: "10.0.0.0/8,168.63.129.16/32" # <- VNet CIDR + Azure health probe + trustedIPs: "10.0.0.0/8" websecure: forwardedHeaders: - trustedIPs: "10.0.0.0/8,168.63.129.16/32" + trustedIPs: "10.0.0.0/8" diff --git a/infra/values/eks-dev/gitea-values.yaml b/infra/values/eks-dev/gitea-values.yaml index 597af4f..c55964f 100644 --- a/infra/values/eks-dev/gitea-values.yaml +++ b/infra/values/eks-dev/gitea-values.yaml @@ -1,4 +1,4 @@ -# AWS EBS gp3 storage class (requires EBS CSI driver) +# EKS-specific: gp3 storage class persistence: storageClass: gp3 postgresql: diff --git a/infra/values/eks-dev/grafana-values.yaml b/infra/values/eks-dev/grafana-values.yaml new file mode 100644 index 0000000..e5d932e --- /dev/null +++ b/infra/values/eks-dev/grafana-values.yaml @@ -0,0 +1,4 @@ +# EKS-specific: Grafana hostname +ingress: + hosts: + - grafana.forteapps.net diff --git a/infra/values/eks-dev/keycloak-values.yaml b/infra/values/eks-dev/keycloak-values.yaml new file mode 100644 index 0000000..ee027eb --- /dev/null +++ b/infra/values/eks-dev/keycloak-values.yaml @@ -0,0 +1,3 @@ +# EKS-specific: Keycloak hostname +ingress: + hostname: id.forteapps.net diff --git a/infra/values/eks-dev/opencost-values.yaml b/infra/values/eks-dev/opencost-values.yaml index 93ff67a..efd110a 100644 --- a/infra/values/eks-dev/opencost-values.yaml +++ b/infra/values/eks-dev/opencost-values.yaml @@ -1,12 +1,10 @@ -# AWS native pricing via Cost and Usage Reports +# EKS-specific: AWS pricing via Cost and Usage Report opencost: exporter: + cloudProviderApiKey: "" customPricing: - enabled: true - provider: aws + enabled: false aws: - service_key_name: "" # <- populate or use IRSA - service_key_secret: "" spot_data_region: "" spot_data_bucket: "" spot_data_prefix: "" diff --git a/infra/values/eks-dev/traefik-values.yaml b/infra/values/eks-dev/traefik-values.yaml index 34306f7..1390d17 100644 --- a/infra/values/eks-dev/traefik-values.yaml +++ b/infra/values/eks-dev/traefik-values.yaml @@ -1,14 +1,13 @@ -# AWS EKS — NLB with Proxy Protocol v2 for real client IPs +# EKS-specific: AWS NLB for Traefik service: annotations: - service.beta.kubernetes.io/aws-load-balancer-type: "external" - service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip" - service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing" + service.beta.kubernetes.io/aws-load-balancer-type: nlb + service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*" ports: web: proxyProtocol: - trustedIPs: "10.0.0.0/8" # <- adjust to your VPC CIDR + trustedIPs: "10.0.0.0/8" forwardedHeaders: trustedIPs: "10.0.0.0/8" websecure: diff --git a/infra/values/eks-prod/gitea-values.yaml b/infra/values/eks-prod/gitea-values.yaml index 597af4f..7aae415 100644 --- a/infra/values/eks-prod/gitea-values.yaml +++ b/infra/values/eks-prod/gitea-values.yaml @@ -1,4 +1,4 @@ -# AWS EBS gp3 storage class (requires EBS CSI driver) +# EKS-specific: gp3 storage class (prod) persistence: storageClass: gp3 postgresql: diff --git a/infra/values/eks-prod/grafana-values.yaml b/infra/values/eks-prod/grafana-values.yaml new file mode 100644 index 0000000..2034392 --- /dev/null +++ b/infra/values/eks-prod/grafana-values.yaml @@ -0,0 +1,4 @@ +# EKS-specific: Grafana hostname (prod) +ingress: + hosts: + - grafana.fortedigital.com diff --git a/infra/values/eks-prod/keycloak-values.yaml b/infra/values/eks-prod/keycloak-values.yaml new file mode 100644 index 0000000..9797896 --- /dev/null +++ b/infra/values/eks-prod/keycloak-values.yaml @@ -0,0 +1,3 @@ +# EKS-specific: Keycloak hostname (prod) +ingress: + hostname: id.fortedigital.com diff --git a/infra/values/eks-prod/opencost-values.yaml b/infra/values/eks-prod/opencost-values.yaml index 93ff67a..ac86a76 100644 --- a/infra/values/eks-prod/opencost-values.yaml +++ b/infra/values/eks-prod/opencost-values.yaml @@ -1,12 +1,10 @@ -# AWS native pricing via Cost and Usage Reports +# EKS-specific: AWS pricing via Cost and Usage Report (prod) opencost: exporter: + cloudProviderApiKey: "" customPricing: - enabled: true - provider: aws + enabled: false aws: - service_key_name: "" # <- populate or use IRSA - service_key_secret: "" spot_data_region: "" spot_data_bucket: "" spot_data_prefix: "" diff --git a/infra/values/eks-prod/traefik-values.yaml b/infra/values/eks-prod/traefik-values.yaml index 34306f7..fd64496 100644 --- a/infra/values/eks-prod/traefik-values.yaml +++ b/infra/values/eks-prod/traefik-values.yaml @@ -1,14 +1,14 @@ -# AWS EKS — NLB with Proxy Protocol v2 for real client IPs +# EKS-specific: AWS NLB for Traefik (prod) service: annotations: - service.beta.kubernetes.io/aws-load-balancer-type: "external" - service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip" - service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing" + service.beta.kubernetes.io/aws-load-balancer-type: nlb + service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*" + service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true" ports: web: proxyProtocol: - trustedIPs: "10.0.0.0/8" # <- adjust to your VPC CIDR + trustedIPs: "10.0.0.0/8" forwardedHeaders: trustedIPs: "10.0.0.0/8" websecure: diff --git a/infra/values/gke-dev/gitea-values.yaml b/infra/values/gke-dev/gitea-values.yaml index b825aee..04ec9aa 100644 --- a/infra/values/gke-dev/gitea-values.yaml +++ b/infra/values/gke-dev/gitea-values.yaml @@ -1,4 +1,4 @@ -# GCP Persistent Disk (SSD via CSI driver) +# GKE-specific: SSD persistent disk storage class persistence: storageClass: premium-rwo postgresql: diff --git a/infra/values/gke-dev/grafana-values.yaml b/infra/values/gke-dev/grafana-values.yaml new file mode 100644 index 0000000..db36770 --- /dev/null +++ b/infra/values/gke-dev/grafana-values.yaml @@ -0,0 +1,4 @@ +# GKE-specific: Grafana hostname +ingress: + hosts: + - grafana.forteapps.net diff --git a/infra/values/gke-dev/keycloak-values.yaml b/infra/values/gke-dev/keycloak-values.yaml new file mode 100644 index 0000000..4c67591 --- /dev/null +++ b/infra/values/gke-dev/keycloak-values.yaml @@ -0,0 +1,3 @@ +# GKE-specific: Keycloak hostname +ingress: + hostname: id.forteapps.net diff --git a/infra/values/gke-dev/opencost-values.yaml b/infra/values/gke-dev/opencost-values.yaml index f3ea481..6534718 100644 --- a/infra/values/gke-dev/opencost-values.yaml +++ b/infra/values/gke-dev/opencost-values.yaml @@ -1,9 +1,10 @@ -# GCP native pricing via Cloud Billing API +# GKE-specific: GCP pricing via BigQuery billing export opencost: exporter: + cloudProviderApiKey: "" customPricing: - enabled: true - provider: gcp - gcp: - projectID: "" # <- populate with your GCP project ID - key: "" # <- or use Workload Identity + enabled: false + google: + key: "" + project_id: "" + billing_account: "" diff --git a/infra/values/gke-dev/traefik-values.yaml b/infra/values/gke-dev/traefik-values.yaml index 55351c0..96a78ab 100644 --- a/infra/values/gke-dev/traefik-values.yaml +++ b/infra/values/gke-dev/traefik-values.yaml @@ -1,15 +1,12 @@ -# GCP GKE — External passthrough Network Load Balancer +# GKE-specific: Google Cloud Load Balancer for Traefik service: annotations: - cloud.google.com/l4-rbs: "enabled" + cloud.google.com/neg: '{"ingress":true}' + networking.gke.io/load-balancer-type: External ports: web: - proxyProtocol: - trustedIPs: "10.0.0.0/8,35.191.0.0/16,130.211.0.0/22" # <- subnet CIDR + GCP health checks forwardedHeaders: - trustedIPs: "10.0.0.0/8,35.191.0.0/16,130.211.0.0/22" + trustedIPs: "10.0.0.0/8" websecure: - proxyProtocol: - trustedIPs: "10.0.0.0/8,35.191.0.0/16,130.211.0.0/22" forwardedHeaders: - trustedIPs: "10.0.0.0/8,35.191.0.0/16,130.211.0.0/22" + trustedIPs: "10.0.0.0/8" diff --git a/infra/values/gke-prod/gitea-values.yaml b/infra/values/gke-prod/gitea-values.yaml index b825aee..5df877a 100644 --- a/infra/values/gke-prod/gitea-values.yaml +++ b/infra/values/gke-prod/gitea-values.yaml @@ -1,4 +1,4 @@ -# GCP Persistent Disk (SSD via CSI driver) +# GKE-specific: SSD persistent disk storage class (prod) persistence: storageClass: premium-rwo postgresql: diff --git a/infra/values/gke-prod/grafana-values.yaml b/infra/values/gke-prod/grafana-values.yaml new file mode 100644 index 0000000..e0b0d37 --- /dev/null +++ b/infra/values/gke-prod/grafana-values.yaml @@ -0,0 +1,4 @@ +# GKE-specific: Grafana hostname (prod) +ingress: + hosts: + - grafana.fortedigital.com diff --git a/infra/values/gke-prod/keycloak-values.yaml b/infra/values/gke-prod/keycloak-values.yaml new file mode 100644 index 0000000..76ab384 --- /dev/null +++ b/infra/values/gke-prod/keycloak-values.yaml @@ -0,0 +1,3 @@ +# GKE-specific: Keycloak hostname (prod) +ingress: + hostname: id.fortedigital.com diff --git a/infra/values/gke-prod/opencost-values.yaml b/infra/values/gke-prod/opencost-values.yaml index f3ea481..404f49b 100644 --- a/infra/values/gke-prod/opencost-values.yaml +++ b/infra/values/gke-prod/opencost-values.yaml @@ -1,9 +1,10 @@ -# GCP native pricing via Cloud Billing API +# GKE-specific: GCP pricing via BigQuery billing export (prod) opencost: exporter: + cloudProviderApiKey: "" customPricing: - enabled: true - provider: gcp - gcp: - projectID: "" # <- populate with your GCP project ID - key: "" # <- or use Workload Identity + enabled: false + google: + key: "" + project_id: "" + billing_account: "" diff --git a/infra/values/gke-prod/traefik-values.yaml b/infra/values/gke-prod/traefik-values.yaml index 55351c0..7d70c40 100644 --- a/infra/values/gke-prod/traefik-values.yaml +++ b/infra/values/gke-prod/traefik-values.yaml @@ -1,15 +1,12 @@ -# GCP GKE — External passthrough Network Load Balancer +# GKE-specific: Google Cloud Load Balancer for Traefik (prod) service: annotations: - cloud.google.com/l4-rbs: "enabled" + cloud.google.com/neg: '{"ingress":true}' + networking.gke.io/load-balancer-type: External ports: web: - proxyProtocol: - trustedIPs: "10.0.0.0/8,35.191.0.0/16,130.211.0.0/22" # <- subnet CIDR + GCP health checks forwardedHeaders: - trustedIPs: "10.0.0.0/8,35.191.0.0/16,130.211.0.0/22" + trustedIPs: "10.0.0.0/8" websecure: - proxyProtocol: - trustedIPs: "10.0.0.0/8,35.191.0.0/16,130.211.0.0/22" forwardedHeaders: - trustedIPs: "10.0.0.0/8,35.191.0.0/16,130.211.0.0/22" + trustedIPs: "10.0.0.0/8"