Keycloak setup

This commit is contained in:
Astra Logical 2026-06-12 12:20:40 -04:00
parent ba83a95f08
commit d36431f7ef
6 changed files with 133 additions and 78 deletions

View file

@ -1,33 +1,35 @@
apiVersion: k8s.keycloak.org/v2beta1 apiVersion: apps/v1
kind: Keycloak kind: Deployment
metadata: metadata:
name: keycloak name: keycloak
namespace: default namespace: security
spec: spec:
instances: 1 replicas: 1
image: quay.io/keycloak/keycloak:latest selector:
startOptimized: false matchLabels:
db: app: keycloak
vendor: postgres template:
host: birdfeeder2.home.nest metadata:
port: 5432 labels:
database: keycloak app: keycloak
usernameSecret: spec:
name: keycloak-db-secret containers:
key: username - name: keycloak
passwordSecret: image: quay.io/keycloak/keycloak:24.0.0
name: keycloak-db-secret command: ["/bin/sh", "-c", "/opt/keycloak/bin/kc.sh start"]
key: password envFrom:
http: - secretRef:
httpEnabled: true name: keycloak-credentials
hostname: env:
hostname: sso.mynest.love - name: KC_HOSTNAME
strict: true value: "sso.mynest.love"
bootstrapAdmin: - name: KC_PROXY_HEADERS
user: value: "xforwarded"
secret: keycloak-admin-login - name: KC_HTTP_ENABLED
additionalOptions: value: "true"
- name: proxy-headers - name: KC_TRANSACTION_XA_ENABLED
value: xforwarded value: "false"
ingress: - name: KC_DB
enabled: false value: "postgres"
- name: KC_DB_URL
value: "jdbc:postgresql://keycloak-postgres:5432/keycloak"

View file

@ -1,45 +1,57 @@
apiVersion: external-secrets.io/v1 apiVersion: external-secrets.io/v1
kind: ExternalSecret kind: ExternalSecret
metadata: metadata:
name: keycloak-db-credentials name: keycloak-postgres-credentials
namespace: default namespace: security
spec: spec:
refreshInterval: "1h" refreshInterval: "1h"
secretStoreRef: secretStoreRef:
name: vault-external-secrets-store name: vault-external-secrets-store
kind: ClusterSecretStore kind: ClusterSecretStore
target: target:
name: keycloak-db-secret name: keycloak-postgres-credentials
creationPolicy: Owner creationPolicy: Owner
data: data:
- secretKey: username - secretKey: POSTGRES_USER
remoteRef: remoteRef:
key: keycloak/database key: keycloak
property: username property: db-user
- secretKey: password - secretKey: POSTGRES_PASSWORD
remoteRef: remoteRef:
key: keycloak/database key: keycloak
property: password property: db-password
- secretKey: POSTGRES_DB
remoteRef:
key: keycloak
property: db-name
--- ---
apiVersion: external-secrets.io/v1 apiVersion: external-secrets.io/v1
kind: ExternalSecret kind: ExternalSecret
metadata: metadata:
name: keycloak-admin-credentials name: keycloak-credentials
namespace: default namespace: security
spec: spec:
refreshInterval: "1h" refreshInterval: "1h"
secretStoreRef: secretStoreRef:
name: vault-external-secrets-store name: vault-external-secrets-store
kind: ClusterSecretStore kind: ClusterSecretStore
target: target:
name: keycloak-admin-login name: keycloak-credentials
creationPolicy: Owner creationPolicy: Owner
data: data:
- secretKey: username - secretKey: KC_DB_USERNAME
remoteRef: remoteRef:
key: keycloak/admin key: keycloak
property: username property: db-user
- secretKey: password - secretKey: KC_DB_PASSWORD
remoteRef: remoteRef:
key: keycloak/admin key: keycloak
property: password property: db-password
- secretKey: KEYCLOAK_ADMIN
remoteRef:
key: keycloak
property: admin-user
- secretKey: KEYCLOAK_ADMIN_PASSWORD
remoteRef:
key: keycloak
property: admin-password

View file

@ -1,25 +1,12 @@
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: keycloak-proxy-headers
namespace: default
spec:
headers:
customRequestHeaders:
X-Forwarded-Proto: "https"
---
apiVersion: networking.k8s.io/v1 apiVersion: networking.k8s.io/v1
kind: Ingress kind: Ingress
metadata: metadata:
name: keycloak-ingress name: keycloak-ingress
namespace: default namespace: security
annotations: annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod" cert-manager.io/cluster-issuer: "letsencrypt-prod"
traefik.ingress.kubernetes.io/router.entrypoints: websecure traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
traefik.ingress.kubernetes.io/router.middlewares: default-keycloak-proxy-headers@kubernetescrd
spec: spec:
ingressClassName: traefik
tls: tls:
- hosts: - hosts:
- sso.mynest.love - sso.mynest.love
@ -32,6 +19,6 @@ spec:
pathType: Prefix pathType: Prefix
backend: backend:
service: service:
name: keycloak-service name: keycloak
port: port:
number: 8080 number: 8080

View file

@ -0,0 +1,44 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: keycloak-postgres
namespace: security
spec:
replicas: 1
selector:
matchLabels:
app: keycloak-postgres
template:
metadata:
labels:
app: keycloak-postgres
spec:
containers:
- name: postgres
image: postgres:15-alpine
envFrom:
- secretRef:
name: keycloak-postgres-credentials
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
subPath: postgres-data
volumes:
- name: data
persistentVolumeClaim:
claimName: keycloak-db-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: keycloak-db-pvc
namespace: security
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job-group.longhorn.io/critical-data: "enabled"
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "longhorn"
resources:
requests:
storage: 5Gi

View file

@ -1,15 +0,0 @@
apiVersion: k8s.keycloak.org/v2alpha1
kind: KeycloakRealmImport
metadata:
name: keycloak-realm
namespace: default
spec:
keycloakCRName: keycloak
realm:
id: nest
realm: nest
enabled: true
displayName: "Nest SSO"
# You will eventually dump your full JSON realm export here
# clients: [...]
# users: [...]

View file

@ -0,0 +1,25 @@
apiVersion: v1
kind: Service
metadata:
name: keycloak
namespace: security
spec:
selector:
app: keycloak
ports:
- protocol: TCP
port: 8080
targetPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: keycloak-postgres
namespace: security
spec:
selector:
app: keycloak-postgres
ports:
- protocol: TCP
port: 5432
targetPort: 5432