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 = {
|
||||
provider: HelmProvider;
|
||||
version: string;
|
||||
name: string;
|
||||
namespace: string;
|
||||
};
|
||||
|
||||
@@ -3,25 +3,25 @@ apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: cloudflare-domains-config
|
||||
namespace: cloudflare-system
|
||||
namespace: homelab
|
||||
data:
|
||||
DOMAINS: "auth.dogar.dev,grafana.dogar.dev,vpn.dogar.dev"
|
||||
DOMAINS: "auth.dogar.dev,grafana.dogar.dev"
|
||||
PROXIED: "true"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: cloudflare-domains-config-non-proxied
|
||||
namespace: cloudflare-system
|
||||
namespace: homelab
|
||||
data:
|
||||
DOMAINS: "postgres.dogar.dev"
|
||||
DOMAINS: "dogar.dev,git.dogar.dev"
|
||||
PROXIED: "false"
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: cloudflare-ddns
|
||||
namespace: cloudflare-system
|
||||
namespace: homelab
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
@@ -40,7 +40,7 @@ spec:
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: cloudflare-token
|
||||
key: credential
|
||||
key: token
|
||||
- name: DOMAINS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
@@ -55,7 +55,7 @@ apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: cloudflare-ddns-non-proxied
|
||||
namespace: cloudflare-system
|
||||
namespace: homelab
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
@@ -74,7 +74,7 @@ spec:
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: cloudflare-token
|
||||
key: credential
|
||||
key: token
|
||||
- name: DOMAINS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
|
||||
@@ -5,7 +5,6 @@ import { Construct } from "constructs";
|
||||
|
||||
type GiteaServerOptions = {
|
||||
provider: HelmProvider;
|
||||
version: string;
|
||||
name: string;
|
||||
namespace: string;
|
||||
};
|
||||
|
||||
@@ -1,17 +1,86 @@
|
||||
global:
|
||||
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:
|
||||
secret_key: "c8cc2e4a498c697a0443d96b31fe042c69c2158dc8bfb3da3878d1dbfbe6128e"
|
||||
error_reporting:
|
||||
enabled: false
|
||||
email:
|
||||
host: "smtp.protonmail.ch"
|
||||
port: 587
|
||||
postgresql:
|
||||
host: postgres-cluster-rw.postgres-system.svc.cluster.local
|
||||
user: file:///postgres-creds/username
|
||||
password: file:///postgres-creds/password
|
||||
host: postgres-cluster-rw
|
||||
redis:
|
||||
host: redis-master.redis-system.svc.cluster.local
|
||||
password: file:///redis-creds/password
|
||||
host: valkey
|
||||
|
||||
server:
|
||||
replicas: 3
|
||||
@@ -21,45 +90,20 @@ server:
|
||||
cert-manager.io/cluster-issuer: cloudflare-issuer
|
||||
cert-manager.io/acme-challenge-type: dns01
|
||||
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
|
||||
https: true
|
||||
hosts:
|
||||
- auth.dogar.dev
|
||||
- auth.rihla.digital
|
||||
tls:
|
||||
- secretName: authentik-tls
|
||||
hosts:
|
||||
- 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:
|
||||
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:
|
||||
enabled: false
|
||||
|
||||
@@ -3,7 +3,7 @@ provider: pihole
|
||||
policy: upsert-only
|
||||
txtOwnerId: "homelab"
|
||||
pihole:
|
||||
server: http://pihole-web.pihole-system.svc.cluster.local
|
||||
server: http://pihole-web
|
||||
extraEnvVars:
|
||||
- name: EXTERNAL_DNS_PIHOLE_PASSWORD
|
||||
valueFrom:
|
||||
|
||||
@@ -1,22 +1,34 @@
|
||||
global:
|
||||
storageClass: longhorn-crypto
|
||||
image:
|
||||
rootless: false
|
||||
service:
|
||||
http:
|
||||
annotations:
|
||||
metallb.universe.tf/allow-shared-ip: gitea
|
||||
port: 443
|
||||
targetPort: 443
|
||||
ssh:
|
||||
annotations:
|
||||
metallb.universe.tf/allow-shared-ip: gitea
|
||||
ingress:
|
||||
enabled: true
|
||||
className: nginx-internal
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: nginx-internal
|
||||
cert-manager.io/cluster-issuer: cloudflare-issuer
|
||||
cert-manager.io/acme-challenge-type: dns01
|
||||
cert-manager.io/private-key-size: "4096"
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
|
||||
hosts:
|
||||
- host: git.dogar.dev
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: gitea-http
|
||||
port:
|
||||
number: 443
|
||||
tls:
|
||||
- secretName: gitea-tls
|
||||
hosts:
|
||||
@@ -37,19 +49,23 @@ gitea:
|
||||
ENABLE_GZIP: true
|
||||
LFS_START_SERVER: true
|
||||
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:
|
||||
DB_TYPE: postgres
|
||||
HOST: postgres-cluster-rw.postgres-system.svc.cluster.local:5432
|
||||
HOST: postgres-cluster-rw
|
||||
NAME: gitea
|
||||
USER: gitea
|
||||
SSL_MODE: require
|
||||
cache:
|
||||
ADAPTER: memcache
|
||||
HOST: memcached.memcached-system.svc.cluster.local:11211
|
||||
ADAPTER: memory
|
||||
session:
|
||||
PROVIDER: db
|
||||
PROVIDER_CONFIG: ""
|
||||
queue:
|
||||
TYPE: redis
|
||||
TYPE: channel
|
||||
lfs:
|
||||
STORAGE_TYPE: local
|
||||
service:
|
||||
@@ -69,27 +85,76 @@ gitea:
|
||||
iconUrl: "https://goauthentik.io/img/icon.png"
|
||||
scopes: "email profile"
|
||||
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
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
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:
|
||||
enabled: true
|
||||
storageClass: longhorn-crypto
|
||||
accessModes:
|
||||
- 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:
|
||||
enabled: false
|
||||
redis-cluster:
|
||||
valkey-cluster:
|
||||
enabled: false
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
defaultSettings:
|
||||
backupTarget: "s3://homelab-backups@apac/longhorn"
|
||||
backupTargetCredentialSecret: longhorn-backup
|
||||
defaultReplicaCount: 2
|
||||
storageOverProvisioningPercentage: 100
|
||||
backupCompressionMethod: "gzip"
|
||||
backupConcurrentLimit: 4
|
||||
defaultBackupStore:
|
||||
backupTarget: "s3://homelab@auto/longhorn"
|
||||
backupTargetCredentialSecret: cloudflare-token
|
||||
metrics:
|
||||
serviceMonitor:
|
||||
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"
|
||||
parameters: {}
|
||||
ingressClass: nginx-internal
|
||||
service:
|
||||
annotations:
|
||||
external-dns.alpha.kubernetes.io/hostname: "postgres.dogar.dev"
|
||||
tcp:
|
||||
22: "gitea-system/gitea-ssh:22"
|
||||
5432: "postgres-system/postgres-cluster-rw:5432"
|
||||
6379: "redis-system/redis-master-0:6379"
|
||||
11211: "memcached-system/memcached:11211"
|
||||
35432: "rihla/postgres-cluster-rw:5432"
|
||||
22: "homelab/gitea-ssh:22"
|
||||
25565: "minecraft/monifactory-server:25565"
|
||||
|
||||
@@ -3,8 +3,6 @@ DNS1:
|
||||
1.1.1.1
|
||||
DNS2:
|
||||
1.0.0.1
|
||||
nodeSelector:
|
||||
pihole: "true"
|
||||
admin:
|
||||
enabled: true
|
||||
existingSecret: pihole-admin
|
||||
@@ -30,19 +28,16 @@ ingress:
|
||||
serviceWeb:
|
||||
annotations:
|
||||
metallb.universe.tf/allow-shared-ip: pihole-svc
|
||||
type: LoadBalancer
|
||||
loadBalancerIP: 192.168.18.250
|
||||
type: ClusterIP
|
||||
https:
|
||||
enabled: false
|
||||
serviceDns:
|
||||
annotations:
|
||||
metallb.universe.tf/allow-shared-ip: pihole-svc
|
||||
type: LoadBalancer
|
||||
loadBalancerIP: 192.168.18.250
|
||||
serviceDhcp:
|
||||
annotations:
|
||||
metallb.universe.tf/allow-shared-ip: pihole-svc
|
||||
enabled: true
|
||||
type: LoadBalancer
|
||||
loadBalancerIP: 192.168.18.250
|
||||
enabled: false
|
||||
probes:
|
||||
liveness:
|
||||
enabled: false
|
||||
@@ -55,7 +50,6 @@ dnsmasq:
|
||||
- dhcp-host=B0:41:6F:0F:A0:CD,192.168.18.12,homelab-2
|
||||
hostNetwork: true
|
||||
hostname: pihole
|
||||
privileged: true
|
||||
capabilities:
|
||||
add:
|
||||
- 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
|
||||
metadata:
|
||||
name: pool
|
||||
namespace: metallb-system
|
||||
namespace: homelab
|
||||
spec:
|
||||
addresses:
|
||||
- 192.168.18.192/26
|
||||
@@ -12,7 +12,7 @@ apiVersion: metallb.io/v1beta1
|
||||
kind: L2Advertisement
|
||||
metadata:
|
||||
name: pool
|
||||
namespace: metallb-system
|
||||
namespace: homelab
|
||||
spec:
|
||||
ipAddressPools:
|
||||
- pool
|
||||
|
||||
@@ -10,7 +10,6 @@ type LonghornOptions = {
|
||||
kubernetes: KubernetesProvider;
|
||||
helm: HelmProvider;
|
||||
};
|
||||
version: string;
|
||||
name: string;
|
||||
namespace: string;
|
||||
};
|
||||
@@ -24,11 +23,11 @@ export class Longhorn extends Construct {
|
||||
new Release(this, id, {
|
||||
name: options.name,
|
||||
namespace: options.namespace,
|
||||
version: options.version,
|
||||
provider: helm,
|
||||
repository: "https://charts.longhorn.io",
|
||||
chart: "longhorn",
|
||||
createNamespace: true,
|
||||
upgradeInstall: true,
|
||||
values: [
|
||||
fs.readFileSync("helm/values/longhorn.values.yaml", {
|
||||
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", {
|
||||
provider: kubernetes,
|
||||
manifest: {
|
||||
|
||||
107
main.ts
107
main.ts
@@ -10,11 +10,10 @@ import { OnePassword } from "./1password";
|
||||
import { PostgresCluster } from "./postgres";
|
||||
import { Longhorn } from "./longhorn";
|
||||
import { AuthentikServer } from "./authentik";
|
||||
import { RedisCluster } from "./redis";
|
||||
import { ValkeyCluster } from "./valkey";
|
||||
import { CertManager } from "./cert-manager";
|
||||
import { Manifest } from "@cdktf/provider-kubernetes/lib/manifest";
|
||||
import { PiHole } from "./pihole";
|
||||
import { MemcachedCluster } from "./memcached";
|
||||
import { Nginx } from "./nginx";
|
||||
import { Prometheus } from "./prometheus";
|
||||
import { MetalLB } from "./metallb";
|
||||
@@ -28,6 +27,8 @@ const env = cleanEnv(process.env, {
|
||||
BUCKET: str({ desc: "The name of the R2 bucket." }),
|
||||
});
|
||||
|
||||
const r2Endpoint = `https://${env.ACCOUNT_ID}.r2.cloudflarestorage.com`;
|
||||
|
||||
class Homelab extends TerraformStack {
|
||||
constructor(scope: Construct, id: string) {
|
||||
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,
|
||||
manifest: {
|
||||
kind: "Namespace",
|
||||
apiVersion: "v1",
|
||||
metadata: {
|
||||
name: "homelab",
|
||||
name: namespace,
|
||||
},
|
||||
spec: {},
|
||||
},
|
||||
@@ -72,54 +75,40 @@ class Homelab extends TerraformStack {
|
||||
},
|
||||
});
|
||||
|
||||
new Longhorn(this, "longhorn", {
|
||||
namespace: "longhorn-system",
|
||||
const longhorn = new Longhorn(this, "longhorn", {
|
||||
namespace,
|
||||
name: "longhorn",
|
||||
version: "1.8.2",
|
||||
providers: {
|
||||
kubernetes,
|
||||
helm,
|
||||
},
|
||||
});
|
||||
|
||||
longhorn.node.addDependency(ns);
|
||||
|
||||
new MetalLB(this, "metallb", {
|
||||
provider: helm,
|
||||
name: "metallb",
|
||||
namespace: "metallb-system",
|
||||
version: "0.15.2",
|
||||
namespace,
|
||||
});
|
||||
|
||||
new OnePassword(this, "one-password", {
|
||||
provider: kubernetes,
|
||||
namespace,
|
||||
});
|
||||
|
||||
new Nginx(this, "nginx", {
|
||||
const nginx = new Nginx(this, "nginx", {
|
||||
provider: helm,
|
||||
namespace: "nginx-system",
|
||||
name: "ingress-nginx-internal",
|
||||
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",
|
||||
namespace,
|
||||
name: "nginx-ingress",
|
||||
});
|
||||
|
||||
const certManagerApiVersion = "cert-manager.io/v1";
|
||||
|
||||
new CertManager(this, "cert-manager", {
|
||||
const cm = new CertManager(this, "cert-manager", {
|
||||
certManagerApiVersion,
|
||||
name: "cert-manager",
|
||||
namespace: "cert-manager",
|
||||
namespace,
|
||||
version: "1.18.2",
|
||||
providers: {
|
||||
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,
|
||||
version: "0.24.0",
|
||||
name: "postgres-cluster",
|
||||
namespace: "postgres-system",
|
||||
namespace,
|
||||
providers: {
|
||||
kubernetes,
|
||||
helm,
|
||||
},
|
||||
storageClass: "longhorn-crypto",
|
||||
users: ["shahab", "budget-tracker"],
|
||||
users: ["shahab", "budget-tracker", "authentik", "gitea"],
|
||||
primaryUser: "shahab",
|
||||
initSecretName: "postgres-password",
|
||||
backupR2EndpointURL: `https://${env.ACCOUNT_ID}.r2.cloudflarestorage.com`,
|
||||
backupR2EndpointURL: r2Endpoint,
|
||||
});
|
||||
|
||||
new RedisCluster(this, "redis-cluster", {
|
||||
provider: helm,
|
||||
namespace: "redis-system",
|
||||
name: "redis",
|
||||
pg.node.addDependency(pihole);
|
||||
|
||||
const valkey = new ValkeyCluster(this, "valkey-cluster", {
|
||||
provider: kubernetes,
|
||||
namespace,
|
||||
name: "valkey",
|
||||
});
|
||||
|
||||
new MemcachedCluster(this, "memcached-cluster", {
|
||||
provider: helm,
|
||||
namespace: "memcached-system",
|
||||
name: "memcached",
|
||||
});
|
||||
valkey.node.addDependency(pihole);
|
||||
|
||||
new AuthentikServer(this, "authentik-server", {
|
||||
const authentik = new AuthentikServer(this, "authentik-server", {
|
||||
provider: helm,
|
||||
name: "authentik",
|
||||
namespace: "authentik-system",
|
||||
version: "2025.8.1",
|
||||
namespace,
|
||||
});
|
||||
|
||||
new GiteaServer(this, "gitea-server", {
|
||||
authentik.node.addDependency(pg);
|
||||
authentik.node.addDependency(valkey);
|
||||
|
||||
const gitea = new GiteaServer(this, "gitea-server", {
|
||||
name: "gitea",
|
||||
namespace: "gitea-system",
|
||||
namespace,
|
||||
provider: helm,
|
||||
version: "12.1.1",
|
||||
});
|
||||
|
||||
gitea.node.addDependency(authentik);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,6 +181,7 @@ const app = new App();
|
||||
const stack = new Homelab(app, "homelab");
|
||||
|
||||
new S3Backend(stack, {
|
||||
encrypt: true,
|
||||
bucket: env.BUCKET,
|
||||
key: "terraform.tfstate",
|
||||
region: "auto",
|
||||
@@ -186,7 +193,7 @@ new S3Backend(stack, {
|
||||
accessKey: env.R2_ACCESS_KEY_ID,
|
||||
secretKey: env.R2_SECRET_ACCESS_KEY,
|
||||
endpoints: {
|
||||
s3: `https://${env.ACCOUNT_ID}.r2.cloudflarestorage.com/${env.BUCKET}`,
|
||||
s3: `${r2Endpoint}/${env.BUCKET}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ type MetalLBOptions = {
|
||||
provider: HelmProvider;
|
||||
name: string;
|
||||
namespace: string;
|
||||
version: string;
|
||||
};
|
||||
|
||||
export class MetalLB extends Construct {
|
||||
|
||||
@@ -7,7 +7,6 @@ type NginxOptions = {
|
||||
provider: HelmProvider;
|
||||
name: string;
|
||||
namespace: string;
|
||||
version: string;
|
||||
};
|
||||
|
||||
export class Nginx extends Construct {
|
||||
|
||||
@@ -5,7 +5,6 @@ import { Construct } from "constructs";
|
||||
|
||||
type PiHoleOptions = {
|
||||
provider: HelmProvider;
|
||||
version: string;
|
||||
name: string;
|
||||
namespace: string;
|
||||
};
|
||||
@@ -18,7 +17,7 @@ export class PiHole extends Construct {
|
||||
...options,
|
||||
repository: "https://mojo2600.github.io/pihole-kubernetes",
|
||||
chart: "pihole",
|
||||
createNamespace: true,
|
||||
version: "2.26.1",
|
||||
values: [
|
||||
fs.readFileSync("helm/values/pihole.values.yaml", {
|
||||
encoding: "utf8",
|
||||
@@ -30,7 +29,7 @@ export class PiHole extends Construct {
|
||||
provider: options.provider,
|
||||
name: "externaldns-pihole",
|
||||
namespace: options.namespace,
|
||||
repository: "https://charts.bitnami.com/bitnami",
|
||||
repository: "oci://registry-1.docker.io/bitnamicharts/",
|
||||
chart: "external-dns",
|
||||
values: [
|
||||
fs.readFileSync("helm/values/externaldns.values.yaml", {
|
||||
|
||||
@@ -16,7 +16,6 @@ type PostgresClusterOptions = {
|
||||
primaryUser: string;
|
||||
initSecretName: string;
|
||||
certManagerApiVersion: string;
|
||||
version: string;
|
||||
backupR2EndpointURL: string;
|
||||
};
|
||||
|
||||
@@ -28,27 +27,27 @@ export class PostgresCluster extends Construct {
|
||||
|
||||
new Release(this, "cnpg-operator", {
|
||||
provider: helm,
|
||||
version: options.version,
|
||||
repository: "https://cloudnative-pg.github.io/charts",
|
||||
chart: "cloudnative-pg",
|
||||
name: "postgres-system",
|
||||
namespace: options.namespace,
|
||||
namespace: "cnpg-system",
|
||||
});
|
||||
|
||||
const destinationPath = "s3://homelab-backups/";
|
||||
|
||||
const destinationPath = "s3://homelab/";
|
||||
const endpointURL = options.backupR2EndpointURL;
|
||||
const barmanStoreName = "r2-postgres-backup-store";
|
||||
|
||||
const barmanConfiguration = {
|
||||
destinationPath,
|
||||
endpointURL,
|
||||
s3Credentials: {
|
||||
accessKeyId: {
|
||||
name: "cloudflare-r2-token",
|
||||
key: "access_key",
|
||||
name: "cloudflare-token",
|
||||
key: "access_key_id",
|
||||
},
|
||||
secretAccessKey: {
|
||||
name: "cloudflare-r2-token",
|
||||
key: "secret_key",
|
||||
name: "cloudflare-token",
|
||||
key: "secret_access_key",
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -60,7 +59,7 @@ export class PostgresCluster extends Construct {
|
||||
kind: "ObjectStore",
|
||||
metadata: {
|
||||
namespace: options.namespace,
|
||||
name: "r2-postgres-backup-store-homelab",
|
||||
name: barmanStoreName,
|
||||
},
|
||||
spec: {
|
||||
configuration: {
|
||||
@@ -178,9 +177,8 @@ export class PostgresCluster extends Construct {
|
||||
secretName: certNames.server,
|
||||
usages: ["server auth"],
|
||||
dnsNames: [
|
||||
"postgres-cluster-rw.postgres-system.svc.cluster.local",
|
||||
"postgres-cluster-ro.postgres-system.svc.cluster.local",
|
||||
"postgres-cluster-r.postgres-system.svc.cluster.local",
|
||||
"postgres-cluster-rw",
|
||||
"postgres-cluster-rw.homelab.svc.cluster.local",
|
||||
"postgres.dogar.dev",
|
||||
],
|
||||
duration: "4380h", // 6 months
|
||||
@@ -342,7 +340,7 @@ export class PostgresCluster extends Construct {
|
||||
enabled: true,
|
||||
isWALArchiver: true,
|
||||
parameters: {
|
||||
barmanObjectName: "r2-postgres-backup-store",
|
||||
barmanObjectName: barmanStoreName,
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -396,7 +394,7 @@ export class PostgresCluster extends Construct {
|
||||
storageClass: options.storageClass,
|
||||
},
|
||||
walStorage: {
|
||||
size: "10Gi",
|
||||
size: "1Gi",
|
||||
storageClass: options.storageClass,
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user