Initial Phoenix Sankofa Cloud setup

- Complete project structure with Next.js frontend
- GraphQL API backend with Apollo Server
- Portal application with NextAuth
- Crossplane Proxmox provider
- GitOps configurations
- CI/CD pipelines
- Testing infrastructure (Vitest, Jest, Go tests)
- Error handling and monitoring
- Security hardening
- UI component library
- Documentation
This commit is contained in:
defiQUG
2025-11-28 12:54:33 -08:00
commit 6f28146ac3
229 changed files with 43136 additions and 0 deletions

View File

@@ -0,0 +1,26 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: root-apps
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: https://github.com/yourorg/hybrid-cloud-gitops
targetRevision: main
path: gitops/apps
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
allowEmpty: false
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground
- PruneLast=true

View File

@@ -0,0 +1,50 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: crossplane
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: https://charts.crossplane.io/stable
targetRevision: 1.14.0
chart: crossplane
helm:
releaseName: crossplane
values: |
args:
- --enable-usages
resourcesCrossplane:
limits:
cpu: 1000m
memory: 1Gi
requests:
cpu: 100m
memory: 128Mi
resourcesRBACManager:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 50m
memory: 64Mi
provider:
packages:
- crossplane/provider-kubernetes:v0.12.0
- crossplane/provider-helm:v0.15.0
- crossplane/provider-azure:v0.20.0
- crossplane/provider-aws:v0.40.0
- crossplane/provider-gcp:v0.35.0
destination:
server: https://kubernetes.default.svc
namespace: crossplane-system
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground

View File

@@ -0,0 +1,75 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: monitoring
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: https://prometheus-community.github.io/helm-charts
targetRevision: 48.0.0
chart: kube-prometheus-stack
helm:
releaseName: monitoring
values: |
prometheus:
prometheusSpec:
retention: 30d
storageSpec:
volumeClaimTemplate:
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 500Gi
resources:
requests:
cpu: 1000m
memory: 4Gi
limits:
cpu: 2000m
memory: 8Gi
grafana:
enabled: true
adminPassword: changeme
ingress:
enabled: true
ingressClassName: nginx
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
hosts:
- grafana.yourdomain.com
persistence:
enabled: true
size: 10Gi
alertmanager:
alertmanagerSpec:
retention: 120h
storage:
volumeClaimTemplate:
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 50Gi
prometheusOperator:
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
destination:
server: https://kubernetes.default.svc
namespace: monitoring
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground

View File

@@ -0,0 +1,60 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: loki
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: https://grafana.github.io/helm-charts
targetRevision: 0.69.0
chart: loki-stack
helm:
releaseName: loki
values: |
loki:
enabled: true
persistence:
enabled: true
size: 100Gi
config:
schema_config:
configs:
- from: "2024-01-01"
store: boltdb-shipper
object_store: filesystem
schema: v11
index:
prefix: index_
period: 24h
storage_config:
boltdb_shipper:
active_index_directory: /loki/boltdb-shipper-active
cache_location: /loki/boltdb-shipper-cache
shared_store: filesystem
filesystem:
directory: /loki/chunks
limits_config:
enforce_metric_name: false
reject_old_samples: true
reject_old_samples_max_age: 168h
promtail:
enabled: true
config:
clients:
- url: http://loki:3100/loki/api/v1/push
grafana:
enabled: false
destination:
server: https://kubernetes.default.svc
namespace: monitoring
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground

View File

@@ -0,0 +1,24 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: portal
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: https://github.com/yourorg/hybrid-cloud-gitops
targetRevision: main
path: gitops/apps/portal/manifests
destination:
server: https://kubernetes.default.svc
namespace: portal
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground

View File

@@ -0,0 +1,113 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: portal
namespace: portal
labels:
app: portal
spec:
replicas: 3
selector:
matchLabels:
app: portal
template:
metadata:
labels:
app: portal
spec:
containers:
- name: portal
image: yourregistry/portal:latest
ports:
- containerPort: 3000
name: http
env:
- name: NODE_ENV
value: "production"
- name: KEYCLOAK_URL
valueFrom:
configMapKeyRef:
name: portal-config
key: keycloak-url
- name: CROSSPLANE_API_URL
valueFrom:
configMapKeyRef:
name: portal-config
key: crossplane-api-url
- name: ARGOCD_URL
valueFrom:
configMapKeyRef:
name: portal-config
key: argocd-url
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: 1000m
memory: 2Gi
livenessProbe:
httpGet:
path: /api/health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /api/health
port: 3000
initialDelaySeconds: 10
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: portal
namespace: portal
spec:
selector:
app: portal
ports:
- port: 80
targetPort: 3000
name: http
type: ClusterIP
---
apiVersion: v1
kind: ConfigMap
metadata:
name: portal-config
namespace: portal
data:
keycloak-url: "https://keycloak.yourdomain.com"
crossplane-api-url: "https://crossplane-api.crossplane-system.svc.cluster.local"
argocd-url: "https://argocd.yourdomain.com"
grafana-url: "https://grafana.yourdomain.com"
loki-url: "https://loki.monitoring.svc.cluster.local:3100"
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: portal
namespace: portal
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- portal.yourdomain.com
secretName: portal-tls
rules:
- host: portal.yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: portal
port:
number: 80

View File

@@ -0,0 +1,44 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: rancher
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: https://github.com/rancher/rancher
targetRevision: release/v2.8
path: charts/rancher
helm:
releaseName: rancher
values: |
hostname: rancher.yourdomain.com
replicas: 3
ingress:
enabled: true
ingressClassName: nginx
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
tls: external
rancherImage: rancher/rancher
rancherImageTag: v2.8.0
global:
cattle:
systemDefaultRegistry: ""
extraEnv:
- name: CATTLE_PROMETHEUS_METRICS
value: "true"
destination:
server: https://kubernetes.default.svc
namespace: rancher-system
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground
- PruneLast=true

View File

@@ -0,0 +1,54 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: vault
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: https://helm.releases.hashicorp.com
targetRevision: 0.24.0
chart: vault
helm:
releaseName: vault
values: |
server:
ha:
enabled: true
replicas: 3
raft:
enabled: true
setNodeId: true
image:
repository: hashicorp/vault
tag: "1.15.0"
service:
type: ClusterIP
ingress:
enabled: true
ingressClassName: nginx
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
hosts:
- host: vault.yourdomain.com
paths:
- /
ui:
enabled: true
injector:
enabled: true
csi:
enabled: true
destination:
server: https://kubernetes.default.svc
namespace: vault
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground