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:
138
gitops/README.md
Normal file
138
gitops/README.md
Normal file
@@ -0,0 +1,138 @@
|
||||
# GitOps Repository
|
||||
|
||||
This repository contains all infrastructure and application definitions managed via ArgoCD GitOps.
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
gitops/
|
||||
├── base/ # Base Kubernetes resources
|
||||
│ ├── namespaces/ # Namespace definitions
|
||||
│ ├── rbac/ # RBAC roles and bindings
|
||||
│ └── kustomization.yaml # Base kustomization
|
||||
├── overlays/ # Environment-specific overlays
|
||||
│ ├── dev/ # Development environment
|
||||
│ ├── staging/ # Staging environment
|
||||
│ └── prod/ # Production environment
|
||||
├── apps/ # ArgoCD Application definitions
|
||||
│ ├── rancher/ # Rancher installation
|
||||
│ ├── crossplane/ # Crossplane installation
|
||||
│ ├── argocd/ # ArgoCD self-config
|
||||
│ ├── vault/ # Vault installation
|
||||
│ ├── monitoring/ # Prometheus, Grafana, Loki
|
||||
│ └── portal/ # Portal deployment
|
||||
├── infrastructure/ # Crossplane infrastructure definitions
|
||||
│ ├── xrds/ # Composite Resource Definitions
|
||||
│ ├── compositions/ # Composition templates
|
||||
│ └── claims/ # Example claims
|
||||
└── templates/ # Reusable templates
|
||||
├── vm/ # VM templates
|
||||
├── cluster/ # K8s cluster templates
|
||||
└── network/ # Network templates
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Bootstrap ArgoCD
|
||||
|
||||
1. Install ArgoCD on your cluster:
|
||||
```bash
|
||||
kubectl create namespace argocd
|
||||
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
|
||||
```
|
||||
|
||||
2. Apply the root ArgoCD Application:
|
||||
```bash
|
||||
kubectl apply -f apps/argocd/root-application.yaml
|
||||
```
|
||||
|
||||
### Deploy to Specific Environment
|
||||
|
||||
```bash
|
||||
# Development
|
||||
kubectl apply -k overlays/dev/
|
||||
|
||||
# Production
|
||||
kubectl apply -k overlays/prod/
|
||||
```
|
||||
|
||||
## Environment Configuration
|
||||
|
||||
Each overlay directory contains:
|
||||
- `kustomization.yaml` - Environment-specific patches
|
||||
- `config/` - ConfigMaps and Secrets
|
||||
- `patches/` - Strategic merge patches
|
||||
|
||||
## Infrastructure as Code
|
||||
|
||||
Crossplane XRDs and Compositions are defined in `infrastructure/`. These enable high-level resource provisioning through the portal.
|
||||
|
||||
### Example: Creating a VM
|
||||
|
||||
1. Create a claim:
|
||||
```bash
|
||||
kubectl apply -f infrastructure/claims/vm-claim-example.yaml
|
||||
```
|
||||
|
||||
2. Monitor the resource:
|
||||
```bash
|
||||
kubectl get proxmoxvm web-server-01
|
||||
kubectl describe proxmoxvm web-server-01
|
||||
```
|
||||
|
||||
### Compositions
|
||||
|
||||
Compositions define reusable templates for common resources:
|
||||
|
||||
- `vm-ubuntu.yaml` - Ubuntu VM template
|
||||
- Additional compositions can be added for other OS images
|
||||
|
||||
### Claims
|
||||
|
||||
Claims are user-facing resources that use compositions:
|
||||
|
||||
- `vm-claim-example.yaml` - Example VM claim
|
||||
|
||||
## GitOps Workflow
|
||||
|
||||
1. **Developer** creates/modifies resources in this repository
|
||||
2. **Git** triggers ArgoCD sync (or manual sync)
|
||||
3. **ArgoCD** applies changes to the cluster
|
||||
4. **Crossplane** provisions infrastructure based on claims
|
||||
5. **Monitoring** tracks resource status
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Always use overlays for environment-specific configurations
|
||||
- Keep base configurations generic and reusable
|
||||
- Use Kustomize for configuration management
|
||||
- Document all custom compositions
|
||||
- Version control all infrastructure changes
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### ArgoCD Sync Issues
|
||||
|
||||
```bash
|
||||
# Check ArgoCD application status
|
||||
kubectl get applications -n argocd
|
||||
|
||||
# View sync logs
|
||||
argocd app logs <app-name> --tail=100
|
||||
```
|
||||
|
||||
### Crossplane Issues
|
||||
|
||||
```bash
|
||||
# Check provider status
|
||||
kubectl get providerconfig -n crossplane-system
|
||||
|
||||
# View resource events
|
||||
kubectl describe proxmoxvm <vm-name>
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [ArgoCD Documentation](https://argo-cd.readthedocs.io/)
|
||||
- [Crossplane Documentation](https://crossplane.io/docs/)
|
||||
- [Kustomize Documentation](https://kustomize.io/)
|
||||
26
gitops/apps/argocd/root-application.yaml
Normal file
26
gitops/apps/argocd/root-application.yaml
Normal 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
|
||||
|
||||
50
gitops/apps/crossplane/application.yaml
Normal file
50
gitops/apps/crossplane/application.yaml
Normal 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
|
||||
|
||||
75
gitops/apps/monitoring/application.yaml
Normal file
75
gitops/apps/monitoring/application.yaml
Normal 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
|
||||
|
||||
60
gitops/apps/monitoring/loki-application.yaml
Normal file
60
gitops/apps/monitoring/loki-application.yaml
Normal 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
|
||||
|
||||
24
gitops/apps/portal/application.yaml
Normal file
24
gitops/apps/portal/application.yaml
Normal 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
|
||||
|
||||
113
gitops/apps/portal/manifests/deployment.yaml
Normal file
113
gitops/apps/portal/manifests/deployment.yaml
Normal 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
|
||||
|
||||
44
gitops/apps/rancher/application.yaml
Normal file
44
gitops/apps/rancher/application.yaml
Normal 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
|
||||
|
||||
54
gitops/apps/vault/application.yaml
Normal file
54
gitops/apps/vault/application.yaml
Normal 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
|
||||
|
||||
12
gitops/base/kustomization.yaml
Normal file
12
gitops/base/kustomization.yaml
Normal file
@@ -0,0 +1,12 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
namespace: default
|
||||
|
||||
resources:
|
||||
- namespaces/
|
||||
- rbac/
|
||||
|
||||
commonLabels:
|
||||
app.kubernetes.io/managed-by: argocd
|
||||
app.kubernetes.io/part-of: phoenix-sankofa-cloud
|
||||
56
gitops/base/namespaces/namespaces.yaml
Normal file
56
gitops/base/namespaces/namespaces.yaml
Normal file
@@ -0,0 +1,56 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: rancher-system
|
||||
labels:
|
||||
name: rancher-system
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: crossplane-system
|
||||
labels:
|
||||
name: crossplane-system
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: argocd
|
||||
labels:
|
||||
name: argocd
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: vault
|
||||
labels:
|
||||
name: vault
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: monitoring
|
||||
labels:
|
||||
name: monitoring
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: portal
|
||||
labels:
|
||||
name: portal
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: keycloak
|
||||
labels:
|
||||
name: keycloak
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: infrastructure
|
||||
labels:
|
||||
name: infrastructure
|
||||
|
||||
34
gitops/base/rbac/cluster-admin.yaml
Normal file
34
gitops/base/rbac/cluster-admin.yaml
Normal file
@@ -0,0 +1,34 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: hybrid-cloud-admin
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["*"]
|
||||
verbs: ["*"]
|
||||
- apiGroups: ["apps"]
|
||||
resources: ["*"]
|
||||
verbs: ["*"]
|
||||
- apiGroups: ["extensions"]
|
||||
resources: ["*"]
|
||||
verbs: ["*"]
|
||||
- apiGroups: ["networking.k8s.io"]
|
||||
resources: ["*"]
|
||||
verbs: ["*"]
|
||||
- apiGroups: ["pkg.crossplane.io"]
|
||||
resources: ["*"]
|
||||
verbs: ["*"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: hybrid-cloud-admin-binding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: hybrid-cloud-admin
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: argocd-application-controller
|
||||
namespace: argocd
|
||||
|
||||
26
gitops/infrastructure/claims/vm-claim-example.yaml
Normal file
26
gitops/infrastructure/claims/vm-claim-example.yaml
Normal file
@@ -0,0 +1,26 @@
|
||||
apiVersion: proxmox.yourorg.io/v1alpha1
|
||||
kind: ProxmoxVM
|
||||
metadata:
|
||||
name: web-server-01
|
||||
namespace: default
|
||||
spec:
|
||||
forProvider:
|
||||
node: pve1
|
||||
name: web-server-01
|
||||
cpu: 4
|
||||
memory: 8Gi
|
||||
disk: 100Gi
|
||||
storage: local-lvm
|
||||
network: vmbr0
|
||||
image: ubuntu-22.04-cloud
|
||||
site: us-east-1
|
||||
userData: |
|
||||
#cloud-config
|
||||
users:
|
||||
- name: admin
|
||||
ssh-authorized-keys:
|
||||
- ssh-rsa AAAAB3NzaC1yc2E...
|
||||
sshKeys:
|
||||
- ssh-rsa AAAAB3NzaC1yc2E...
|
||||
providerConfigRef:
|
||||
name: proxmox-provider-config
|
||||
44
gitops/infrastructure/compositions/vm-ubuntu.yaml
Normal file
44
gitops/infrastructure/compositions/vm-ubuntu.yaml
Normal file
@@ -0,0 +1,44 @@
|
||||
apiVersion: apiextensions.crossplane.io/v1
|
||||
kind: Composition
|
||||
metadata:
|
||||
name: vm-ubuntu
|
||||
labels:
|
||||
provider: proxmox
|
||||
spec:
|
||||
writeConnectionSecretsToRef:
|
||||
name: vm-connection-secret
|
||||
namespace: crossplane-system
|
||||
compositeTypeRef:
|
||||
apiVersion: proxmox.yourorg.io/v1alpha1
|
||||
kind: ProxmoxVM
|
||||
resources:
|
||||
- name: proxmox-vm
|
||||
base:
|
||||
apiVersion: proxmox.yourorg.io/v1alpha1
|
||||
kind: ProxmoxVM
|
||||
spec:
|
||||
forProvider:
|
||||
node: pve1
|
||||
cpu: 2
|
||||
memory: 4Gi
|
||||
disk: 50Gi
|
||||
storage: local-lvm
|
||||
network: vmbr0
|
||||
image: ubuntu-22.04-cloud
|
||||
site: us-east-1
|
||||
patches:
|
||||
- type: FromCompositeFieldPath
|
||||
fromFieldPath: spec.forProvider.name
|
||||
toFieldPath: spec.forProvider.name
|
||||
- type: FromCompositeFieldPath
|
||||
fromFieldPath: spec.forProvider.cpu
|
||||
toFieldPath: spec.forProvider.cpu
|
||||
- type: FromCompositeFieldPath
|
||||
fromFieldPath: spec.forProvider.memory
|
||||
toFieldPath: spec.forProvider.memory
|
||||
- type: FromCompositeFieldPath
|
||||
fromFieldPath: spec.forProvider.disk
|
||||
toFieldPath: spec.forProvider.disk
|
||||
- type: FromCompositeFieldPath
|
||||
fromFieldPath: spec.forProvider.site
|
||||
toFieldPath: spec.forProvider.site
|
||||
101
gitops/infrastructure/xrds/virtualmachine.yaml
Normal file
101
gitops/infrastructure/xrds/virtualmachine.yaml
Normal file
@@ -0,0 +1,101 @@
|
||||
apiVersion: apiextensions.crossplane.io/v1
|
||||
kind: CompositeResourceDefinition
|
||||
metadata:
|
||||
name: virtualmachines.proxmox.yourorg.io
|
||||
spec:
|
||||
group: proxmox.yourorg.io
|
||||
names:
|
||||
kind: VirtualMachine
|
||||
plural: virtualmachines
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
referenceable: true
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
type: object
|
||||
properties:
|
||||
spec:
|
||||
type: object
|
||||
properties:
|
||||
parameters:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: Name of the virtual machine
|
||||
node:
|
||||
type: string
|
||||
description: Proxmox node to deploy on
|
||||
cpu:
|
||||
type: integer
|
||||
description: Number of CPU cores
|
||||
default: 2
|
||||
memory:
|
||||
type: string
|
||||
description: Memory in GB (e.g., "4Gi")
|
||||
default: "4Gi"
|
||||
disk:
|
||||
type: string
|
||||
description: Disk size (e.g., "50Gi")
|
||||
default: "50Gi"
|
||||
storage:
|
||||
type: string
|
||||
description: Storage pool name
|
||||
default: "local-lvm"
|
||||
network:
|
||||
type: string
|
||||
description: Network bridge
|
||||
default: "vmbr0"
|
||||
image:
|
||||
type: string
|
||||
description: OS image template
|
||||
default: "ubuntu-22.04-cloud"
|
||||
site:
|
||||
type: string
|
||||
description: Proxmox site identifier
|
||||
required:
|
||||
- name
|
||||
- node
|
||||
- site
|
||||
required:
|
||||
- parameters
|
||||
status:
|
||||
type: object
|
||||
properties:
|
||||
vmId:
|
||||
type: integer
|
||||
state:
|
||||
type: string
|
||||
ipAddress:
|
||||
type: string
|
||||
conditions:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
status:
|
||||
type: string
|
||||
reason:
|
||||
type: string
|
||||
message:
|
||||
type: string
|
||||
additionalPrinterColumns:
|
||||
- name: VMID
|
||||
type: integer
|
||||
jsonPath: .status.vmId
|
||||
- name: STATE
|
||||
type: string
|
||||
jsonPath: .status.state
|
||||
- name: IP
|
||||
type: string
|
||||
jsonPath: .status.ipAddress
|
||||
- name: AGE
|
||||
type: date
|
||||
jsonPath: .metadata.creationTimestamp
|
||||
claimNames:
|
||||
kind: VirtualMachineClaim
|
||||
plural: virtualmachineclaims
|
||||
|
||||
22
gitops/overlays/dev/kustomization.yaml
Normal file
22
gitops/overlays/dev/kustomization.yaml
Normal file
@@ -0,0 +1,22 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
namespace: default
|
||||
|
||||
resources:
|
||||
- ../../base
|
||||
|
||||
patchesStrategicMerge:
|
||||
- patches/namespace-patch.yaml
|
||||
- patches/resource-limits-patch.yaml
|
||||
|
||||
configMapGenerator:
|
||||
- name: environment-config
|
||||
literals:
|
||||
- ENV=development
|
||||
- LOG_LEVEL=debug
|
||||
- REPLICAS=1
|
||||
|
||||
commonLabels:
|
||||
environment: development
|
||||
|
||||
7
gitops/overlays/dev/patches/namespace-patch.yaml
Normal file
7
gitops/overlays/dev/patches/namespace-patch.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: portal
|
||||
labels:
|
||||
environment: development
|
||||
|
||||
19
gitops/overlays/dev/patches/resource-limits-patch.yaml
Normal file
19
gitops/overlays/dev/patches/resource-limits-patch.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: portal
|
||||
namespace: portal
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: portal
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 256Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
|
||||
23
gitops/overlays/prod/kustomization.yaml
Normal file
23
gitops/overlays/prod/kustomization.yaml
Normal file
@@ -0,0 +1,23 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
namespace: default
|
||||
|
||||
resources:
|
||||
- ../../base
|
||||
|
||||
patchesStrategicMerge:
|
||||
- patches/namespace-patch.yaml
|
||||
- patches/resource-limits-patch.yaml
|
||||
- patches/high-availability-patch.yaml
|
||||
|
||||
configMapGenerator:
|
||||
- name: environment-config
|
||||
literals:
|
||||
- ENV=production
|
||||
- LOG_LEVEL=info
|
||||
- REPLICAS=3
|
||||
|
||||
commonLabels:
|
||||
environment: production
|
||||
|
||||
27
gitops/overlays/prod/patches/high-availability-patch.yaml
Normal file
27
gitops/overlays/prod/patches/high-availability-patch.yaml
Normal file
@@ -0,0 +1,27 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: portal
|
||||
namespace: portal
|
||||
spec:
|
||||
replicas: 3
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 0
|
||||
template:
|
||||
spec:
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- weight: 100
|
||||
podAffinityTerm:
|
||||
labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- portal
|
||||
topologyKey: kubernetes.io/hostname
|
||||
|
||||
7
gitops/overlays/prod/patches/namespace-patch.yaml
Normal file
7
gitops/overlays/prod/patches/namespace-patch.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: portal
|
||||
labels:
|
||||
environment: production
|
||||
|
||||
19
gitops/overlays/prod/patches/resource-limits-patch.yaml
Normal file
19
gitops/overlays/prod/patches/resource-limits-patch.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: portal
|
||||
namespace: portal
|
||||
spec:
|
||||
replicas: 3
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: portal
|
||||
resources:
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 4Gi
|
||||
|
||||
40
gitops/templates/cluster/k3s-cluster.yaml
Normal file
40
gitops/templates/cluster/k3s-cluster.yaml
Normal file
@@ -0,0 +1,40 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: "{{ .namespace }}"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: k3s-cluster-sa
|
||||
namespace: "{{ .namespace }}"
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: k3s-cluster-admin
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["*"]
|
||||
verbs: ["*"]
|
||||
- apiGroups: ["apps"]
|
||||
resources: ["*"]
|
||||
verbs: ["*"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: k3s-cluster-admin-binding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: k3s-cluster-admin
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: k3s-cluster-sa
|
||||
namespace: "{{ .namespace }}"
|
||||
---
|
||||
# This is a template for creating a k3s cluster via Crossplane
|
||||
# The actual implementation would use a Crossplane provider
|
||||
# to provision VMs and install k3s on them
|
||||
|
||||
19
gitops/templates/vm/debian-12.yaml
Normal file
19
gitops/templates/vm/debian-12.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
apiVersion: proxmox.yourorg.io/v1alpha1
|
||||
kind: VirtualMachineClaim
|
||||
metadata:
|
||||
name: "{{ .name }}"
|
||||
namespace: "{{ .namespace | default "default" }}"
|
||||
spec:
|
||||
compositionRef:
|
||||
name: virtualmachine.ubuntu.proxmox.yourorg.io
|
||||
parameters:
|
||||
name: "{{ .name }}"
|
||||
node: "{{ .node }}"
|
||||
cpu: {{ .cpu | default 2 }}
|
||||
memory: "{{ .memory | default "4Gi" }}"
|
||||
disk: "{{ .disk | default "50Gi" }}"
|
||||
storage: "{{ .storage | default "local-lvm" }}"
|
||||
network: "{{ .network | default "vmbr0" }}"
|
||||
image: "debian-12-cloud"
|
||||
site: "{{ .site }}"
|
||||
|
||||
19
gitops/templates/vm/ubuntu-20.04.yaml
Normal file
19
gitops/templates/vm/ubuntu-20.04.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
apiVersion: proxmox.yourorg.io/v1alpha1
|
||||
kind: VirtualMachineClaim
|
||||
metadata:
|
||||
name: "{{ .name }}"
|
||||
namespace: "{{ .namespace | default "default" }}"
|
||||
spec:
|
||||
compositionRef:
|
||||
name: virtualmachine.ubuntu.proxmox.yourorg.io
|
||||
parameters:
|
||||
name: "{{ .name }}"
|
||||
node: "{{ .node }}"
|
||||
cpu: {{ .cpu | default 2 }}
|
||||
memory: "{{ .memory | default "4Gi" }}"
|
||||
disk: "{{ .disk | default "50Gi" }}"
|
||||
storage: "{{ .storage | default "local-lvm" }}"
|
||||
network: "{{ .network | default "vmbr0" }}"
|
||||
image: "ubuntu-20.04-cloud"
|
||||
site: "{{ .site }}"
|
||||
|
||||
19
gitops/templates/vm/ubuntu-22.04.yaml
Normal file
19
gitops/templates/vm/ubuntu-22.04.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
apiVersion: proxmox.yourorg.io/v1alpha1
|
||||
kind: VirtualMachineClaim
|
||||
metadata:
|
||||
name: "{{ .name }}"
|
||||
namespace: "{{ .namespace | default "default" }}"
|
||||
spec:
|
||||
compositionRef:
|
||||
name: virtualmachine.ubuntu.proxmox.yourorg.io
|
||||
parameters:
|
||||
name: "{{ .name }}"
|
||||
node: "{{ .node }}"
|
||||
cpu: {{ .cpu | default 2 }}
|
||||
memory: "{{ .memory | default "4Gi" }}"
|
||||
disk: "{{ .disk | default "50Gi" }}"
|
||||
storage: "{{ .storage | default "local-lvm" }}"
|
||||
network: "{{ .network | default "vmbr0" }}"
|
||||
image: "ubuntu-22.04-cloud"
|
||||
site: "{{ .site }}"
|
||||
|
||||
Reference in New Issue
Block a user