diff --git a/_app-of-apps-aks-dev.yaml b/_app-of-apps-aks-dev.yaml new file mode 100644 index 0000000..9547bfe --- /dev/null +++ b/_app-of-apps-aks-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: ssh://git@git.forteapps.net:2222/Forte/launchpad.git + targetRevision: HEAD + path: infra/overlays/aks-dev + destination: + server: https://kubernetes.default.svc + namespace: default + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/_app-of-apps-aks-prod.yaml b/_app-of-apps-aks-prod.yaml new file mode 100644 index 0000000..6d945ac --- /dev/null +++ b/_app-of-apps-aks-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/aks-prod + destination: + server: https://kubernetes.default.svc + namespace: default + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/_app-of-apps-eks-dev.yaml b/_app-of-apps-eks-dev.yaml new file mode 100644 index 0000000..f40e164 --- /dev/null +++ b/_app-of-apps-eks-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: ssh://git@git.forteapps.net:2222/Forte/launchpad.git + targetRevision: HEAD + path: infra/overlays/eks-dev + destination: + server: https://kubernetes.default.svc + namespace: default + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/_app-of-apps-eks-prod.yaml b/_app-of-apps-eks-prod.yaml new file mode 100644 index 0000000..1e51d04 --- /dev/null +++ b/_app-of-apps-eks-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/eks-prod + destination: + server: https://kubernetes.default.svc + namespace: default + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/_app-of-apps-gke-dev.yaml b/_app-of-apps-gke-dev.yaml new file mode 100644 index 0000000..faf753c --- /dev/null +++ b/_app-of-apps-gke-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: ssh://git@git.forteapps.net:2222/Forte/launchpad.git + targetRevision: HEAD + path: infra/overlays/gke-dev + destination: + server: https://kubernetes.default.svc + namespace: default + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/_app-of-apps-gke-prod.yaml b/_app-of-apps-gke-prod.yaml new file mode 100644 index 0000000..8c6fc27 --- /dev/null +++ b/_app-of-apps-gke-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/gke-prod + destination: + server: https://kubernetes.default.svc + namespace: default + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/bootstrap.sh b/bootstrap.sh index 2265d6b..6c1170a 100644 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -2,7 +2,7 @@ # in case of $'\r': command not found error, run command below first # sed -i 's/\r$//' ./bootstrap.sh -CLUSTER="${1:?Usage: ./bootstrap.sh (upc-dev|upc-prod)}" +CLUSTER="${1:?Usage: ./bootstrap.sh (upc-dev|upc-prod|aks-dev|aks-prod|eks-dev|eks-prod|gke-dev|gke-prod)}" echo "running $0 for cluster: ${CLUSTER}..." diff --git a/clusters/aks-dev.yaml b/clusters/aks-dev.yaml new file mode 100644 index 0000000..db86d2b --- /dev/null +++ b/clusters/aks-dev.yaml @@ -0,0 +1,10 @@ +clusterName: dev-fd-aks +domain: forteapps.net +argocdDomain: argocd.127.0.0.1.nip.io +grafanaDomain: grafana.forteapps.net +keycloakDomain: id.forteapps.net +dotaiDomain: kubemcp.forteapps.net +dotaiUiDomain: kubemcpui.forteapps.net +letsencryptEmail: danijels@gmail.com +trustedIPs: "10.0.0.0/8" +cloudProvider: azure diff --git a/clusters/aks-prod.yaml b/clusters/aks-prod.yaml new file mode 100644 index 0000000..d230b08 --- /dev/null +++ b/clusters/aks-prod.yaml @@ -0,0 +1,10 @@ +clusterName: prod-fd-aks +domain: fortedigital.com +argocdDomain: argocd.127.0.0.1.nip.io +grafanaDomain: grafana.fortedigital.com +keycloakDomain: id.fortedigital.com +dotaiDomain: kubemcp.fortedigital.com +dotaiUiDomain: kubemcpui.fortedigital.com +letsencryptEmail: danijel.simeunovic@fortedigital.com +trustedIPs: "10.0.0.0/8" +cloudProvider: azure diff --git a/clusters/eks-dev.yaml b/clusters/eks-dev.yaml new file mode 100644 index 0000000..e822b84 --- /dev/null +++ b/clusters/eks-dev.yaml @@ -0,0 +1,10 @@ +clusterName: dev-fd-eks +domain: forteapps.net +argocdDomain: argocd.127.0.0.1.nip.io +grafanaDomain: grafana.forteapps.net +keycloakDomain: id.forteapps.net +dotaiDomain: kubemcp.forteapps.net +dotaiUiDomain: kubemcpui.forteapps.net +letsencryptEmail: danijels@gmail.com +trustedIPs: "10.0.0.0/8" +cloudProvider: aws diff --git a/clusters/eks-prod.yaml b/clusters/eks-prod.yaml new file mode 100644 index 0000000..dd5cc83 --- /dev/null +++ b/clusters/eks-prod.yaml @@ -0,0 +1,10 @@ +clusterName: prod-fd-eks +domain: fortedigital.com +argocdDomain: argocd.127.0.0.1.nip.io +grafanaDomain: grafana.fortedigital.com +keycloakDomain: id.fortedigital.com +dotaiDomain: kubemcp.fortedigital.com +dotaiUiDomain: kubemcpui.fortedigital.com +letsencryptEmail: danijel.simeunovic@fortedigital.com +trustedIPs: "10.0.0.0/8" +cloudProvider: aws diff --git a/clusters/gke-dev.yaml b/clusters/gke-dev.yaml new file mode 100644 index 0000000..fd5afd5 --- /dev/null +++ b/clusters/gke-dev.yaml @@ -0,0 +1,10 @@ +clusterName: dev-fd-gke +domain: forteapps.net +argocdDomain: argocd.127.0.0.1.nip.io +grafanaDomain: grafana.forteapps.net +keycloakDomain: id.forteapps.net +dotaiDomain: kubemcp.forteapps.net +dotaiUiDomain: kubemcpui.forteapps.net +letsencryptEmail: danijels@gmail.com +trustedIPs: "10.0.0.0/8" +cloudProvider: gcp diff --git a/clusters/gke-prod.yaml b/clusters/gke-prod.yaml new file mode 100644 index 0000000..9c6751d --- /dev/null +++ b/clusters/gke-prod.yaml @@ -0,0 +1,10 @@ +clusterName: prod-fd-gke +domain: fortedigital.com +argocdDomain: argocd.127.0.0.1.nip.io +grafanaDomain: grafana.fortedigital.com +keycloakDomain: id.fortedigital.com +dotaiDomain: kubemcp.fortedigital.com +dotaiUiDomain: kubemcpui.fortedigital.com +letsencryptEmail: danijel.simeunovic@fortedigital.com +trustedIPs: "10.0.0.0/8" +cloudProvider: gcp diff --git a/docs/REFERENCE.md b/docs/REFERENCE.md index 4bab669..74645c2 100644 --- a/docs/REFERENCE.md +++ b/docs/REFERENCE.md @@ -20,9 +20,9 @@ | Component | Value | |-----------|-------| -| **Provider** | UpCloud Managed Kubernetes | -| **Environment** | Production (internal use) | -| **Cluster Count** | Multi-cluster (upc-dev, upc-prod) | +| **Provider** | Multi-cloud (UpCloud, AKS, EKS, GKE) | +| **Environment** | Dev + Production per cloud | +| **Cluster Count** | Multi-cluster (upc-dev/prod, aks-dev/prod, eks-dev/prod, gke-dev/prod) | | **GitOps Tool** | ArgoCD | | **Ingress Controller** | Traefik v2 | | **Certificate Management** | Cert-Manager + Let's Encrypt | @@ -1653,7 +1653,18 @@ POST /loki/api/v1/push ### Overview -Cloud-specific configuration (StorageClass, LoadBalancer annotations, pricing models, etc.) lives in per-cloud overlay value files, **not** in `base/`. This means adding a new cloud provider (AKS, EKS, GKE) only requires a new overlay directory — no base changes. +Cloud-specific configuration (StorageClass, LoadBalancer annotations, pricing models, etc.) lives in per-cloud overlay value files, **not** in `base/`. Adding a new cloud provider only requires a new overlay directory — no base changes. + +### Supported Clouds + +| Cloud | Dev overlay | Prod overlay | StorageClass | LB type | +|-------|-----------|-------------|-------------|---------| +| **UpCloud** | `upc-dev` | `upc-prod` | `upcloud-block-storage-maxiops` | UpCloud LB (proxy protocol v2) | +| **Azure AKS** | `aks-dev` | `aks-prod` | `managed-csi-premium` | Azure LB | +| **AWS EKS** | `eks-dev` | `eks-prod` | `gp3` | AWS NLB (proxy protocol) | +| **GCP GKE** | `gke-dev` | `gke-prod` | `premium-rwo` | GCP NEG | + +Bootstrap any cluster with: `./bootstrap.sh ` (e.g., `./bootstrap.sh aks-dev`) ### How It Works @@ -1703,22 +1714,19 @@ The `gitea-backup` CronJob uses a generic `s3` alias for `minio/mc`. The actual ### Adding a New Cloud Provider -To add support for a new cloud (e.g., `aks-dev`): +To add support for a new cloud (e.g., `oci-dev` for Oracle Cloud): -1. **Create overlay value directory**: `infra/values/aks-dev/` -2. **Add cloud-specific value files** for each component that needs one: +1. **Cluster config**: `clusters/oci-dev.yaml` — clusterName, domain, trustedIPs, cloudProvider +2. **Overlay value files** in `infra/values/oci-dev/`: - `traefik-values.yaml` — LB annotations, proxy protocol config - - `keycloak-values.yaml` — hostname/TLS if different - - `grafana-values.yaml` — hostname/datasources if different + - `keycloak-values.yaml` — hostname + - `grafana-values.yaml` — hostname - `gitea-values.yaml` — `storageClass` for persistence + PostgreSQL - - `opencost-values.yaml` — `customPricing` cost model for your cloud -3. **Create a Kustomize overlay** (if needed): `infra/overlays/aks-prod/kustomization.yaml` - - Patch each Application's `valueFiles[1]` to point to `aks-prod/` files -4. **Create a root Application**: `_app-of-apps-aks-dev.yaml` pointing to the overlay -5. **Create Sealed Secrets** for the new cluster: - - `secrets/aks-dev/` — TLS certs, credentials, backup S3 config -6. **Update `gitea-backup-s3` secret** with the new cloud's S3-compatible endpoint -7. **Bootstrap**: `kubectl apply -f _app-of-apps-aks-dev.yaml -n argocd` + - `opencost-values.yaml` — pricing model or cloud billing integration +3. **Kustomize overlay**: `infra/overlays/oci-dev/kustomization.yaml` — patch `valueFiles[1]` for each Application +4. **App-of-apps**: `_app-of-apps-oci-dev.yaml` — points to `infra/overlays/oci-dev` +5. **Sealed Secrets**: `secrets/oci-dev/` — TLS certs, credentials, backup S3 config +6. **Bootstrap**: `./bootstrap.sh oci-dev` --- diff --git a/infra/overlays/aks-dev/kustomization.yaml b/infra/overlays/aks-dev/kustomization.yaml new file mode 100644 index 0000000..185869f --- /dev/null +++ b/infra/overlays/aks-dev/kustomization.yaml @@ -0,0 +1,68 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- ../../base + +patches: +# 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/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 + name: gitea + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/aks-dev/gitea-values.yaml + +# 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/aks-dev/opencost-values.yaml + +# 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 new file mode 100644 index 0000000..73b0aaa --- /dev/null +++ b/infra/overlays/aks-prod/kustomization.yaml @@ -0,0 +1,68 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- ../../base + +patches: +# 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/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 + name: gitea + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/aks-prod/gitea-values.yaml + +# 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/aks-prod/opencost-values.yaml + +# 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 new file mode 100644 index 0000000..16e542a --- /dev/null +++ b/infra/overlays/eks-dev/kustomization.yaml @@ -0,0 +1,68 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- ../../base + +patches: +# 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/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 + name: gitea + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/eks-dev/gitea-values.yaml + +# 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/eks-dev/opencost-values.yaml + +# 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 new file mode 100644 index 0000000..46be9a9 --- /dev/null +++ b/infra/overlays/eks-prod/kustomization.yaml @@ -0,0 +1,68 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- ../../base + +patches: +# 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/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 + name: gitea + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/eks-prod/gitea-values.yaml + +# 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/eks-prod/opencost-values.yaml + +# 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 new file mode 100644 index 0000000..4d3da3e --- /dev/null +++ b/infra/overlays/gke-dev/kustomization.yaml @@ -0,0 +1,68 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- ../../base + +patches: +# 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/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 + name: gitea + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/gke-dev/gitea-values.yaml + +# 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/gke-dev/opencost-values.yaml + +# 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 new file mode 100644 index 0000000..0f4a583 --- /dev/null +++ b/infra/overlays/gke-prod/kustomization.yaml @@ -0,0 +1,68 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- ../../base + +patches: +# 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/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 + name: gitea + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/gke-prod/gitea-values.yaml + +# 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/gke-prod/opencost-values.yaml + +# 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 diff --git a/infra/values/aks-dev/gitea-values.yaml b/infra/values/aks-dev/gitea-values.yaml new file mode 100644 index 0000000..94e9760 --- /dev/null +++ b/infra/values/aks-dev/gitea-values.yaml @@ -0,0 +1,7 @@ +# AKS-specific: Azure managed disk storage class +persistence: + storageClass: managed-csi-premium +postgresql: + primary: + persistence: + storageClass: managed-csi-premium 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 new file mode 100644 index 0000000..64dcfa1 --- /dev/null +++ b/infra/values/aks-dev/opencost-values.yaml @@ -0,0 +1,8 @@ +# AKS-specific: Azure pricing via Cloud Billing API +opencost: + exporter: + cloudProviderApiKey: "" + customPricing: + enabled: false + azure: + secretName: opencost-azure-billing diff --git a/infra/values/aks-dev/traefik-values.yaml b/infra/values/aks-dev/traefik-values.yaml new file mode 100644 index 0000000..fd5c882 --- /dev/null +++ b/infra/values/aks-dev/traefik-values.yaml @@ -0,0 +1,11 @@ +# AKS-specific: Azure Load Balancer for Traefik +service: + annotations: + service.beta.kubernetes.io/azure-load-balancer-health-probe-request-path: /ping +ports: + web: + forwardedHeaders: + trustedIPs: "10.0.0.0/8" + websecure: + forwardedHeaders: + trustedIPs: "10.0.0.0/8" diff --git a/infra/values/aks-prod/gitea-values.yaml b/infra/values/aks-prod/gitea-values.yaml new file mode 100644 index 0000000..d035b5d --- /dev/null +++ b/infra/values/aks-prod/gitea-values.yaml @@ -0,0 +1,7 @@ +# AKS-specific: Azure managed disk storage class (prod) +persistence: + storageClass: managed-csi-premium +postgresql: + primary: + persistence: + storageClass: managed-csi-premium 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 new file mode 100644 index 0000000..d465129 --- /dev/null +++ b/infra/values/aks-prod/opencost-values.yaml @@ -0,0 +1,8 @@ +# AKS-specific: Azure pricing via Cloud Billing API (prod) +opencost: + exporter: + cloudProviderApiKey: "" + customPricing: + enabled: false + azure: + secretName: opencost-azure-billing diff --git a/infra/values/aks-prod/traefik-values.yaml b/infra/values/aks-prod/traefik-values.yaml new file mode 100644 index 0000000..469f276 --- /dev/null +++ b/infra/values/aks-prod/traefik-values.yaml @@ -0,0 +1,12 @@ +# AKS-specific: Azure Load Balancer for Traefik (prod) +service: + annotations: + 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" + websecure: + forwardedHeaders: + trustedIPs: "10.0.0.0/8" diff --git a/infra/values/eks-dev/gitea-values.yaml b/infra/values/eks-dev/gitea-values.yaml new file mode 100644 index 0000000..c55964f --- /dev/null +++ b/infra/values/eks-dev/gitea-values.yaml @@ -0,0 +1,7 @@ +# EKS-specific: gp3 storage class +persistence: + storageClass: gp3 +postgresql: + primary: + persistence: + storageClass: gp3 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 new file mode 100644 index 0000000..efd110a --- /dev/null +++ b/infra/values/eks-dev/opencost-values.yaml @@ -0,0 +1,11 @@ +# EKS-specific: AWS pricing via Cost and Usage Report +opencost: + exporter: + cloudProviderApiKey: "" + customPricing: + enabled: false + aws: + spot_data_region: "" + spot_data_bucket: "" + spot_data_prefix: "" + account_id: "" diff --git a/infra/values/eks-dev/traefik-values.yaml b/infra/values/eks-dev/traefik-values.yaml new file mode 100644 index 0000000..1390d17 --- /dev/null +++ b/infra/values/eks-dev/traefik-values.yaml @@ -0,0 +1,17 @@ +# EKS-specific: AWS NLB for Traefik +service: + annotations: + 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" + 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/eks-prod/gitea-values.yaml b/infra/values/eks-prod/gitea-values.yaml new file mode 100644 index 0000000..7aae415 --- /dev/null +++ b/infra/values/eks-prod/gitea-values.yaml @@ -0,0 +1,7 @@ +# EKS-specific: gp3 storage class (prod) +persistence: + storageClass: gp3 +postgresql: + primary: + persistence: + storageClass: gp3 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 new file mode 100644 index 0000000..ac86a76 --- /dev/null +++ b/infra/values/eks-prod/opencost-values.yaml @@ -0,0 +1,11 @@ +# EKS-specific: AWS pricing via Cost and Usage Report (prod) +opencost: + exporter: + cloudProviderApiKey: "" + customPricing: + enabled: false + aws: + spot_data_region: "" + spot_data_bucket: "" + spot_data_prefix: "" + account_id: "" diff --git a/infra/values/eks-prod/traefik-values.yaml b/infra/values/eks-prod/traefik-values.yaml new file mode 100644 index 0000000..fd64496 --- /dev/null +++ b/infra/values/eks-prod/traefik-values.yaml @@ -0,0 +1,18 @@ +# EKS-specific: AWS NLB for Traefik (prod) +service: + annotations: + 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" + 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/gke-dev/gitea-values.yaml b/infra/values/gke-dev/gitea-values.yaml new file mode 100644 index 0000000..04ec9aa --- /dev/null +++ b/infra/values/gke-dev/gitea-values.yaml @@ -0,0 +1,7 @@ +# GKE-specific: SSD persistent disk storage class +persistence: + storageClass: premium-rwo +postgresql: + primary: + persistence: + storageClass: premium-rwo 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 new file mode 100644 index 0000000..6534718 --- /dev/null +++ b/infra/values/gke-dev/opencost-values.yaml @@ -0,0 +1,10 @@ +# GKE-specific: GCP pricing via BigQuery billing export +opencost: + exporter: + cloudProviderApiKey: "" + customPricing: + 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 new file mode 100644 index 0000000..96a78ab --- /dev/null +++ b/infra/values/gke-dev/traefik-values.yaml @@ -0,0 +1,12 @@ +# GKE-specific: Google Cloud Load Balancer for Traefik +service: + annotations: + cloud.google.com/neg: '{"ingress":true}' + networking.gke.io/load-balancer-type: External +ports: + web: + forwardedHeaders: + trustedIPs: "10.0.0.0/8" + websecure: + forwardedHeaders: + trustedIPs: "10.0.0.0/8" diff --git a/infra/values/gke-prod/gitea-values.yaml b/infra/values/gke-prod/gitea-values.yaml new file mode 100644 index 0000000..5df877a --- /dev/null +++ b/infra/values/gke-prod/gitea-values.yaml @@ -0,0 +1,7 @@ +# GKE-specific: SSD persistent disk storage class (prod) +persistence: + storageClass: premium-rwo +postgresql: + primary: + persistence: + storageClass: premium-rwo 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 new file mode 100644 index 0000000..404f49b --- /dev/null +++ b/infra/values/gke-prod/opencost-values.yaml @@ -0,0 +1,10 @@ +# GKE-specific: GCP pricing via BigQuery billing export (prod) +opencost: + exporter: + cloudProviderApiKey: "" + customPricing: + 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 new file mode 100644 index 0000000..7d70c40 --- /dev/null +++ b/infra/values/gke-prod/traefik-values.yaml @@ -0,0 +1,12 @@ +# GKE-specific: Google Cloud Load Balancer for Traefik (prod) +service: + annotations: + cloud.google.com/neg: '{"ingress":true}' + networking.gke.io/load-balancer-type: External +ports: + web: + forwardedHeaders: + trustedIPs: "10.0.0.0/8" + websecure: + forwardedHeaders: + trustedIPs: "10.0.0.0/8"