infrastructure/vaultwarden.yaml
Infrastructure Admin 0dee133377 Add Argo Workflows, mTLS container registry, and fix infrastructure
- Move Keycloak off Helm to plain Crossplane Object manifests (PostgreSQL + Keycloak deployment)
- Add Vaultwarden SSO/OIDC config with Keycloak, fix Recreate deployment strategy for RWO volumes
- Switch routing from Helm-based Pomerium to pomerium-allinone with all service routes
- Deploy Argo Workflows (controller, server, CRDs, RBAC) with KEDA queue-depth autoscaling
- Add Civo cluster autoscaler with pool-scaler for zero-to-one scale-up via Civo API
- Add node-labeler to auto-tag nodes by pool membership for nodeSelector scheduling
- Set up mTLS container registry at registry.nge6.com (Forgejo built-in, client cert required)
- Add internal registry route (registry-internal.nge6.com) for in-cluster image pulls
- Fix DNS records for new Emissary LB IP (212.2.241.28)
- Fix CoreDNS crash from invalid custom config
- Fix Emissary apiext expired webhook CA certificate

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 21:23:12 -04:00

250 lines
6.2 KiB
YAML

# Vaultwarden namespace
apiVersion: kubernetes.crossplane.io/v1alpha2
kind: Object
metadata:
name: vaultwarden-namespace
namespace: crossplane-system
spec:
providerConfigRef:
name: kubernetes-provider
forProvider:
manifest:
apiVersion: v1
kind: Namespace
metadata:
name: vaultwarden
---
# Vaultwarden ConfigMap
apiVersion: kubernetes.crossplane.io/v1alpha2
kind: Object
metadata:
name: vaultwarden-config
namespace: crossplane-system
spec:
providerConfigRef:
name: kubernetes-provider
forProvider:
manifest:
apiVersion: v1
kind: ConfigMap
metadata:
name: vaultwarden-config
namespace: vaultwarden
data:
DOMAIN: "https://vault.nge6.com"
WEBSOCKET_ENABLED: "true"
ROCKET_PORT: "8080"
ROCKET_WORKERS: "10"
# Security settings
INVITATIONS_ALLOWED: "true"
SIGNUPS_ALLOWED: "true"
SHOW_PASSWORD_HINT: "false"
# Email configuration (disabled)
# OIDC/SSO configuration
SSO_ENABLED: "true"
SSO_ONLY: "false"
SSO_CLIENT_ID: "vaultwarden"
SSO_CLIENT_SECRET: "zMeG3odq6GUBoYUVcoNl1CmngJpwgMS6"
SSO_AUTHORITY: "https://auth.nge6.com/realms/kubernetes-realm"
SSO_SCOPES: "openid email profile"
# SSO_MASTER_PASSWORD_POLICY removed - not valid in testing image
SSO_DOMAIN: "nge6.com"
SSO_ORGANIZATIONS_INVITE: "true"
# Admin settings
ADMIN_TOKEN: "vaultwarden-admin-token-change-in-production"
# Database (using SQLite for simplicity)
DATABASE_URL: "/data/db.sqlite3"
# File attachments
ATTACHMENTS_FOLDER: "/data/attachments"
# Icons
ICON_CACHE_FOLDER: "/data/icon_cache"
---
# Vaultwarden PVC for data persistence
apiVersion: kubernetes.crossplane.io/v1alpha2
kind: Object
metadata:
name: vaultwarden-data-pvc
namespace: crossplane-system
spec:
providerConfigRef:
name: kubernetes-provider
forProvider:
manifest:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: vaultwarden-data
namespace: vaultwarden
spec:
accessModes:
- ReadWriteOnce
storageClassName: civo-volume
resources:
requests:
storage: 10Gi
---
# Vaultwarden Deployment
apiVersion: kubernetes.crossplane.io/v1alpha2
kind: Object
metadata:
name: vaultwarden-deployment
namespace: crossplane-system
spec:
providerConfigRef:
name: kubernetes-provider
forProvider:
manifest:
apiVersion: apps/v1
kind: Deployment
metadata:
name: vaultwarden
namespace: vaultwarden
labels:
app: vaultwarden
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: vaultwarden
template:
metadata:
labels:
app: vaultwarden
spec:
containers:
- name: vaultwarden
image: vaultwarden/server:testing
ports:
- containerPort: 8080
name: http
- containerPort: 3012
name: websocket
envFrom:
- configMapRef:
name: vaultwarden-config
resources:
limits:
cpu: 500m
memory: 1Gi
requests:
cpu: 100m
memory: 256Mi
volumeMounts:
- name: data
mountPath: /data
readinessProbe:
httpGet:
path: /alive
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /alive
port: 8080
initialDelaySeconds: 30
periodSeconds: 30
volumes:
- name: data
persistentVolumeClaim:
claimName: vaultwarden-data
---
# Vaultwarden Service
apiVersion: kubernetes.crossplane.io/v1alpha2
kind: Object
metadata:
name: vaultwarden-service
namespace: crossplane-system
spec:
providerConfigRef:
name: kubernetes-provider
forProvider:
manifest:
apiVersion: v1
kind: Service
metadata:
name: vaultwarden-http
namespace: vaultwarden
labels:
app: vaultwarden
spec:
selector:
app: vaultwarden
ports:
- name: http
port: 8080
targetPort: 8080
- name: websocket
port: 3012
targetPort: 3012
type: ClusterIP
---
# SSL Certificate for Vaultwarden
apiVersion: kubernetes.crossplane.io/v1alpha2
kind: Object
metadata:
name: vaultwarden-certificate
namespace: crossplane-system
spec:
providerConfigRef:
name: kubernetes-provider
forProvider:
manifest:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: vaultwarden-tls
namespace: emissary
spec:
secretName: vaultwarden-tls
issuerRef:
name: letsencrypt-dns
kind: ClusterIssuer
dnsNames:
- vault.nge6.com
---
# Ambassador Host for Vaultwarden
apiVersion: kubernetes.crossplane.io/v1alpha2
kind: Object
metadata:
name: vaultwarden-host
namespace: crossplane-system
spec:
providerConfigRef:
name: kubernetes-provider
forProvider:
manifest:
apiVersion: getambassador.io/v3alpha1
kind: Host
metadata:
name: vaultwarden-host
namespace: emissary
spec:
hostname: vault.nge6.com
tlsSecret:
name: vaultwarden-tls
---
# Ambassador Mapping for Vaultwarden
apiVersion: kubernetes.crossplane.io/v1alpha2
kind: Object
metadata:
name: vaultwarden-mapping
namespace: crossplane-system
spec:
providerConfigRef:
name: kubernetes-provider
forProvider:
manifest:
apiVersion: getambassador.io/v3alpha1
kind: Mapping
metadata:
name: vaultwarden-mapping
namespace: emissary
spec:
hostname: vault.nge6.com
prefix: /
service: http://pomerium-allinone.pomerium:443
timeout_ms: 30000
connect_timeout_ms: 10000