feat: revamp and use single namespace and update to latest versions
This commit is contained in:
@@ -5,7 +5,6 @@ import { Construct } from "constructs";
|
|||||||
|
|
||||||
type AuthentikServerOptions = {
|
type AuthentikServerOptions = {
|
||||||
provider: HelmProvider;
|
provider: HelmProvider;
|
||||||
version: string;
|
|
||||||
name: string;
|
name: string;
|
||||||
namespace: string;
|
namespace: string;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,25 +3,25 @@ apiVersion: v1
|
|||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
metadata:
|
metadata:
|
||||||
name: cloudflare-domains-config
|
name: cloudflare-domains-config
|
||||||
namespace: cloudflare-system
|
namespace: homelab
|
||||||
data:
|
data:
|
||||||
DOMAINS: "auth.dogar.dev,grafana.dogar.dev,vpn.dogar.dev"
|
DOMAINS: "auth.dogar.dev,grafana.dogar.dev"
|
||||||
PROXIED: "true"
|
PROXIED: "true"
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
metadata:
|
metadata:
|
||||||
name: cloudflare-domains-config-non-proxied
|
name: cloudflare-domains-config-non-proxied
|
||||||
namespace: cloudflare-system
|
namespace: homelab
|
||||||
data:
|
data:
|
||||||
DOMAINS: "postgres.dogar.dev"
|
DOMAINS: "dogar.dev,git.dogar.dev"
|
||||||
PROXIED: "false"
|
PROXIED: "false"
|
||||||
---
|
---
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: cloudflare-ddns
|
name: cloudflare-ddns
|
||||||
namespace: cloudflare-system
|
namespace: homelab
|
||||||
spec:
|
spec:
|
||||||
replicas: 1
|
replicas: 1
|
||||||
selector:
|
selector:
|
||||||
@@ -40,7 +40,7 @@ spec:
|
|||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: cloudflare-token
|
name: cloudflare-token
|
||||||
key: credential
|
key: token
|
||||||
- name: DOMAINS
|
- name: DOMAINS
|
||||||
valueFrom:
|
valueFrom:
|
||||||
configMapKeyRef:
|
configMapKeyRef:
|
||||||
@@ -55,7 +55,7 @@ apiVersion: apps/v1
|
|||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: cloudflare-ddns-non-proxied
|
name: cloudflare-ddns-non-proxied
|
||||||
namespace: cloudflare-system
|
namespace: homelab
|
||||||
spec:
|
spec:
|
||||||
replicas: 1
|
replicas: 1
|
||||||
selector:
|
selector:
|
||||||
@@ -74,7 +74,7 @@ spec:
|
|||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: cloudflare-token
|
name: cloudflare-token
|
||||||
key: credential
|
key: token
|
||||||
- name: DOMAINS
|
- name: DOMAINS
|
||||||
valueFrom:
|
valueFrom:
|
||||||
configMapKeyRef:
|
configMapKeyRef:
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { Construct } from "constructs";
|
|||||||
|
|
||||||
type GiteaServerOptions = {
|
type GiteaServerOptions = {
|
||||||
provider: HelmProvider;
|
provider: HelmProvider;
|
||||||
version: string;
|
|
||||||
name: string;
|
name: string;
|
||||||
namespace: string;
|
namespace: string;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,17 +1,86 @@
|
|||||||
global:
|
global:
|
||||||
addPrometheusAnnotations: true
|
addPrometheusAnnotations: true
|
||||||
|
securityContext:
|
||||||
|
runAsUser: 1000
|
||||||
|
fsGroup: 1000
|
||||||
|
env:
|
||||||
|
- name: AUTHENTIK_SECRET_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: authentik-secret-key
|
||||||
|
key: password
|
||||||
|
- name: AUTHENTIK_EMAIL__USERNAME
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: smtp-token
|
||||||
|
key: authentik-username
|
||||||
|
- name: AUTHENTIK_EMAIL__PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: smtp-token
|
||||||
|
key: authentik-password
|
||||||
|
- name: AUTHENTIK_EMAIL__FROM
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: smtp-token
|
||||||
|
key: authentik-username
|
||||||
|
- name: AUTHENTIK_EMAIL__USE_TLS
|
||||||
|
value: "true"
|
||||||
|
- name: AUTHENTIK_POSTGRESQL__USER
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: authentik-postgres
|
||||||
|
key: username
|
||||||
|
- name: AUTHENTIK_POSTGRESQL__NAME
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: authentik-postgres
|
||||||
|
key: database
|
||||||
|
- name: AUTHENTIK_POSTGRESQL__SSLMODE
|
||||||
|
value: verify-full
|
||||||
|
- name: AUTHENTIK_POSTGRESQL__SSLROOTCERT
|
||||||
|
value: "/opt/authentik/certs/ca.crt"
|
||||||
|
- name: AUTHENTIK_POSTGRESQL__SSLCERT
|
||||||
|
value: "/opt/authentik/certs/tls.crt"
|
||||||
|
- name: AUTHENTIK_POSTGRESQL__SSLKEY
|
||||||
|
value: "/opt/authentik/certs/tls.key"
|
||||||
|
- name: AUTHENTIK_REDIS__PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: valkey
|
||||||
|
key: password
|
||||||
|
volumes:
|
||||||
|
- name: ssl-bundle
|
||||||
|
projected:
|
||||||
|
sources:
|
||||||
|
- secret:
|
||||||
|
name: authentik-client-cert
|
||||||
|
items:
|
||||||
|
- key: tls.crt
|
||||||
|
path: tls.crt
|
||||||
|
- key: tls.key
|
||||||
|
path: tls.key
|
||||||
|
mode: 0600
|
||||||
|
- secret:
|
||||||
|
name: postgres-server-cert
|
||||||
|
items:
|
||||||
|
- key: ca.crt
|
||||||
|
path: ca.crt
|
||||||
|
volumeMounts:
|
||||||
|
- name: ssl-bundle
|
||||||
|
mountPath: /opt/authentik/certs
|
||||||
|
readOnly: true
|
||||||
|
|
||||||
authentik:
|
authentik:
|
||||||
secret_key: "c8cc2e4a498c697a0443d96b31fe042c69c2158dc8bfb3da3878d1dbfbe6128e"
|
|
||||||
error_reporting:
|
error_reporting:
|
||||||
enabled: false
|
enabled: false
|
||||||
|
email:
|
||||||
|
host: "smtp.protonmail.ch"
|
||||||
|
port: 587
|
||||||
postgresql:
|
postgresql:
|
||||||
host: postgres-cluster-rw.postgres-system.svc.cluster.local
|
host: postgres-cluster-rw
|
||||||
user: file:///postgres-creds/username
|
|
||||||
password: file:///postgres-creds/password
|
|
||||||
redis:
|
redis:
|
||||||
host: redis-master.redis-system.svc.cluster.local
|
host: valkey
|
||||||
password: file:///redis-creds/password
|
|
||||||
|
|
||||||
server:
|
server:
|
||||||
replicas: 3
|
replicas: 3
|
||||||
@@ -21,45 +90,20 @@ server:
|
|||||||
cert-manager.io/cluster-issuer: cloudflare-issuer
|
cert-manager.io/cluster-issuer: cloudflare-issuer
|
||||||
cert-manager.io/acme-challenge-type: dns01
|
cert-manager.io/acme-challenge-type: dns01
|
||||||
cert-manager.io/private-key-size: "4096"
|
cert-manager.io/private-key-size: "4096"
|
||||||
|
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
|
||||||
|
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
||||||
|
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||||
ingressClassName: nginx-internal
|
ingressClassName: nginx-internal
|
||||||
|
https: true
|
||||||
hosts:
|
hosts:
|
||||||
- auth.dogar.dev
|
- auth.dogar.dev
|
||||||
- auth.rihla.digital
|
|
||||||
tls:
|
tls:
|
||||||
- secretName: authentik-tls
|
- secretName: authentik-tls
|
||||||
hosts:
|
hosts:
|
||||||
- auth.dogar.dev
|
- auth.dogar.dev
|
||||||
- auth.rihla.digital
|
|
||||||
volumes:
|
|
||||||
- name: postgres-creds
|
|
||||||
secret:
|
|
||||||
secretName: authentik-postgres
|
|
||||||
- name: redis-creds
|
|
||||||
secret:
|
|
||||||
secretName: authentik-redis
|
|
||||||
volumeMounts:
|
|
||||||
- name: postgres-creds
|
|
||||||
mountPath: /postgres-creds
|
|
||||||
readOnly: true
|
|
||||||
- name: redis-creds
|
|
||||||
mountPath: /redis-creds
|
|
||||||
readOnly: true
|
|
||||||
worker:
|
worker:
|
||||||
replicas: 3
|
replicas: 3
|
||||||
volumes:
|
|
||||||
- name: postgres-creds
|
|
||||||
secret:
|
|
||||||
secretName: authentik-postgres
|
|
||||||
- name: redis-creds
|
|
||||||
secret:
|
|
||||||
secretName: authentik-redis
|
|
||||||
volumeMounts:
|
|
||||||
- name: postgres-creds
|
|
||||||
mountPath: /postgres-creds
|
|
||||||
readOnly: true
|
|
||||||
- name: redis-creds
|
|
||||||
mountPath: /redis-creds
|
|
||||||
readOnly: true
|
|
||||||
|
|
||||||
postgresql:
|
postgresql:
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ provider: pihole
|
|||||||
policy: upsert-only
|
policy: upsert-only
|
||||||
txtOwnerId: "homelab"
|
txtOwnerId: "homelab"
|
||||||
pihole:
|
pihole:
|
||||||
server: http://pihole-web.pihole-system.svc.cluster.local
|
server: http://pihole-web
|
||||||
extraEnvVars:
|
extraEnvVars:
|
||||||
- name: EXTERNAL_DNS_PIHOLE_PASSWORD
|
- name: EXTERNAL_DNS_PIHOLE_PASSWORD
|
||||||
valueFrom:
|
valueFrom:
|
||||||
|
|||||||
@@ -1,22 +1,34 @@
|
|||||||
|
global:
|
||||||
|
storageClass: longhorn-crypto
|
||||||
|
image:
|
||||||
|
rootless: false
|
||||||
service:
|
service:
|
||||||
http:
|
http:
|
||||||
annotations:
|
annotations:
|
||||||
metallb.universe.tf/allow-shared-ip: gitea
|
metallb.universe.tf/allow-shared-ip: gitea
|
||||||
|
port: 443
|
||||||
|
targetPort: 443
|
||||||
ssh:
|
ssh:
|
||||||
annotations:
|
annotations:
|
||||||
metallb.universe.tf/allow-shared-ip: gitea
|
metallb.universe.tf/allow-shared-ip: gitea
|
||||||
ingress:
|
ingress:
|
||||||
enabled: true
|
enabled: true
|
||||||
className: nginx-internal
|
|
||||||
annotations:
|
annotations:
|
||||||
|
kubernetes.io/ingress.class: nginx-internal
|
||||||
cert-manager.io/cluster-issuer: cloudflare-issuer
|
cert-manager.io/cluster-issuer: cloudflare-issuer
|
||||||
cert-manager.io/acme-challenge-type: dns01
|
cert-manager.io/acme-challenge-type: dns01
|
||||||
cert-manager.io/private-key-size: "4096"
|
cert-manager.io/private-key-size: "4096"
|
||||||
|
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
|
||||||
hosts:
|
hosts:
|
||||||
- host: git.dogar.dev
|
- host: git.dogar.dev
|
||||||
paths:
|
paths:
|
||||||
- path: /
|
- path: /
|
||||||
pathType: Prefix
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: gitea-http
|
||||||
|
port:
|
||||||
|
number: 443
|
||||||
tls:
|
tls:
|
||||||
- secretName: gitea-tls
|
- secretName: gitea-tls
|
||||||
hosts:
|
hosts:
|
||||||
@@ -37,19 +49,23 @@ gitea:
|
|||||||
ENABLE_GZIP: true
|
ENABLE_GZIP: true
|
||||||
LFS_START_SERVER: true
|
LFS_START_SERVER: true
|
||||||
SSH_DOMAIN: git.dogar.dev
|
SSH_DOMAIN: git.dogar.dev
|
||||||
|
HTTP_PORT: 443
|
||||||
|
PROTOCOL: https
|
||||||
|
CERT_FILE: /opt/gitea/tls/cert.pem
|
||||||
|
KEY_FILE: /opt/gitea/tls/key.pem
|
||||||
database:
|
database:
|
||||||
DB_TYPE: postgres
|
DB_TYPE: postgres
|
||||||
HOST: postgres-cluster-rw.postgres-system.svc.cluster.local:5432
|
HOST: postgres-cluster-rw
|
||||||
NAME: gitea
|
NAME: gitea
|
||||||
USER: gitea
|
USER: gitea
|
||||||
|
SSL_MODE: require
|
||||||
cache:
|
cache:
|
||||||
ADAPTER: memcache
|
ADAPTER: memory
|
||||||
HOST: memcached.memcached-system.svc.cluster.local:11211
|
|
||||||
session:
|
session:
|
||||||
PROVIDER: db
|
PROVIDER: db
|
||||||
PROVIDER_CONFIG: ""
|
PROVIDER_CONFIG: ""
|
||||||
queue:
|
queue:
|
||||||
TYPE: redis
|
TYPE: channel
|
||||||
lfs:
|
lfs:
|
||||||
STORAGE_TYPE: local
|
STORAGE_TYPE: local
|
||||||
service:
|
service:
|
||||||
@@ -69,27 +85,76 @@ gitea:
|
|||||||
iconUrl: "https://goauthentik.io/img/icon.png"
|
iconUrl: "https://goauthentik.io/img/icon.png"
|
||||||
scopes: "email profile"
|
scopes: "email profile"
|
||||||
additionalConfigFromEnvs:
|
additionalConfigFromEnvs:
|
||||||
- name: GITEA__DATABASE__PASSWD
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: gitea-postgres
|
|
||||||
key: password
|
|
||||||
- name: GITEA__QUEUE__CONN_STR
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: gitea-redis
|
|
||||||
key: password
|
|
||||||
- name: GITEA__MAILER__PASSWD
|
- name: GITEA__MAILER__PASSWD
|
||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: smtp-token
|
name: smtp-token
|
||||||
key: password
|
key: gitea-password
|
||||||
|
livenessProbe:
|
||||||
|
enabled: true
|
||||||
|
tcpSocket:
|
||||||
|
port: 443
|
||||||
|
readinessProbe:
|
||||||
|
enabled: true
|
||||||
|
tcpSocket:
|
||||||
|
port: 443
|
||||||
|
startupProbe:
|
||||||
|
enabled: true
|
||||||
|
tcpSocket:
|
||||||
|
port: 443
|
||||||
persistence:
|
persistence:
|
||||||
enabled: true
|
enabled: true
|
||||||
storageClass: longhorn-crypto
|
|
||||||
accessModes:
|
accessModes:
|
||||||
- ReadWriteMany
|
- ReadWriteMany
|
||||||
|
deployment:
|
||||||
|
env:
|
||||||
|
- name: PGSSLMODE
|
||||||
|
value: verify-full
|
||||||
|
- name: PGSSLROOTCERT
|
||||||
|
value: /opt/gitea/.postgresql/root.crt
|
||||||
|
- name: PGSSLCERT
|
||||||
|
value: /opt/gitea/.postgresql/postgresql.crt
|
||||||
|
- name: PGSSLKEY
|
||||||
|
value: /opt/gitea/.postgresql/postgresql.key
|
||||||
|
extraVolumes:
|
||||||
|
- name: ssl-bundle
|
||||||
|
projected:
|
||||||
|
sources:
|
||||||
|
- secret:
|
||||||
|
name: gitea-client-cert
|
||||||
|
items:
|
||||||
|
- key: tls.crt
|
||||||
|
path: postgresql.crt
|
||||||
|
- key: tls.key
|
||||||
|
path: postgresql.key
|
||||||
|
mode: 0600
|
||||||
|
- secret:
|
||||||
|
name: postgres-server-cert
|
||||||
|
items:
|
||||||
|
- key: ca.crt
|
||||||
|
path: root.crt
|
||||||
|
- name: tls-bundle
|
||||||
|
projected:
|
||||||
|
sources:
|
||||||
|
- secret:
|
||||||
|
name: gitea-tls
|
||||||
|
items:
|
||||||
|
- key: tls.crt
|
||||||
|
path: cert.pem
|
||||||
|
- key: tls.key
|
||||||
|
path: key.pem
|
||||||
|
extraInitVolumeMounts:
|
||||||
|
- name: ssl-bundle
|
||||||
|
mountPath: /opt/gitea/.postgresql
|
||||||
|
readOnly: true
|
||||||
|
extraContainerVolumeMounts:
|
||||||
|
- name: ssl-bundle
|
||||||
|
mountPath: /opt/gitea/.postgresql
|
||||||
|
readOnly: true
|
||||||
|
- name: tls-bundle
|
||||||
|
mountPath: /opt/gitea/tls
|
||||||
|
readOnly: true
|
||||||
postgresql-ha:
|
postgresql-ha:
|
||||||
enabled: false
|
enabled: false
|
||||||
redis-cluster:
|
valkey-cluster:
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
defaultSettings:
|
defaultSettings:
|
||||||
backupTarget: "s3://homelab-backups@apac/longhorn"
|
defaultReplicaCount: 2
|
||||||
backupTargetCredentialSecret: longhorn-backup
|
storageOverProvisioningPercentage: 100
|
||||||
backupCompressionMethod: "gzip"
|
backupCompressionMethod: "gzip"
|
||||||
backupConcurrentLimit: 4
|
defaultBackupStore:
|
||||||
|
backupTarget: "s3://homelab@auto/longhorn"
|
||||||
|
backupTargetCredentialSecret: cloudflare-token
|
||||||
metrics:
|
metrics:
|
||||||
serviceMonitor:
|
serviceMonitor:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
containerSecurityContext:
|
|
||||||
readOnlyRootFilesystem: false
|
|
||||||
service:
|
|
||||||
annotations:
|
|
||||||
external-dns.alpha.kubernetes.io/hostname: memcached.dogar.dev
|
|
||||||
metrics:
|
|
||||||
enabled: true
|
|
||||||
serviceMonitor:
|
|
||||||
enabled: true
|
|
||||||
interval: 10s
|
|
||||||
scrapeTimeout: 10s
|
|
||||||
@@ -6,12 +6,6 @@ controller:
|
|||||||
controllerValue: "k8s.io/ingress-nginx"
|
controllerValue: "k8s.io/ingress-nginx"
|
||||||
parameters: {}
|
parameters: {}
|
||||||
ingressClass: nginx-internal
|
ingressClass: nginx-internal
|
||||||
service:
|
|
||||||
annotations:
|
|
||||||
external-dns.alpha.kubernetes.io/hostname: "postgres.dogar.dev"
|
|
||||||
tcp:
|
tcp:
|
||||||
22: "gitea-system/gitea-ssh:22"
|
22: "homelab/gitea-ssh:22"
|
||||||
5432: "postgres-system/postgres-cluster-rw:5432"
|
25565: "minecraft/monifactory-server:25565"
|
||||||
6379: "redis-system/redis-master-0:6379"
|
|
||||||
11211: "memcached-system/memcached:11211"
|
|
||||||
35432: "rihla/postgres-cluster-rw:5432"
|
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ DNS1:
|
|||||||
1.1.1.1
|
1.1.1.1
|
||||||
DNS2:
|
DNS2:
|
||||||
1.0.0.1
|
1.0.0.1
|
||||||
nodeSelector:
|
|
||||||
pihole: "true"
|
|
||||||
admin:
|
admin:
|
||||||
enabled: true
|
enabled: true
|
||||||
existingSecret: pihole-admin
|
existingSecret: pihole-admin
|
||||||
@@ -30,19 +28,16 @@ ingress:
|
|||||||
serviceWeb:
|
serviceWeb:
|
||||||
annotations:
|
annotations:
|
||||||
metallb.universe.tf/allow-shared-ip: pihole-svc
|
metallb.universe.tf/allow-shared-ip: pihole-svc
|
||||||
type: LoadBalancer
|
type: ClusterIP
|
||||||
loadBalancerIP: 192.168.18.250
|
https:
|
||||||
|
enabled: false
|
||||||
serviceDns:
|
serviceDns:
|
||||||
annotations:
|
annotations:
|
||||||
metallb.universe.tf/allow-shared-ip: pihole-svc
|
metallb.universe.tf/allow-shared-ip: pihole-svc
|
||||||
type: LoadBalancer
|
type: LoadBalancer
|
||||||
loadBalancerIP: 192.168.18.250
|
loadBalancerIP: 192.168.18.250
|
||||||
serviceDhcp:
|
serviceDhcp:
|
||||||
annotations:
|
enabled: false
|
||||||
metallb.universe.tf/allow-shared-ip: pihole-svc
|
|
||||||
enabled: true
|
|
||||||
type: LoadBalancer
|
|
||||||
loadBalancerIP: 192.168.18.250
|
|
||||||
probes:
|
probes:
|
||||||
liveness:
|
liveness:
|
||||||
enabled: false
|
enabled: false
|
||||||
@@ -55,7 +50,6 @@ dnsmasq:
|
|||||||
- dhcp-host=B0:41:6F:0F:A0:CD,192.168.18.12,homelab-2
|
- dhcp-host=B0:41:6F:0F:A0:CD,192.168.18.12,homelab-2
|
||||||
hostNetwork: true
|
hostNetwork: true
|
||||||
hostname: pihole
|
hostname: pihole
|
||||||
privileged: true
|
|
||||||
capabilities:
|
capabilities:
|
||||||
add:
|
add:
|
||||||
- NET_ADMIN
|
- NET_ADMIN
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
architecture: standalone
|
|
||||||
|
|
||||||
auth:
|
|
||||||
enabled: true
|
|
||||||
sentinel: true
|
|
||||||
existingSecret: redis
|
|
||||||
existingSecretPasswordKey: password
|
|
||||||
|
|
||||||
master:
|
|
||||||
persistence:
|
|
||||||
enabled: false
|
|
||||||
service:
|
|
||||||
type: LoadBalancer
|
|
||||||
annotations:
|
|
||||||
external-dns.alpha.kubernetes.io/hostname: redis.dogar.dev
|
|
||||||
|
|
||||||
replica:
|
|
||||||
replicaCount: 0
|
|
||||||
persistence:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
sentinel:
|
|
||||||
enabled: false
|
|
||||||
@@ -3,7 +3,7 @@ apiVersion: metallb.io/v1beta1
|
|||||||
kind: IPAddressPool
|
kind: IPAddressPool
|
||||||
metadata:
|
metadata:
|
||||||
name: pool
|
name: pool
|
||||||
namespace: metallb-system
|
namespace: homelab
|
||||||
spec:
|
spec:
|
||||||
addresses:
|
addresses:
|
||||||
- 192.168.18.192/26
|
- 192.168.18.192/26
|
||||||
@@ -12,7 +12,7 @@ apiVersion: metallb.io/v1beta1
|
|||||||
kind: L2Advertisement
|
kind: L2Advertisement
|
||||||
metadata:
|
metadata:
|
||||||
name: pool
|
name: pool
|
||||||
namespace: metallb-system
|
namespace: homelab
|
||||||
spec:
|
spec:
|
||||||
ipAddressPools:
|
ipAddressPools:
|
||||||
- pool
|
- pool
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ type LonghornOptions = {
|
|||||||
kubernetes: KubernetesProvider;
|
kubernetes: KubernetesProvider;
|
||||||
helm: HelmProvider;
|
helm: HelmProvider;
|
||||||
};
|
};
|
||||||
version: string;
|
|
||||||
name: string;
|
name: string;
|
||||||
namespace: string;
|
namespace: string;
|
||||||
};
|
};
|
||||||
@@ -24,11 +23,11 @@ export class Longhorn extends Construct {
|
|||||||
new Release(this, id, {
|
new Release(this, id, {
|
||||||
name: options.name,
|
name: options.name,
|
||||||
namespace: options.namespace,
|
namespace: options.namespace,
|
||||||
version: options.version,
|
|
||||||
provider: helm,
|
provider: helm,
|
||||||
repository: "https://charts.longhorn.io",
|
repository: "https://charts.longhorn.io",
|
||||||
chart: "longhorn",
|
chart: "longhorn",
|
||||||
createNamespace: true,
|
createNamespace: true,
|
||||||
|
upgradeInstall: true,
|
||||||
values: [
|
values: [
|
||||||
fs.readFileSync("helm/values/longhorn.values.yaml", {
|
fs.readFileSync("helm/values/longhorn.values.yaml", {
|
||||||
encoding: "utf8",
|
encoding: "utf8",
|
||||||
@@ -36,6 +35,25 @@ export class Longhorn extends Construct {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
new Manifest(this, "recurring-backup-job", {
|
||||||
|
provider: kubernetes,
|
||||||
|
manifest: {
|
||||||
|
apiVersion: "longhorn.io/v1beta1",
|
||||||
|
kind: "RecurringJob",
|
||||||
|
metadata: {
|
||||||
|
name: "daily-backup",
|
||||||
|
namespace: options.namespace,
|
||||||
|
},
|
||||||
|
spec: {
|
||||||
|
cron: "0 0 * * *",
|
||||||
|
task: "backup",
|
||||||
|
retain: 30,
|
||||||
|
groups: ["default"],
|
||||||
|
concurrency: 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
new Manifest(this, "longhorn-crypto-storage-class", {
|
new Manifest(this, "longhorn-crypto-storage-class", {
|
||||||
provider: kubernetes,
|
provider: kubernetes,
|
||||||
manifest: {
|
manifest: {
|
||||||
|
|||||||
107
main.ts
107
main.ts
@@ -10,11 +10,10 @@ import { OnePassword } from "./1password";
|
|||||||
import { PostgresCluster } from "./postgres";
|
import { PostgresCluster } from "./postgres";
|
||||||
import { Longhorn } from "./longhorn";
|
import { Longhorn } from "./longhorn";
|
||||||
import { AuthentikServer } from "./authentik";
|
import { AuthentikServer } from "./authentik";
|
||||||
import { RedisCluster } from "./redis";
|
import { ValkeyCluster } from "./valkey";
|
||||||
import { CertManager } from "./cert-manager";
|
import { CertManager } from "./cert-manager";
|
||||||
import { Manifest } from "@cdktf/provider-kubernetes/lib/manifest";
|
import { Manifest } from "@cdktf/provider-kubernetes/lib/manifest";
|
||||||
import { PiHole } from "./pihole";
|
import { PiHole } from "./pihole";
|
||||||
import { MemcachedCluster } from "./memcached";
|
|
||||||
import { Nginx } from "./nginx";
|
import { Nginx } from "./nginx";
|
||||||
import { Prometheus } from "./prometheus";
|
import { Prometheus } from "./prometheus";
|
||||||
import { MetalLB } from "./metallb";
|
import { MetalLB } from "./metallb";
|
||||||
@@ -28,6 +27,8 @@ const env = cleanEnv(process.env, {
|
|||||||
BUCKET: str({ desc: "The name of the R2 bucket." }),
|
BUCKET: str({ desc: "The name of the R2 bucket." }),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const r2Endpoint = `https://${env.ACCOUNT_ID}.r2.cloudflarestorage.com`;
|
||||||
|
|
||||||
class Homelab extends TerraformStack {
|
class Homelab extends TerraformStack {
|
||||||
constructor(scope: Construct, id: string) {
|
constructor(scope: Construct, id: string) {
|
||||||
super(scope, id);
|
super(scope, id);
|
||||||
@@ -42,13 +43,15 @@ class Homelab extends TerraformStack {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
new Manifest(this, "namespace", {
|
const namespace = "homelab";
|
||||||
|
|
||||||
|
const ns = new Manifest(this, "namespace", {
|
||||||
provider: kubernetes,
|
provider: kubernetes,
|
||||||
manifest: {
|
manifest: {
|
||||||
kind: "Namespace",
|
kind: "Namespace",
|
||||||
apiVersion: "v1",
|
apiVersion: "v1",
|
||||||
metadata: {
|
metadata: {
|
||||||
name: "homelab",
|
name: namespace,
|
||||||
},
|
},
|
||||||
spec: {},
|
spec: {},
|
||||||
},
|
},
|
||||||
@@ -72,54 +75,40 @@ class Homelab extends TerraformStack {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
new Longhorn(this, "longhorn", {
|
const longhorn = new Longhorn(this, "longhorn", {
|
||||||
namespace: "longhorn-system",
|
namespace,
|
||||||
name: "longhorn",
|
name: "longhorn",
|
||||||
version: "1.8.2",
|
|
||||||
providers: {
|
providers: {
|
||||||
kubernetes,
|
kubernetes,
|
||||||
helm,
|
helm,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
longhorn.node.addDependency(ns);
|
||||||
|
|
||||||
new MetalLB(this, "metallb", {
|
new MetalLB(this, "metallb", {
|
||||||
provider: helm,
|
provider: helm,
|
||||||
name: "metallb",
|
name: "metallb",
|
||||||
namespace: "metallb-system",
|
namespace,
|
||||||
version: "0.15.2",
|
|
||||||
});
|
});
|
||||||
|
|
||||||
new OnePassword(this, "one-password", {
|
new OnePassword(this, "one-password", {
|
||||||
provider: kubernetes,
|
provider: kubernetes,
|
||||||
|
namespace,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Nginx(this, "nginx", {
|
const nginx = new Nginx(this, "nginx", {
|
||||||
provider: helm,
|
provider: helm,
|
||||||
namespace: "nginx-system",
|
namespace,
|
||||||
name: "ingress-nginx-internal",
|
name: "nginx-ingress",
|
||||||
version: "4.13.0",
|
|
||||||
});
|
|
||||||
|
|
||||||
new PiHole(this, "pihole", {
|
|
||||||
namespace: "pihole-system",
|
|
||||||
provider: helm,
|
|
||||||
name: "pihole",
|
|
||||||
version: "2.26.1",
|
|
||||||
});
|
|
||||||
|
|
||||||
new Prometheus(this, "prometheus", {
|
|
||||||
provider: helm,
|
|
||||||
namespace: "prometheus-system",
|
|
||||||
name: "prometheus-operator",
|
|
||||||
version: "75.10.0",
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const certManagerApiVersion = "cert-manager.io/v1";
|
const certManagerApiVersion = "cert-manager.io/v1";
|
||||||
|
|
||||||
new CertManager(this, "cert-manager", {
|
const cm = new CertManager(this, "cert-manager", {
|
||||||
certManagerApiVersion,
|
certManagerApiVersion,
|
||||||
name: "cert-manager",
|
name: "cert-manager",
|
||||||
namespace: "cert-manager",
|
namespace,
|
||||||
version: "1.18.2",
|
version: "1.18.2",
|
||||||
providers: {
|
providers: {
|
||||||
kubernetes,
|
kubernetes,
|
||||||
@@ -127,47 +116,64 @@ class Homelab extends TerraformStack {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
new PostgresCluster(this, "postgres-cluster", {
|
const pihole = new PiHole(this, "pihole", {
|
||||||
|
namespace,
|
||||||
|
provider: helm,
|
||||||
|
name: "pihole",
|
||||||
|
});
|
||||||
|
|
||||||
|
pihole.node.addDependency(longhorn);
|
||||||
|
pihole.node.addDependency(nginx);
|
||||||
|
pihole.node.addDependency(cm);
|
||||||
|
|
||||||
|
new Prometheus(this, "prometheus", {
|
||||||
|
provider: helm,
|
||||||
|
namespace,
|
||||||
|
name: "prometheus-operator",
|
||||||
|
version: "75.10.0",
|
||||||
|
});
|
||||||
|
|
||||||
|
const pg = new PostgresCluster(this, "postgres-cluster", {
|
||||||
certManagerApiVersion,
|
certManagerApiVersion,
|
||||||
version: "0.24.0",
|
|
||||||
name: "postgres-cluster",
|
name: "postgres-cluster",
|
||||||
namespace: "postgres-system",
|
namespace,
|
||||||
providers: {
|
providers: {
|
||||||
kubernetes,
|
kubernetes,
|
||||||
helm,
|
helm,
|
||||||
},
|
},
|
||||||
storageClass: "longhorn-crypto",
|
storageClass: "longhorn-crypto",
|
||||||
users: ["shahab", "budget-tracker"],
|
users: ["shahab", "budget-tracker", "authentik", "gitea"],
|
||||||
primaryUser: "shahab",
|
primaryUser: "shahab",
|
||||||
initSecretName: "postgres-password",
|
initSecretName: "postgres-password",
|
||||||
backupR2EndpointURL: `https://${env.ACCOUNT_ID}.r2.cloudflarestorage.com`,
|
backupR2EndpointURL: r2Endpoint,
|
||||||
});
|
});
|
||||||
|
|
||||||
new RedisCluster(this, "redis-cluster", {
|
pg.node.addDependency(pihole);
|
||||||
provider: helm,
|
|
||||||
namespace: "redis-system",
|
const valkey = new ValkeyCluster(this, "valkey-cluster", {
|
||||||
name: "redis",
|
provider: kubernetes,
|
||||||
|
namespace,
|
||||||
|
name: "valkey",
|
||||||
});
|
});
|
||||||
|
|
||||||
new MemcachedCluster(this, "memcached-cluster", {
|
valkey.node.addDependency(pihole);
|
||||||
provider: helm,
|
|
||||||
namespace: "memcached-system",
|
|
||||||
name: "memcached",
|
|
||||||
});
|
|
||||||
|
|
||||||
new AuthentikServer(this, "authentik-server", {
|
const authentik = new AuthentikServer(this, "authentik-server", {
|
||||||
provider: helm,
|
provider: helm,
|
||||||
name: "authentik",
|
name: "authentik",
|
||||||
namespace: "authentik-system",
|
namespace,
|
||||||
version: "2025.8.1",
|
|
||||||
});
|
});
|
||||||
|
|
||||||
new GiteaServer(this, "gitea-server", {
|
authentik.node.addDependency(pg);
|
||||||
|
authentik.node.addDependency(valkey);
|
||||||
|
|
||||||
|
const gitea = new GiteaServer(this, "gitea-server", {
|
||||||
name: "gitea",
|
name: "gitea",
|
||||||
namespace: "gitea-system",
|
namespace,
|
||||||
provider: helm,
|
provider: helm,
|
||||||
version: "12.1.1",
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
gitea.node.addDependency(authentik);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,6 +181,7 @@ const app = new App();
|
|||||||
const stack = new Homelab(app, "homelab");
|
const stack = new Homelab(app, "homelab");
|
||||||
|
|
||||||
new S3Backend(stack, {
|
new S3Backend(stack, {
|
||||||
|
encrypt: true,
|
||||||
bucket: env.BUCKET,
|
bucket: env.BUCKET,
|
||||||
key: "terraform.tfstate",
|
key: "terraform.tfstate",
|
||||||
region: "auto",
|
region: "auto",
|
||||||
@@ -186,7 +193,7 @@ new S3Backend(stack, {
|
|||||||
accessKey: env.R2_ACCESS_KEY_ID,
|
accessKey: env.R2_ACCESS_KEY_ID,
|
||||||
secretKey: env.R2_SECRET_ACCESS_KEY,
|
secretKey: env.R2_SECRET_ACCESS_KEY,
|
||||||
endpoints: {
|
endpoints: {
|
||||||
s3: `https://${env.ACCOUNT_ID}.r2.cloudflarestorage.com/${env.BUCKET}`,
|
s3: `${r2Endpoint}/${env.BUCKET}`,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ type MetalLBOptions = {
|
|||||||
provider: HelmProvider;
|
provider: HelmProvider;
|
||||||
name: string;
|
name: string;
|
||||||
namespace: string;
|
namespace: string;
|
||||||
version: string;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export class MetalLB extends Construct {
|
export class MetalLB extends Construct {
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ type NginxOptions = {
|
|||||||
provider: HelmProvider;
|
provider: HelmProvider;
|
||||||
name: string;
|
name: string;
|
||||||
namespace: string;
|
namespace: string;
|
||||||
version: string;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export class Nginx extends Construct {
|
export class Nginx extends Construct {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { Construct } from "constructs";
|
|||||||
|
|
||||||
type PiHoleOptions = {
|
type PiHoleOptions = {
|
||||||
provider: HelmProvider;
|
provider: HelmProvider;
|
||||||
version: string;
|
|
||||||
name: string;
|
name: string;
|
||||||
namespace: string;
|
namespace: string;
|
||||||
};
|
};
|
||||||
@@ -18,7 +17,7 @@ export class PiHole extends Construct {
|
|||||||
...options,
|
...options,
|
||||||
repository: "https://mojo2600.github.io/pihole-kubernetes",
|
repository: "https://mojo2600.github.io/pihole-kubernetes",
|
||||||
chart: "pihole",
|
chart: "pihole",
|
||||||
createNamespace: true,
|
version: "2.26.1",
|
||||||
values: [
|
values: [
|
||||||
fs.readFileSync("helm/values/pihole.values.yaml", {
|
fs.readFileSync("helm/values/pihole.values.yaml", {
|
||||||
encoding: "utf8",
|
encoding: "utf8",
|
||||||
@@ -30,7 +29,7 @@ export class PiHole extends Construct {
|
|||||||
provider: options.provider,
|
provider: options.provider,
|
||||||
name: "externaldns-pihole",
|
name: "externaldns-pihole",
|
||||||
namespace: options.namespace,
|
namespace: options.namespace,
|
||||||
repository: "https://charts.bitnami.com/bitnami",
|
repository: "oci://registry-1.docker.io/bitnamicharts/",
|
||||||
chart: "external-dns",
|
chart: "external-dns",
|
||||||
values: [
|
values: [
|
||||||
fs.readFileSync("helm/values/externaldns.values.yaml", {
|
fs.readFileSync("helm/values/externaldns.values.yaml", {
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ type PostgresClusterOptions = {
|
|||||||
primaryUser: string;
|
primaryUser: string;
|
||||||
initSecretName: string;
|
initSecretName: string;
|
||||||
certManagerApiVersion: string;
|
certManagerApiVersion: string;
|
||||||
version: string;
|
|
||||||
backupR2EndpointURL: string;
|
backupR2EndpointURL: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -28,27 +27,27 @@ export class PostgresCluster extends Construct {
|
|||||||
|
|
||||||
new Release(this, "cnpg-operator", {
|
new Release(this, "cnpg-operator", {
|
||||||
provider: helm,
|
provider: helm,
|
||||||
version: options.version,
|
|
||||||
repository: "https://cloudnative-pg.github.io/charts",
|
repository: "https://cloudnative-pg.github.io/charts",
|
||||||
chart: "cloudnative-pg",
|
chart: "cloudnative-pg",
|
||||||
name: "postgres-system",
|
name: "postgres-system",
|
||||||
namespace: options.namespace,
|
namespace: "cnpg-system",
|
||||||
});
|
});
|
||||||
|
|
||||||
const destinationPath = "s3://homelab-backups/";
|
const destinationPath = "s3://homelab/";
|
||||||
|
|
||||||
const endpointURL = options.backupR2EndpointURL;
|
const endpointURL = options.backupR2EndpointURL;
|
||||||
|
const barmanStoreName = "r2-postgres-backup-store";
|
||||||
|
|
||||||
const barmanConfiguration = {
|
const barmanConfiguration = {
|
||||||
destinationPath,
|
destinationPath,
|
||||||
endpointURL,
|
endpointURL,
|
||||||
s3Credentials: {
|
s3Credentials: {
|
||||||
accessKeyId: {
|
accessKeyId: {
|
||||||
name: "cloudflare-r2-token",
|
name: "cloudflare-token",
|
||||||
key: "access_key",
|
key: "access_key_id",
|
||||||
},
|
},
|
||||||
secretAccessKey: {
|
secretAccessKey: {
|
||||||
name: "cloudflare-r2-token",
|
name: "cloudflare-token",
|
||||||
key: "secret_key",
|
key: "secret_access_key",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -60,7 +59,7 @@ export class PostgresCluster extends Construct {
|
|||||||
kind: "ObjectStore",
|
kind: "ObjectStore",
|
||||||
metadata: {
|
metadata: {
|
||||||
namespace: options.namespace,
|
namespace: options.namespace,
|
||||||
name: "r2-postgres-backup-store-homelab",
|
name: barmanStoreName,
|
||||||
},
|
},
|
||||||
spec: {
|
spec: {
|
||||||
configuration: {
|
configuration: {
|
||||||
@@ -178,9 +177,8 @@ export class PostgresCluster extends Construct {
|
|||||||
secretName: certNames.server,
|
secretName: certNames.server,
|
||||||
usages: ["server auth"],
|
usages: ["server auth"],
|
||||||
dnsNames: [
|
dnsNames: [
|
||||||
"postgres-cluster-rw.postgres-system.svc.cluster.local",
|
"postgres-cluster-rw",
|
||||||
"postgres-cluster-ro.postgres-system.svc.cluster.local",
|
"postgres-cluster-rw.homelab.svc.cluster.local",
|
||||||
"postgres-cluster-r.postgres-system.svc.cluster.local",
|
|
||||||
"postgres.dogar.dev",
|
"postgres.dogar.dev",
|
||||||
],
|
],
|
||||||
duration: "4380h", // 6 months
|
duration: "4380h", // 6 months
|
||||||
@@ -342,7 +340,7 @@ export class PostgresCluster extends Construct {
|
|||||||
enabled: true,
|
enabled: true,
|
||||||
isWALArchiver: true,
|
isWALArchiver: true,
|
||||||
parameters: {
|
parameters: {
|
||||||
barmanObjectName: "r2-postgres-backup-store",
|
barmanObjectName: barmanStoreName,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -396,7 +394,7 @@ export class PostgresCluster extends Construct {
|
|||||||
storageClass: options.storageClass,
|
storageClass: options.storageClass,
|
||||||
},
|
},
|
||||||
walStorage: {
|
walStorage: {
|
||||||
size: "10Gi",
|
size: "1Gi",
|
||||||
storageClass: options.storageClass,
|
storageClass: options.storageClass,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user