This commit is contained in:
2024-05-22 12:49:28 -05:00
commit 35b77bb0df
219 changed files with 9997 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
apiVersion: v2
name: authentik
version: 1.0.0
sources:
- https://github.com/goauthentik/authentik
- https://github.com/goauthentik/helm
- https://github.com/bjw-s/helm-charts/tree/main/charts/other/app-template
- https://github.com/alexlebens/helm-charts/charts/postgres-cluster
dependencies:
- name: authentik
version: 2024.4.2
repository: https://charts.goauthentik.io/
- name: app-template
alias: cloudflared
repository: https://bjw-s.github.io/helm-charts/
version: 3.1.0
- name: postgres-cluster
alias: postgres-16-cluster
version: 3.0.0
repository: http://alexlebens.github.io/helm-charts
appVersion: "2024.4.2"

View File

@@ -0,0 +1,60 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: authentik-custom-css
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: {{ .Release.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/component: web
app.kubernetes.io/part-of: {{ .Release.Name }}
data:
custom.css: |
/* Change sign button color */
.pf-c-button.pf-m-primary {
color: black;
background-color: white;
}
/* Remove background */
.pf-c-login__main {
background-color: rgba(3, 3, 3, 0.16);
}
/* Remove specific height */
.pf-c-brand {
height: auto;
}
/* Center text */
.pf-c-title {
text-align: center;
}
/* Match text field to login button */
.pf-c-form-control {
border-radius: 3px;
background-color: white;
color: black;
}
/* Force border color */
.pf-c-form-control {
border-color: white;
}
/* Use default cursor on this div */
.pf-c-form__label {
cursor: default;
}
/* Hide required asterik */
.pf-c-form__label-required {
display: none;
}
/* Change link color to white */
.a {
color: white;
}

View File

@@ -0,0 +1,80 @@
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: authentik-key-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: authentik-key-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/component: web
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: key
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /authentik/key
metadataPolicy: None
property: key
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: authentik-cloudflared-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: authentik-cloudflared-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/component: web
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: cf-tunnel-token
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cloudflare/tunnels/authentik
metadataPolicy: None
property: token
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: authentik-postgresql-16-cluster-backup-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: authentik-postgresql-16-cluster-backup-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/component: database
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: ACCESS_KEY_ID
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /aws/keys/cl01tl-authentik-postgresql
metadataPolicy: None
property: access_key
- secretKey: ACCESS_SECRET_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /aws/keys/cl01tl-authentik-postgresql
metadataPolicy: None
property: secret_key

View File

@@ -0,0 +1,118 @@
authentik:
global:
env:
- name: AUTHENTIK_SECRET_KEY
valueFrom:
secretKeyRef:
name: authentik-key-secret
key: key
- name: AUTHENTIK_POSTGRESQL__HOST
valueFrom:
secretKeyRef:
name: authentik-postgresql-16-cluster-app
key: host
- name: AUTHENTIK_POSTGRESQL__NAME
valueFrom:
secretKeyRef:
name: authentik-postgresql-16-cluster-app
key: dbname
- name: AUTHENTIK_POSTGRESQL__USER
valueFrom:
secretKeyRef:
name: authentik-postgresql-16-cluster-app
key: user
- name: AUTHENTIK_POSTGRESQL__PASSWORD
valueFrom:
secretKeyRef:
name: authentik-postgresql-16-cluster-app
key: password
server:
name: server
replicas: 1
volumes:
- name: custom-css
configMap:
name: authentik-custom-css
volumeMounts:
- name: custom-css
mountPath: /web/dist/custom.css
subPath: custom.css
metrics:
enabled: true
serviceMonitor:
enabled: true
ingress:
enabled: true
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
cert-manager.io/cluster-issuer: letsencrypt-issuer
ingressClassName: traefik
hosts:
- auth.alexlebens.net
- authentik.alexlebens.net
tls:
- secretName: authentik-secret-tls
hosts:
- auth.alexlebens.net
- authentik.alexlebens.net
worker:
name: worker
replicas: 1
prometheus:
rules:
enabled: true
postgresql:
enabled: false
redis:
enabled: true
cloudflared:
global:
nameOverride: cloudflared
controllers:
main:
type: deployment
strategy: Recreate
containers:
main:
image:
repository: cloudflare/cloudflared
tag: "2024.5.0"
pullPolicy: IfNotPresent
args:
- tunnel
- --no-autoupdate
- run
- --token
- $(CF_MANAGED_TUNNEL_TOKEN)
env:
- name: CF_MANAGED_TUNNEL_TOKEN
valueFrom:
secretKeyRef:
name: authentik-cloudflared-secret
key: cf-tunnel-token
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 10m
memory: 64Mi
postgres-16-cluster:
mode: standalone
cluster:
walStorage:
storageClass: local-path
storage:
storageClass: local-path
monitoring:
enabled: true
prometheusRule:
enabled: false
backup:
enabled: true
endpointURL: https://s3.us-east-2.amazonaws.com
destinationPath: s3://cl01tl-postgresql-backups/authentik
endpointCredentials: authentik-postgresql-16-cluster-backup-secret
backupIndex: 1
retentionPolicy: 14d

View File

@@ -0,0 +1,11 @@
apiVersion: v2
name: external-secrets
version: 0.0.1
sources:
- https://github.com/external-secrets/external-secrets
- https://github.com/external-secrets/external-secrets/tree/main/deploy/charts/external-secrets
dependencies:
- name: external-secrets
version: 0.9.18
repository: https://charts.external-secrets.io
appVersion: 0.9.13

View File

@@ -0,0 +1,21 @@
apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
name: vault
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: {{ .Release.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/component: auth
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
provider:
vault:
server: http://vault-internal.vault:8200
path: secret
auth:
tokenSecretRef:
namespace: vault
name: vault-token
key: token

View File

@@ -0,0 +1,16 @@
apiVersion: v2
name: gitea
version: 1.0.0
sources:
- https://github.com/go-gitea/gitea
- https://gitea.com/gitea/helm-chart
- https://github.com/alexlebens/helm-charts/charts/postgres-cluster
dependencies:
- name: gitea
version: 10.1.4
repository: https://dl.gitea.io/charts/
- name: postgres-cluster
alias: postgres-16-cluster
version: 3.0.0
repository: http://alexlebens.github.io/helm-charts
appVersion: "1.21.7"

View File

@@ -0,0 +1,94 @@
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: gitea-admin-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: {{ .Release.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/component: web
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: username
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /gitea/auth/admin
metadataPolicy: None
property: username
- secretKey: password
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /gitea/auth/admin
metadataPolicy: None
property: password
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: gitea-oidc-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: {{ .Release.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/component: web
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: secret
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /authentik/oidc/gitea
metadataPolicy: None
property: secret
- secretKey: key
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /authentik/oidc/gitea
metadataPolicy: None
property: client
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: gitea-postgresql-16-cluster-backup-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: {{ .Release.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/component: database
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: ACCESS_KEY_ID
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /aws/keys/cl01tl-gitea-postgresql
metadataPolicy: None
property: access_key
- secretKey: ACCESS_SECRET_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /aws/keys/cl01tl-gitea-postgresql
metadataPolicy: None
property: secret_key

View File

@@ -0,0 +1,96 @@
gitea:
ingress:
enabled: true
className: traefik
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
cert-manager.io/cluster-issuer: letsencrypt-issuer
hosts:
- host: gitea.alexlebens.net
paths:
- path: /
pathType: Prefix
tls:
- secretName: gitea-secret-tls
hosts:
- gitea.alexlebens.net
gitea:
admin:
existingSecret: gitea-admin-secret
metrics:
enabled: true
serviceMonitor:
enabled: true
config:
server:
LANDING_PAGE: explore
ROOT_URL: https://gitea.alexlebens.net
ENABLE_PPROF: true
webhook:
ALLOWED_HOST_LIST: private
scopes: email profile
service:
DISABLE_REGISTRATION: true
SHOW_REGISTRATION_BUTTON: false
explore:
REQUIRE_SIGNIN_VIEW: true
database:
DB_TYPE: postgres
SCHEMA: public
additionalConfigFromEnvs:
- name: GITEA__DATABASE__HOST
valueFrom:
secretKeyRef:
name: gitea-postgresql-16-cluster-app
key: host
- name: GITEA__DATABASE__NAME
valueFrom:
secretKeyRef:
name: gitea-postgresql-16-cluster-app
key: dbname
- name: GITEA__DATABASE__USER
valueFrom:
secretKeyRef:
name: gitea-postgresql-16-cluster-app
key: user
- name: GITEA__DATABASE__PASSWD
valueFrom:
secretKeyRef:
name: gitea-postgresql-16-cluster-app
key: password
oauth:
- name: Authentik
provider: openidConnect
existingSecret: gitea-oidc-secret
autoDiscoverUrl: "https://authentik.alexlebens.net/application/o/gitea/.well-known/openid-configuration"
iconUrl: https://goauthentik.io/img/icon.png
scopes: "email profile"
persistence:
storageClass: ceph-block
postgresql:
enabled: false
postgresql-ha:
enabled: false
redis-cluster:
enabled: true
persistence:
enabled: false
postgres-16-cluster:
mode: standalone
cluster:
walStorage:
storageClass: local-path
storage:
storageClass: local-path
monitoring:
enabled: true
prometheusRule:
enabled: false
backup:
enabled: true
endpointURL: https://s3.us-east-2.amazonaws.com
destinationPath: s3://cl01tl-postgresql-backups/gitea
endpointCredentials: gitea-postgresql-16-cluster-backup-secret
backupIndex: 1
retentionPolicy: 14d

View File

@@ -0,0 +1,11 @@
apiVersion: v2
name: grafana
version: 0.0.1
sources:
- https://github.com/grafana/grafana
- https://github.com/grafana/helm-charts/tree/main/charts/grafana
dependencies:
- name: grafana
version: 7.3.11
repository: https://grafana.github.io/helm-charts
appVersion: "10.4.0"

View File

@@ -0,0 +1,62 @@
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: grafana-auth-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: {{ .Release.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/component: web
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: admin-user
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /grafana/auth
metadataPolicy: None
property: admin-user
- secretKey: admin-password
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /grafana/auth
metadataPolicy: None
property: admin-password
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: grafana-oauth-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: {{ .Release.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/component: web
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: GF_AUTH_GENERIC_OAUTH_CLIENT_ID
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /authentik/oidc/grafana
metadataPolicy: None
property: client
- secretKey: GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /authentik/oidc/grafana
metadataPolicy: None
property: secret

View File

@@ -0,0 +1,142 @@
grafana:
deploymentStrategy:
type: Recreate
createConfigmap: true
serviceMonitor:
enabled: true
ingress:
enabled: true
ingressClassName: traefik
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
cert-manager.io/cluster-issuer: letsencrypt-issuer
hosts:
- grafana.alexlebens.net
tls:
- secretName: grafana-secret-tls
hosts:
- grafana.alexlebens.net
persistence:
enabled: true
storageClassName: ceph-block
admin:
existingSecret: grafana-auth-secret
userKey: admin-user
passwordKey: admin-password
envFromSecret: grafana-oauth-secret
plugins:
- grafana-clock-panel
- vonage-status-panel
- grafana-worldmap-panel
datasources:
datasources.yaml:
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
uid: prometheus
url: http://kube-prometheus-stack-prometheus.kube-prometheus-stack:9090/
access: proxy
isDefault: true
jsonData:
timeInterval: 30s
- name: Loki
type: loki
url: http://loki.loki:3100
jsonData:
httpHeaderName1: "X-Scope-OrgID"
secureJsonData:
httpHeaderValue1: "1"
dashboardProviders:
dashboardproviders.yaml:
apiVersion: 1
providers:
- name: "default"
orgId: 1
folder: ""
type: file
disableDeletion: false
editable: true
options:
path: /var/lib/grafana/dashboards/default
dashboards:
default:
node-exporter:
gnetId: 1860
revision: 33
datasource: Prometheus
coredns:
gnetId: 14981
revision: 2
datasource: Prometheus
loki:
gnetId: 14055
revision: 5
datasource: Prometheus
argocd:
gnetId: 14584
revision: 1
datasource: Prometheus
cert-manager:
gnetId: 11001
revision: 1
datasource: Prometheus
traefik:
gnetId: 17346
revision: 7
datasource: Prometheus
kubernetes-nodes:
gnetId: 8171
revision: 1
datasource: Prometheus
vault:
gnetId: 12904
revision: 2
datasource: Prometheus
ceph:
gnetId: 2842
revision: 17
datasource: Prometheus
alertmanager:
gnetId: 9578
revision: 4
datasource: Prometheus
sonarr:
gnetId: 12530
revision: 2
datasource: Prometheus
radarr:
gnetId: 12896
revision: 1
datasource: Prometheus
unpoller:
gnetId: 11315
revision: 9
datasource: Prometheus
etcd:
gnetId: 3070
revision: 3
datasource: Prometheus
grafana.ini:
analytics:
check_for_updates: false
server:
domain: alexlebens.net
root_url: https://grafana.alexlebens.net
users:
auto_assign_org: true
auto_assign_org_id: 1
auth:
disable_login_form: true
oauth_auto_login: true
signout_redirect_url: https://authentik.alexlebens.net/application/o/grafana/end-session/
auth.generic_oauth:
enabled: true
name: Authentik
allow_sign_up: true
scopes: openid profile email
auth_url: https://authentik.alexlebens.net/application/o/authorize/
token_url: https://authentik.alexlebens.net/application/o/token/
api_url: https://authentik.alexlebens.net/application/o/userinfo/
role_attribute_path: contains(groups, 'Grafana Admins') && 'Admin' || contains(groups, 'Grafana Editors') && 'Editor' || 'Viewer'

View File

@@ -0,0 +1,11 @@
apiVersion: v2
name: headlamp
version: 0.0.1
sources:
- https://github.com/headlamp-k8s/headlamp
- https://github.com/headlamp-k8s/headlamp/tree/main/charts/headlamp
dependencies:
- name: headlamp
version: 0.21.0
repository: https://headlamp-k8s.github.io/headlamp/
appVersion: 0.23.1

View File

@@ -0,0 +1,19 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cluster-admin-oidc
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: {{ .Release.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/component: web
app.kubernetes.io/part-of: {{ .Release.Name }}
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: User
name: alexanderlebens@gmail.com
apiGroup: rbac.authorization.k8s.io

View File

@@ -0,0 +1,30 @@
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: headlamp-oidc-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: {{ .Release.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/component: web
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: HEADLAMP_CONFIG_OIDC_CLIENT_ID
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /authentik/oidc/headlamp
metadataPolicy: None
property: client
- secretKey: HEADLAMP_CONFIG_OIDC_CLIENT_SECRET
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /authentik/oidc/headlamp
metadataPolicy: None
property: secret

View File

@@ -0,0 +1,48 @@
headlamp:
config:
oidc:
secret:
create: true
name: headlamp-oidc-generated-secret
env:
- name: HEADLAMP_CONFIG_OIDC_CLIENT_ID
valueFrom:
secretKeyRef:
key: HEADLAMP_CONFIG_OIDC_CLIENT_ID
name: headlamp-oidc-secret
- name: HEADLAMP_CONFIG_OIDC_CLIENT_SECRET
valueFrom:
secretKeyRef:
key: HEADLAMP_CONFIG_OIDC_CLIENT_SECRET
name: headlamp-oidc-secret
- name: HEADLAMP_CONFIG_OIDC_IDP_ISSUER_URL
value: https://authentik.alexlebens.net/application/o/headlamp/
persistentVolumeClaim:
enabled: true
accessModes:
- ReadWriteOnce
size: 10Gi
storageClassName: ceph-block
volumeMode: Filesystem
ingress:
enabled: true
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
cert-manager.io/cluster-issuer: letsencrypt-issuer
hosts:
- host: headlamp.alexlebens.net
paths:
- path: /
type: ImplementationSpecific
tls:
- secretName: headlamp-secret-tls
hosts:
- headlamp.alexlebens.net
resources:
limits:
cpu: 500m
memory: 1Gi
requests:
cpu: 100m
memory: 256Mi

View File

@@ -0,0 +1,11 @@
apiVersion: v2
name: pgadmin4
version: 0.0.3
sources:
- https://github.com/pgadmin-org/pgadmin4
- https://github.com/rowanruseler/helm-charts
dependencies:
- name: pgadmin4
version: 1.25.1
repository: https://helm.runix.net
appVersion: "8.4"

View File

@@ -0,0 +1,62 @@
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: pgadmin-password-secret
namespace: {{ .Release.Namespace | quote }}
labels:
app.kubernetes.io/name: {{ .Release.Name | quote }}
app.kubernetes.io/instance: {{ .Release.Name | quote }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/component: web
app.kubernetes.io/part-of: {{ .Release.Name | quote }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: pgadmin-password
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /pgadmin/auth
metadataPolicy: None
property: pgadmin-password
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: pgadmin-env-secret
namespace: {{ .Release.Namespace | quote }}
labels:
app.kubernetes.io/name: {{ .Release.Name | quote }}
app.kubernetes.io/instance: {{ .Release.Name | quote }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/component: web
app.kubernetes.io/part-of: {{ .Release.Name | quote }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: PGADMIN_CONFIG_AUTHENTICATION_SOURCES
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /pgadmin/env
metadataPolicy: None
property: PGADMIN_CONFIG_AUTHENTICATION_SOURCES
- secretKey: PGADMIN_CONFIG_OAUTH2_AUTO_CREATE_USER
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /pgadmin/env
metadataPolicy: None
property: PGADMIN_CONFIG_OAUTH2_AUTO_CREATE_USER
- secretKey: PGADMIN_CONFIG_OAUTH2_CONFIG
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /pgadmin/env
metadataPolicy: None
property: PGADMIN_CONFIG_OAUTH2_CONFIG

View File

@@ -0,0 +1,40 @@
pgadmin4:
image:
repository: dpage/pgadmin4
tag: "8.6"
serviceAccount:
create: true
automountServiceAccountToken: true
strategy:
type: Recreate
serverDefinitions:
enabled: false
ingress:
enabled: true
ingressClassName: traefik
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
cert-manager.io/cluster-issuer: letsencrypt-issuer
hosts:
- host: pgadmin.alexlebens.net
paths:
- path: /
pathType: Prefix
tls:
- secretName: pgadmin-secret-tls
hosts:
- pgadmin.alexlebens.net
existingSecret: pgadmin-password-secret
secretKeys:
pgadminPasswordKey: pgadmin-password
env:
email: alexanderlebens@gmail.com
envVarsFromSecrets:
- pgadmin-env-secret
persistentVolume:
enabled: true
accessModes:
- ReadWriteOnce
size: 5Gi
storageClass: ceph-block

View File

@@ -0,0 +1,11 @@
apiVersion: v2
name: portainer
version: 0.0.1
sources:
- https://github.com/portainer/portainer
- https://github.com/portainer/k8s
dependencies:
- name: portainer
version: "1.0.51"
repository: https://portainer.github.io/k8s/
appVersion: "2.19.3"

View File

@@ -0,0 +1,35 @@
portainer:
replicaCount: 1
enterpriseEdition:
enabled: false
image:
repository: portainer/portainer-ce
tag: 2.20.2
serviceAccount:
name: portainer-sa-clusteradmin
service:
type: ClusterIP
tls:
force: false
mtls:
enable: false
ingress:
enabled: true
ingressClassName: traefik
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
cert-manager.io/cluster-issuer: letsencrypt-issuer
hosts:
- host: portainer.alexlebens.net
paths:
- path: /
pathType: Prefix
tls:
- secretName: portainer-secret-tls
hosts:
- portainer.alexlebens.net
persistence:
enabled: true
size: 5Gi
storageClass: ceph-block

View File

@@ -0,0 +1,11 @@
apiVersion: v2
name: vault
version: 0.0.1
sources:
- https://github.com/hashicorp/vault
- https://github.com/hashicorp/vault-helm
dependencies:
- name: vault
version: "0.28.0"
repository: https://helm.releases.hashicorp.com
appVersion: 1.15.5

View File

@@ -0,0 +1,64 @@
apiVersion: batch/v1
kind: CronJob
metadata:
name: vault-snapshot-cronjob
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: vault-snapshot-cronjob
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/component: storage
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
schedule: "@every 24h"
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 3
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: snapshot
image: hashicorp/vault:1.16.2
imagePullPolicy: IfNotPresent
command:
- /bin/ash
args:
- -ec
- |
apk add --no-cache jq;
export VAULT_TOKEN=$(vault write auth/approle/login role_id=$VAULT_APPROLE_ROLE_ID secret_id=$VAULT_APPROLE_SECRET_ID -format=json | jq -r .auth.client_token);
vault operator raft snapshot save /opt/backup/vault-snapshot-latest.snap;
cp /opt/backup/vault-snapshot-latest.snap /opt/backup/vault-snapshot-$(date +"%Y%m%d-%H-%M").snap;
cp /opt/backup/vault-snapshot-latest.snap /opt/backup/vault-snapshot-s3.snap;
envFrom:
- secretRef:
name: vault-snapshot-agent-token
env:
- name: VAULT_ADDR
value: http://vault-active.vault.svc.cluster.local:8200
volumeMounts:
- mountPath: /opt/backup
name: backup
- name: upload
image: amazon/aws-cli:2.15.42
imagePullPolicy: IfNotPresent
command:
- /bin/sh
args:
- -ec
- |
until [ -f /opt/backup/vault-snapshot-s3.snap ]; do sleep 5; done;
aws s3 cp /opt/backup/vault-snapshot-s3.snap s3://cl01tl-vault-snapshots/vault-snapshot-$(date +"%Y%m%d-%H-%M").snap;
rm /opt/backup/vault-snapshot-s3.snap;
envFrom:
- secretRef:
name: vault-snapshot-s3
volumeMounts:
- mountPath: /opt/backup
name: backup
volumes:
- name: backup
persistentVolumeClaim:
claimName: vault-nfs-storage-backup

View File

@@ -0,0 +1,26 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tailscale-cl01tl-vault-ui
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: tailscale-cl01tl-vault-ui
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/component: tailscale
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
ingressClassName: tailscale
tls:
- hosts:
- vault-cl01tl
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: vault-ui
port:
name: http

View File

@@ -0,0 +1,19 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: vault-nfs-storage-backup
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: vault-nfs-storage-backup
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/component: storage
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
volumeMode: Filesystem
storageClassName: nfs-client
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi

View File

@@ -0,0 +1,170 @@
vault:
global:
enabled: true
tlsDisable: true
psp:
enable: false
serverTelemetry:
prometheusOperator: true
injector:
enabled: false
server:
enabled: true
image:
repository: "hashicorp/vault"
tag: "1.16.2"
updateStrategyType: "OnDelete"
logLevel: debug
logFormat: standard
resources:
requests:
memory: 256Mi
cpu: 250m
limits:
memory: 256Mi
cpu: 250m
ingress:
enabled: true
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
cert-manager.io/cluster-issuer: letsencrypt-issuer
ingressClassName: traefik
pathType: Prefix
activeService: true
hosts:
- host: vault.alexlebens.net
paths:
- /
tls:
- secretName: vault-secret-tls
hosts:
- vault.alexlebens.net
route:
enabled: false
authDelegator:
enabled: false
readinessProbe:
enabled: true
port: 8200
livenessProbe:
enabled: false
volumes:
- name: vault-nfs-storage-backup
persistentVolumeClaim:
claimName: vault-nfs-storage-backup
volumeMounts:
- mountPath: /opt/backups/
name: vault-nfs-storage-backup
readOnly: false
affinity: |
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app.kubernetes.io/name: {{ template "vault.name" . }}
app.kubernetes.io/instance: "{{ .Release.Name }}"
component: server
topologyKey: kubernetes.io/hostname
networkPolicy:
enabled: false
service:
enabled: true
active:
enabled: true
standby:
enabled: false
type: ClusterIP
port: 8200
targetPort: 8200
dataStorage:
enabled: true
size: 10Gi
mountPath: "/vault/data"
accessMode: ReadWriteOnce
auditStorage:
enabled: false
size: 10Gi
mountPath: "/vault/audit"
accessMode: ReadWriteOnce
dev:
enabled: false
standalone:
enabled: false
ha:
enabled: true
replicas: 3
raft:
enabled: true
config: |
ui = true
listener "tcp" {
tls_disable = 1
address = "[::]:8200"
cluster_address = "[::]:8201"
telemetry {
unauthenticated_metrics_access = "true"
}
}
storage "raft" {
path = "/vault/data"
retry_join {
leader_api_addr = "http://vault-0.vault-internal:8200"
}
retry_join {
leader_api_addr = "http://vault-1.vault-internal:8200"
}
retry_join {
leader_api_addr = "http://vault-2.vault-internal:8200"
}
}
service_registration "kubernetes" {}
telemetry {
prometheus_retention_time = "30s"
disable_hostname = true
}
disruptionBudget:
enabled: true
maxUnavailable: null
serviceAccount:
create: true
serviceDiscovery:
enabled: true
hostNetwork: false
ui:
enabled: true
publishNotReadyAddresses: true
activeVaultPodOnly: false
serviceType: "ClusterIP"
serviceNodePort: null
externalPort: 8200
targetPort: 8200
csi:
enabled: false
serverTelemetry:
serviceMonitor:
enabled: true
interval: 30s
scrapeTimeout: 10s
prometheusRules:
enabled: true
rules:
- alert: vault-HighResponseTime
annotations:
message: The response time of Vault is over 500ms on average over the last 5 minutes.
expr: vault_core_handle_request{quantile="0.5", namespace="mynamespace"} > 500
for: 5m
labels:
severity: warning
- alert: vault-HighResponseTime
annotations:
message: The response time of Vault is over 1s on average over the last 5 minutes.
expr: vault_core_handle_request{quantile="0.5", namespace="mynamespace"} > 1000
for: 5m
labels:
severity: critical