diff --git a/.tofu/scripts/setup-cluster.sh b/.tofu/scripts/setup-cluster.sh index 869dd02..0651909 100644 --- a/.tofu/scripts/setup-cluster.sh +++ b/.tofu/scripts/setup-cluster.sh @@ -15,6 +15,7 @@ Usage: $0 [options] Clusters: aks-dev | aks-prod | eks-dev | eks-prod gke-dev | gke-prod | upc-dev | upc-prod + forte-group -workload (for workload clusters) Options: diff --git a/_app-of-apps-forte-group.yaml b/_app-of-apps-forte-group.yaml new file mode 100644 index 0000000..19492c3 --- /dev/null +++ b/_app-of-apps-forte-group.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/forte-group + destination: + server: https://kubernetes.default.svc + namespace: default + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/apps/base/kustomization.yaml b/apps/overlays/forte-group/kustomization.yaml similarity index 57% rename from apps/base/kustomization.yaml rename to apps/overlays/forte-group/kustomization.yaml index a501fbf..14461d9 100644 --- a/apps/base/kustomization.yaml +++ b/apps/overlays/forte-group/kustomization.yaml @@ -1,8 +1,6 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: -- dot-ai-stack -- mcp10x -- musicman -- ts-mcp -- argo-mcp +- ../../base/mcp10x +- ../../base/ts-mcp + diff --git a/apps/overlays/upc-dev/kustomization.yaml b/apps/overlays/upc-dev/kustomization.yaml index 04cedb3..fbac63d 100644 --- a/apps/overlays/upc-dev/kustomization.yaml +++ b/apps/overlays/upc-dev/kustomization.yaml @@ -1,13 +1,19 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: -- ../../base +- ../../base/musicman +- ../../base/dot-ai-stack +- ../../base/argo-mcp - forte-drop-postgresql - forte-drop - forte-drop-mcp -# No patches needed — base apps already default to "upc-dev" value paths -# (upc-dev is the default/base cluster). -# forte-drop (postgres + web + mcp) and dbunk-demo are upc-dev-only apps — their -# values hardcode upc-dev hosts (drop.forteapps.net etc.) and must not sync to -# upc-prod, so they live here in the overlay rather than in apps/base/. +patches: +# dot-ai-stack: swap upc-dev → forte-group +- target: + kind: Application + name: dot-ai-stack + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/upc-dev/dot-ai-stack-values.yaml diff --git a/apps/overlays/upc-prod/kustomization.yaml b/apps/overlays/upc-prod/kustomization.yaml index 79e912b..4e4f197 100644 --- a/apps/overlays/upc-prod/kustomization.yaml +++ b/apps/overlays/upc-prod/kustomization.yaml @@ -2,13 +2,3 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - ../../base - -patches: -# dot-ai-stack: swap upc-dev → upc-prod -- target: - kind: Application - name: dot-ai-stack - patch: | - - op: replace - path: /spec/sources/0/helm/valueFiles/1 - value: $values/infra/values/upc-prod/dot-ai-stack-values.yaml diff --git a/bootstrap.sh b/bootstrap.sh index b2a9794..240e03b 100644 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -3,7 +3,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|aks-dev|aks-prod|eks-dev|eks-prod|gke-dev|gke-prod)}" +CLUSTER="${1:?Usage: ./bootstrap.sh (upc-dev|upc-prod|forte-group|aks-dev|aks-prod|eks-dev|eks-prod|gke-dev|gke-prod)}" echo "running $0 for cluster: ${CLUSTER}..." diff --git a/clusters/forte-group.yaml b/clusters/forte-group.yaml new file mode 100644 index 0000000..c14a049 --- /dev/null +++ b/clusters/forte-group.yaml @@ -0,0 +1,12 @@ +# Cluster config reference — values must match the corresponding overlay files. +# Read by bootstrap.sh at install time; NOT auto-propagated to ArgoCD value files. +clusterName: prod-fd-no-svg1 # → infra/values/forte-group/argocd-values.yaml (notifications.context.clusterName) +domain: fortedigital.com # → infra/values/base/gitea-values.yaml, renovate-values.yaml, keycloak-values.yaml (subdomains) +argocdDomain: argocd.127.0.0.1.nip.io # → infra/values/forte-group/argocd-values.yaml (global.domain) +grafanaDomain: grafana.fortedigital.com # → infra/values/forte-group/grafana-values.yaml (ingress.hosts) +keycloakDomain: id.fortedigital.com # → infra/values/forte-group/keycloak-values.yaml (ingress.hostname) +dotaiDomain: kubemcp.fortedigital.com # → infra/values/forte-group/dot-ai-stack-values.yaml (dot-ai.ingress.host) +dotaiUiDomain: kubemcpui.fortedigital.com # → infra/values/forte-group/dot-ai-stack-values.yaml (dot-ai-ui.ingress.host) +letsencryptEmail: danijel.simeunovic@fortedigital.com # → cluster-resources/letsencrypt-issuer.yaml (spec.acme.email) +trustedIPs: "172.16.1.0/24" # → infra/values/forte-group/traefik-values.yaml (ports.*.trustedIPs) +cloudProvider: upcloud # → determines overlay directory and cloud-specific LB/storage annotations diff --git a/infra/overlays/forte-group/kustomization.yaml b/infra/overlays/forte-group/kustomization.yaml new file mode 100644 index 0000000..5a60045 --- /dev/null +++ b/infra/overlays/forte-group/kustomization.yaml @@ -0,0 +1,61 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- ../../base/cert-manager-application +- ../../base/cluster-resources-application +- ../../base/enterprise-apps +- ../../base/fluent-bit +- ../../base/gitea +- ../../base/gitea-actions +- ../../base/grafana +- ../../base/grafana-dashboards +- ../../base/homepage +- ../../base/karpor +- ../../base/keycloak +- ../../base/kyverno +- ../../base/kyverno-policies +- ../../base/loki +- ../../base/opencost +- ../../base/prometheus +- ../../base/renovate +- ../../base/sealedsecrets +- ../../base/tempo +- ../../base/traefik-application +- ../../base/vault + +patches: +# Traefik: swap upc-dev → forte-group +- target: + kind: Application + name: traefik + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/forte-group/traefik-values.yaml + +# Grafana: swap upc-dev → forte-group +- target: + kind: Application + name: grafana + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/forte-group/grafana-values.yaml + +# OpenCost: swap upc-dev → forte-group +- target: + kind: Application + name: opencost + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/forte-group/opencost-values.yaml + +# Gitea: swap upc-dev → forte-group +- target: + kind: Application + name: gitea + patch: | + - op: replace + path: /spec/sources/0/helm/valueFiles/1 + value: $values/infra/values/forte-group/gitea-values.yaml diff --git a/infra/overlays/upc-dev/kustomization.yaml b/infra/overlays/upc-dev/kustomization.yaml index b52a217..6121111 100644 --- a/infra/overlays/upc-dev/kustomization.yaml +++ b/infra/overlays/upc-dev/kustomization.yaml @@ -28,12 +28,3 @@ resources: # No patches needed — base already has "upc-dev" paths # upc-dev is the default/base cluster - -patches: -- target: - kind: Application - name: databunker - patch: | - - op: add - path: /spec/sources/0/helm/valueFiles/- - value: $values/infra/values/upc-dev/databunker-values.yaml diff --git a/infra/values/forte-group/argocd-values.yaml b/infra/values/forte-group/argocd-values.yaml new file mode 100644 index 0000000..7844762 --- /dev/null +++ b/infra/values/forte-group/argocd-values.yaml @@ -0,0 +1,5 @@ +global: + domain: argocd.fortedigital.com +notifications: + context: + clusterName: "prod-fd-no-svg1" diff --git a/infra/values/forte-group/gitea-values.yaml b/infra/values/forte-group/gitea-values.yaml new file mode 100644 index 0000000..d86384e --- /dev/null +++ b/infra/values/forte-group/gitea-values.yaml @@ -0,0 +1,50 @@ +# UpCloud storage class for Gitea and its embedded PostgreSQL +persistence: + storageClass: upcloud-block-storage-maxiops +postgresql: + primary: + persistence: + storageClass: upcloud-block-storage-maxiops + +gitea: + # -- Gitea app.ini configuration + config: + APP_NAME: "Forte Git" + + server: + DOMAIN: source.forteapps.net + ROOT_URL: https://source.forteapps.net + SSH_DOMAIN: source.forteapps.net + + +# -- Ingress via Traefik with Let's Encrypt TLS +ingress: + enabled: true + className: traefik + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + gethomepage.dev/enabled: "true" + gethomepage.dev/name: "Gitea" + gethomepage.dev/description: "Git hosting & CI/CD" + gethomepage.dev/group: "DevOps" + gethomepage.dev/icon: "gitea" + gethomepage.dev/href: "https://source.forteapps.net" + gethomepage.dev/widget.type: "gitea" + gethomepage.dev/widget.url: "https://source.forteapps.net" + gethomepage.dev/widget.key: "{{HOMEPAGE_VAR_GITEA_TOKEN}}" + hosts: + - host: source.forteapps.net + paths: + - path: / + pathType: Prefix + tls: + - secretName: gitea-tls + hosts: + - source.forteapps.net + +# -- Git repository storage +persistence: + enabled: true + size: 20Gi + accessModes: + - ReadWriteOnce diff --git a/infra/values/forte-group/grafana-values.yaml b/infra/values/forte-group/grafana-values.yaml new file mode 100644 index 0000000..fb9cf3d --- /dev/null +++ b/infra/values/forte-group/grafana-values.yaml @@ -0,0 +1,3 @@ +ingress: + hosts: + - grafana.fortedigital.com diff --git a/infra/values/forte-group/keycloak-values.yaml b/infra/values/forte-group/keycloak-values.yaml new file mode 100644 index 0000000..72938dc --- /dev/null +++ b/infra/values/forte-group/keycloak-values.yaml @@ -0,0 +1,2 @@ +ingress: + hostname: id.forteapps.com diff --git a/infra/values/forte-group/opencost-values.yaml b/infra/values/forte-group/opencost-values.yaml new file mode 100644 index 0000000..06a7488 --- /dev/null +++ b/infra/values/forte-group/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/forte-group/traefik-values.yaml b/infra/values/forte-group/traefik-values.yaml new file mode 100644 index 0000000..06a9076 --- /dev/null +++ b/infra/values/forte-group/traefik-values.yaml @@ -0,0 +1,13 @@ +service: + annotations: {} +ports: + web: + proxyProtocol: + trustedIPs: "10.0.0.0/16" + forwardedHeaders: + trustedIPs: "10.0.0.0/16" + websecure: + proxyProtocol: + trustedIPs: "10.0.0.0/16" + forwardedHeaders: + trustedIPs: "10.0.0.0/16" diff --git a/infra/values/upc-prod/dot-ai-stack-values.yaml b/infra/values/upc-prod/dot-ai-stack-values.yaml deleted file mode 100644 index 9d5712a..0000000 --- a/infra/values/upc-prod/dot-ai-stack-values.yaml +++ /dev/null @@ -1,8 +0,0 @@ -dot-ai: - ingress: - host: kubemcp.fortedigital.com - webUI: - baseUrl: http://kubemcpui.fortedigital.com -dot-ai-ui: - ingress: - host: kubemcpui.fortedigital.com