Skip to content

Commit beb9a9d

Browse files
committed
external secret support for postgres, redis, clickhouse, plus fixes
1 parent eaacf63 commit beb9a9d

File tree

5 files changed

+224
-23
lines changed

5 files changed

+224
-23
lines changed

hosting/k8s/helm/templates/_helpers.tpl

Lines changed: 126 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -96,27 +96,34 @@ Get the full image name for supervisor
9696
{{- end }}
9797

9898
{{/*
99-
PostgreSQL hostname
99+
PostgreSQL hostname (deprecated - used only for legacy DATABASE_HOST env var)
100100
*/}}
101101
{{- define "trigger-v4.postgres.hostname" -}}
102-
{{- if .Values.postgres.external.host }}
103-
{{- .Values.postgres.external.host }}
104-
{{- else if .Values.postgres.deploy }}
102+
{{- if .Values.postgres.deploy }}
105103
{{- printf "%s-postgres" .Release.Name }}
104+
{{- else }}
105+
{{- "external-postgres" }}
106106
{{- end }}
107107
{{- end }}
108108

109109
{{/*
110-
PostgreSQL connection string
110+
PostgreSQL connection string (fallback when not using secrets)
111111
*/}}
112112
{{- define "trigger-v4.postgres.connectionString" -}}
113-
{{- if .Values.postgres.external.host -}}
114-
postgresql://{{ .Values.postgres.external.username }}:{{ .Values.postgres.external.password }}@{{ .Values.postgres.external.host }}:{{ .Values.postgres.external.port | default 5432 }}/{{ .Values.postgres.external.database }}?schema={{ .Values.postgres.connection.schema | default "public" }}&sslmode={{ .Values.postgres.connection.sslMode | default "prefer" }}
113+
{{- if .Values.postgres.external.databaseUrl -}}
114+
{{ .Values.postgres.external.databaseUrl }}
115115
{{- else if .Values.postgres.deploy -}}
116116
postgresql://{{ .Values.postgres.auth.username }}:{{ .Values.postgres.auth.password }}@{{ include "trigger-v4.postgres.hostname" . }}:5432/{{ .Values.postgres.auth.database }}?schema={{ .Values.postgres.connection.schema | default "public" }}&sslmode={{ .Values.postgres.connection.sslMode | default "prefer" }}
117117
{{- end -}}
118118
{{- end }}
119119

120+
{{/*
121+
Check if we should use DATABASE_URL from secret
122+
*/}}
123+
{{- define "trigger-v4.postgres.useSecretUrl" -}}
124+
{{- or (and .Values.postgres.external.databaseUrl .Values.postgres.external.existingSecret) (and .Values.postgres.external.existingSecret) -}}
125+
{{- end }}
126+
120127
{{/*
121128
Redis hostname
122129
*/}}
@@ -165,6 +172,94 @@ Redis TLS disabled setting
165172
{{- end -}}
166173
{{- end }}
167174

175+
{{/*
176+
PostgreSQL external secret name
177+
*/}}
178+
{{- define "trigger-v4.postgres.external.secretName" -}}
179+
{{- if .Values.postgres.external.existingSecret -}}
180+
{{ .Values.postgres.external.existingSecret }}
181+
{{- else -}}
182+
{{ include "trigger-v4.secretsName" . }}
183+
{{- end -}}
184+
{{- end }}
185+
186+
{{/*
187+
PostgreSQL external secret database URL key
188+
*/}}
189+
{{- define "trigger-v4.postgres.external.databaseUrlKey" -}}
190+
{{- if .Values.postgres.external.existingSecret -}}
191+
{{ .Values.postgres.external.secretKeys.databaseUrlKey }}
192+
{{- else -}}
193+
postgres-database-url
194+
{{- end -}}
195+
{{- end }}
196+
197+
{{/*
198+
PostgreSQL external secret direct URL key
199+
*/}}
200+
{{- define "trigger-v4.postgres.external.directUrlKey" -}}
201+
{{- if .Values.postgres.external.existingSecret -}}
202+
{{ .Values.postgres.external.secretKeys.directUrlKey | default .Values.postgres.external.secretKeys.databaseUrlKey }}
203+
{{- else -}}
204+
postgres-direct-url
205+
{{- end -}}
206+
{{- end }}
207+
208+
{{/*
209+
PostgreSQL direct URL (fallback to database URL if not set)
210+
*/}}
211+
{{- define "trigger-v4.postgres.directUrl" -}}
212+
{{- if .Values.postgres.external.directUrl -}}
213+
{{ .Values.postgres.external.directUrl }}
214+
{{- else -}}
215+
{{ include "trigger-v4.postgres.connectionString" . }}
216+
{{- end -}}
217+
{{- end }}
218+
219+
{{/*
220+
Redis external secret name
221+
*/}}
222+
{{- define "trigger-v4.redis.external.secretName" -}}
223+
{{- if .Values.redis.external.existingSecret -}}
224+
{{ .Values.redis.external.existingSecret }}
225+
{{- else -}}
226+
{{ include "trigger-v4.secretsName" . }}
227+
{{- end -}}
228+
{{- end }}
229+
230+
{{/*
231+
Redis external secret password key
232+
*/}}
233+
{{- define "trigger-v4.redis.external.passwordKey" -}}
234+
{{- if .Values.redis.external.existingSecret -}}
235+
{{ .Values.redis.external.existingSecretPasswordKey }}
236+
{{- else -}}
237+
redis-password
238+
{{- end -}}
239+
{{- end }}
240+
241+
{{/*
242+
ClickHouse external secret name
243+
*/}}
244+
{{- define "trigger-v4.clickhouse.external.secretName" -}}
245+
{{- if .Values.clickhouse.external.existingSecret -}}
246+
{{ .Values.clickhouse.external.existingSecret }}
247+
{{- else -}}
248+
{{ include "trigger-v4.secretsName" . }}
249+
{{- end -}}
250+
{{- end }}
251+
252+
{{/*
253+
ClickHouse external secret password key
254+
*/}}
255+
{{- define "trigger-v4.clickhouse.external.passwordKey" -}}
256+
{{- if .Values.clickhouse.external.existingSecret -}}
257+
{{ .Values.clickhouse.external.existingSecretKey }}
258+
{{- else -}}
259+
clickhouse-password
260+
{{- end -}}
261+
{{- end }}
262+
168263
{{/*
169264
Electric service URL
170265
*/}}
@@ -198,8 +293,12 @@ ClickHouse URL for application (with secure parameter)
198293
{{- else if .Values.clickhouse.external.host -}}
199294
{{- $protocol := ternary "https" "http" .Values.clickhouse.external.secure -}}
200295
{{- $secure := ternary "true" "false" .Values.clickhouse.external.secure -}}
296+
{{- if .Values.clickhouse.external.existingSecret -}}
297+
{{ $protocol }}://{{ .Values.clickhouse.external.username }}:${CLICKHOUSE_PASSWORD}@{{ .Values.clickhouse.external.host }}:{{ .Values.clickhouse.external.httpPort | default 8123 }}?secure={{ $secure }}
298+
{{- else -}}
201299
{{ $protocol }}://{{ .Values.clickhouse.external.username }}:{{ .Values.clickhouse.external.password }}@{{ .Values.clickhouse.external.host }}:{{ .Values.clickhouse.external.httpPort | default 8123 }}?secure={{ $secure }}
202300
{{- end -}}
301+
{{- end -}}
203302
{{- end }}
204303

205304
{{/*
@@ -211,8 +310,12 @@ ClickHouse URL for replication (without secure parameter)
211310
{{ $protocol }}://{{ .Values.clickhouse.auth.username }}:{{ .Values.clickhouse.auth.password }}@{{ include "trigger-v4.clickhouse.hostname" . }}:8123
212311
{{- else if .Values.clickhouse.external.host -}}
213312
{{- $protocol := ternary "https" "http" .Values.clickhouse.external.secure -}}
313+
{{- if .Values.clickhouse.external.existingSecret -}}
314+
{{ $protocol }}://{{ .Values.clickhouse.external.username }}:${CLICKHOUSE_PASSWORD}@{{ .Values.clickhouse.external.host }}:{{ .Values.clickhouse.external.httpPort | default 8123 }}
315+
{{- else -}}
214316
{{ $protocol }}://{{ .Values.clickhouse.external.username }}:{{ .Values.clickhouse.external.password }}@{{ .Values.clickhouse.external.host }}:{{ .Values.clickhouse.external.httpPort | default 8123 }}
215317
{{- end -}}
318+
{{- end -}}
216319
{{- end }}
217320

218321
{{/*
@@ -266,14 +369,27 @@ Registry connection details
266369
{{- end -}}
267370
{{- end }}
268371

372+
{{/*
373+
Webapp connectivity check enabled
374+
*/}}
375+
{{- define "trigger-v4.webapp.connectivityCheckEnabled" -}}
376+
{{- $connectivityCheckEnabled := true -}}
377+
{{- if hasKey .Values.webapp "connectivityCheck" -}}
378+
{{- if hasKey .Values.webapp.connectivityCheck "postgres" -}}
379+
{{- $connectivityCheckEnabled = .Values.webapp.connectivityCheck.postgres -}}
380+
{{- end -}}
381+
{{- end -}}
382+
{{- $connectivityCheckEnabled -}}
383+
{{- end }}
384+
269385
{{/*
270386
PostgreSQL host (for wait-for-it script)
271387
*/}}
272388
{{- define "trigger-v4.postgres.host" -}}
273-
{{- if .Values.postgres.external.host -}}
274-
{{ .Values.postgres.external.host }}:{{ .Values.postgres.external.port | default 5432 }}
275-
{{- else if .Values.postgres.deploy -}}
389+
{{- if .Values.postgres.deploy -}}
276390
{{ include "trigger-v4.postgres.hostname" . }}:5432
391+
{{- else if .Values.postgres.external.connectivityCheck.host -}}
392+
{{ .Values.postgres.external.connectivityCheck.host }}
277393
{{- end -}}
278394
{{- end }}
279395

hosting/k8s/helm/templates/secrets.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,20 @@ data:
1313
MANAGED_WORKER_SECRET: {{ .Values.secrets.managedWorkerSecret | b64enc | quote }}
1414
OBJECT_STORE_ACCESS_KEY_ID: {{ .Values.secrets.objectStore.accessKeyId | b64enc | quote }}
1515
OBJECT_STORE_SECRET_ACCESS_KEY: {{ .Values.secrets.objectStore.secretAccessKey | b64enc | quote }}
16+
{{- if and .Values.postgres.external.databaseUrl (not .Values.postgres.external.existingSecret) }}
17+
postgres-database-url: {{ .Values.postgres.external.databaseUrl | b64enc | quote }}
18+
{{- if .Values.postgres.external.directUrl }}
19+
postgres-direct-url: {{ .Values.postgres.external.directUrl | b64enc | quote }}
20+
{{- else }}
21+
postgres-direct-url: {{ .Values.postgres.external.databaseUrl | b64enc | quote }}
22+
{{- end }}
23+
{{- end }}
24+
{{- if and .Values.redis.external.host (not .Values.redis.external.existingSecret) .Values.redis.external.password }}
25+
redis-password: {{ .Values.redis.external.password | b64enc | quote }}
26+
{{- end }}
27+
{{- if and .Values.clickhouse.external.host (not .Values.clickhouse.external.existingSecret) .Values.clickhouse.external.password }}
28+
clickhouse-password: {{ .Values.clickhouse.external.password | b64enc | quote }}
29+
{{- end }}
1630
{{- end }}
1731
---
1832
{{- if and .Values.registry.deploy .Values.registry.auth.enabled }}

hosting/k8s/helm/templates/validate-external-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ Validation template to ensure external service configurations are provided when
33
This template will fail the Helm deployment if external config is missing for required services
44
*/}}
55
{{- if not .Values.postgres.deploy }}
6-
{{- if or (not .Values.postgres.external.host) (not .Values.postgres.external.database) (not .Values.postgres.external.username) }}
7-
{{- fail "PostgreSQL external configuration is required when postgres.deploy=false. Please provide postgres.external.host, postgres.external.database, and postgres.external.username" }}
6+
{{- if and (not .Values.postgres.external.databaseUrl) (not .Values.postgres.external.existingSecret) }}
7+
{{- fail "PostgreSQL external configuration is required when postgres.deploy=false. Please provide either postgres.external.databaseUrl or postgres.external.existingSecret" }}
88
{{- end }}
99
{{- end }}
1010

hosting/k8s/helm/templates/webapp.yaml

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,17 +180,38 @@ spec:
180180
value: {{ .Values.webapp.apiOrigin | quote }}
181181
- name: ELECTRIC_ORIGIN
182182
value: {{ include "trigger-v4.electric.url" . | quote }}
183+
{{- if include "trigger-v4.postgres.useSecretUrl" . }}
183184
- name: DATABASE_URL
184-
value: {{ include "trigger-v4.postgres.connectionString" . | quote }}
185+
valueFrom:
186+
secretKeyRef:
187+
name: {{ include "trigger-v4.postgres.external.secretName" . }}
188+
key: {{ include "trigger-v4.postgres.external.databaseUrlKey" . }}
185189
- name: DIRECT_URL
190+
valueFrom:
191+
secretKeyRef:
192+
name: {{ include "trigger-v4.postgres.external.secretName" . }}
193+
key: {{ include "trigger-v4.postgres.external.directUrlKey" . }}
194+
{{- else }}
195+
- name: DATABASE_URL
186196
value: {{ include "trigger-v4.postgres.connectionString" . | quote }}
197+
- name: DIRECT_URL
198+
value: {{ include "trigger-v4.postgres.directUrl" . | quote }}
199+
{{- end }}
200+
{{- if and (include "trigger-v4.webapp.connectivityCheckEnabled" .) (include "trigger-v4.postgres.host" .) }}
187201
- name: DATABASE_HOST
188202
value: {{ include "trigger-v4.postgres.host" . | quote }}
203+
{{- end }}
189204
- name: REDIS_HOST
190205
value: {{ include "trigger-v4.redis.host" . | quote }}
191206
- name: REDIS_PORT
192207
value: {{ include "trigger-v4.redis.port" . | quote }}
193-
{{- if include "trigger-v4.redis.password" . }}
208+
{{- if and .Values.redis.external.host .Values.redis.external.existingSecret }}
209+
- name: REDIS_PASSWORD
210+
valueFrom:
211+
secretKeyRef:
212+
name: {{ include "trigger-v4.redis.external.secretName" . }}
213+
key: {{ include "trigger-v4.redis.external.passwordKey" . }}
214+
{{- else if include "trigger-v4.redis.password" . }}
194215
- name: REDIS_PASSWORD
195216
value: {{ include "trigger-v4.redis.password" . | quote }}
196217
{{- end }}
@@ -308,6 +329,13 @@ spec:
308329
- name: INTERNAL_OTEL_METRIC_EXPORTER_INTERVAL_MS
309330
value: {{ .Values.webapp.observability.metrics.exporterIntervalMs | quote }}
310331
{{- end }}
332+
{{- if and .Values.clickhouse.external.host .Values.clickhouse.external.existingSecret }}
333+
- name: CLICKHOUSE_PASSWORD
334+
valueFrom:
335+
secretKeyRef:
336+
name: {{ include "trigger-v4.clickhouse.external.secretName" . }}
337+
key: {{ include "trigger-v4.clickhouse.external.passwordKey" . }}
338+
{{- end }}
311339
- name: CLICKHOUSE_URL
312340
value: {{ include "trigger-v4.clickhouse.url" . | quote }}
313341
- name: CLICKHOUSE_LOG_LEVEL

hosting/k8s/helm/values.yaml

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ webapp:
104104
# cpu: 500m
105105
# memory: 1Gi
106106

107+
# Connectivity check configuration
108+
connectivityCheck:
109+
postgres: true # Set to false to disable DATABASE_HOST env var (overrides postgres.external.connectivityCheck)
110+
107111
# Extra environment variables for webapp
108112
extraEnvVars:
109113
[]
@@ -114,6 +118,10 @@ webapp:
114118
# secretKeyRef:
115119
# name: my-secret
116120
# key: secret-key
121+
#
122+
# Example: PostgreSQL SSL with custom CA certificate
123+
# - name: NODE_EXTRA_CA_CERTS
124+
# value: "/etc/ssl/certs/postgres-ca.crt"
117125

118126
# Extra volumes for the webapp pod
119127
extraVolumes:
@@ -124,6 +132,14 @@ webapp:
124132
# - name: secret-volume
125133
# secret:
126134
# secretName: my-secret
135+
#
136+
# Example: PostgreSQL SSL CA certificate volume
137+
# - name: postgres-ca-cert
138+
# secret:
139+
# secretName: postgres-ca-secret
140+
# items:
141+
# - key: ca.crt
142+
# path: postgres-ca.crt
127143

128144
# Extra volume mounts for the webapp container
129145
extraVolumeMounts:
@@ -134,6 +150,11 @@ webapp:
134150
# - name: secret-volume
135151
# mountPath: /etc/secrets
136152
# readOnly: true
153+
#
154+
# Example: PostgreSQL SSL CA certificate mount
155+
# - name: postgres-ca-cert
156+
# mountPath: /etc/ssl/certs
157+
# readOnly: true
137158

138159
# ServiceMonitor for Prometheus monitoring
139160
serviceMonitor:
@@ -363,15 +384,29 @@ postgres:
363384
# Custom connection settings
364385
connection:
365386
schema: "public"
366-
sslMode: "disable" # Use "require" or "verify-full" for production
387+
sslMode: "disable" # Use "require" or "verify-full" for production with custom CA
367388

368389
# External PostgreSQL connection (when deploy: false)
369390
external:
370-
host: ""
371-
port: 5432
372-
database: ""
373-
username: ""
374-
password: ""
391+
# Database URL configuration - simplified approach using URLs instead of individual parameters
392+
databaseUrl: "" # Full PostgreSQL connection URL (e.g., postgresql://user:pass@host:port/db?schema=public&sslmode=prefer)
393+
directUrl: "" # Optional: Direct URL for migrations (if not set, databaseUrl will be used)
394+
#
395+
# Optional: Connectivity check configuration during webapp startup
396+
connectivityCheck:
397+
host: "" # Optional: hostname:port for wait-for-it script (e.g., "postgres.example.com:5432")
398+
#
399+
# Secure credential management
400+
existingSecret: "" # Name of existing secret containing DATABASE_URL
401+
secretKeys:
402+
databaseUrlKey: "postgres-database-url" # Key in existing secret containing complete DATABASE_URL
403+
directUrlKey: "postgres-direct-url" # Key in existing secret containing direct URL (optional)
404+
#
405+
# Example: For SSL connections with custom CA (e.g., AWS RDS):
406+
# 1. Set connection.sslMode to "require" or "verify-full"
407+
# 2. Create a secret with your CA certificate:
408+
# kubectl create secret generic postgres-ca-secret --from-file=ca.crt=/path/to/rds-ca-cert.pem
409+
# 3. Configure extraVolumes, extraVolumeMounts, and extraEnvVars (see webapp section above)
375410

376411
# Redis configuration
377412
redis:
@@ -394,9 +429,13 @@ redis:
394429
external:
395430
host: ""
396431
port: 6379
397-
password: ""
432+
password: "" # Optional - ignored if existingSecret is set
398433
tls:
399-
enabled: false # Set to true for Redis instances requiring TLS (e.g., AWS ElastiCache)
434+
enabled: false # Set to true for Redis instances requiring TLS (e.g., AWS ElastiCache)
435+
#
436+
# Secure credential management
437+
existingSecret: "" # Name of existing secret containing password
438+
existingSecretPasswordKey: "redis-password" # Key in existing secret containing password
400439

401440
# Electric configuration
402441
electric:
@@ -488,8 +527,12 @@ clickhouse:
488527
httpPort: 8123
489528
nativePort: 9000
490529
username: ""
491-
password: ""
530+
password: "" # Optional - ignored if existingSecret is set
492531
secure: false # Set to true for external secure connections
532+
#
533+
# Secure credential management
534+
existingSecret: "" # Name of existing secret containing password
535+
existingSecretKey: "clickhouse-password" # Key in existing secret containing password
493536

494537
# ClickHouse configuration override
495538
# These defaults are based on official recommendations for systems with <16GB RAM:

0 commit comments

Comments
 (0)