diff --git a/charts/langfuse/templates/_helpers.tpl b/charts/langfuse/templates/_helpers.tpl index 6198aad3..7edcbbb8 100644 --- a/charts/langfuse/templates/_helpers.tpl +++ b/charts/langfuse/templates/_helpers.tpl @@ -162,15 +162,20 @@ Get value of a specific environment variable from additionalEnv if it exists If DATABASE_URL is set, we do nothing in databaseEnv. */}} {{- else -}} +{{- with (include "langfuse.getValueOrSecret" (dict "key" "postgresql.host" "value" .Values.postgresql.host) ) }} +- name: DATABASE_HOST + {{- . | nindent 2 }} +{{- else }} - name: DATABASE_HOST value: {{ include "langfuse.postgresql.hostname" . | quote }} -{{- if .Values.postgresql.port }} +{{- end }} +{{- with (include "langfuse.getValueOrSecret" (dict "key" "postgresql.port" "value" .Values.postgresql.port) ) }} - name: DATABASE_PORT - value: {{ .Values.postgresql.port | quote }} + {{- . | nindent 2 }} {{- end }} -{{- if .Values.postgresql.auth.username }} +{{- with (include "langfuse.getValueOrSecret" (dict "key" "postgresql.auth.username" "value" .Values.postgresql.auth.username) ) }} - name: DATABASE_USERNAME - value: {{ .Values.postgresql.auth.username | quote }} + {{- . | nindent 2 }} {{- end }} - name: DATABASE_PASSWORD {{- if .Values.postgresql.auth.existingSecret }} @@ -179,24 +184,30 @@ Get value of a specific environment variable from additionalEnv if it exists name: {{ .Values.postgresql.auth.existingSecret }} key: {{ required "postgresql.auth.secretKeys.userPasswordKey is required when using an existing secret" .Values.postgresql.auth.secretKeys.userPasswordKey }} {{- else }} - value: {{ required "Using an existing secret or postgresql.auth.password is required" .Values.postgresql.auth.password | quote }} + {{- $pgPassword := .Values.postgresql.auth.password -}} + {{- if kindIs "map" $pgPassword -}} + {{- /* Support password as { value, secretKeyRef } */ -}} + {{- include "langfuse.getRequiredValueOrSecret" (dict "key" "postgresql.auth.password" "value" $pgPassword) | nindent 2 }} + {{- else -}} + value: {{ required "Using an existing secret or postgresql.auth.password is required" $pgPassword | quote }} + {{- end }} {{- end }} {{- end }} -{{- if .Values.postgresql.auth.database }} +{{- with (include "langfuse.getValueOrSecret" (dict "key" "postgresql.auth.database" "value" .Values.postgresql.auth.database) ) }} - name: DATABASE_NAME - value: {{ .Values.postgresql.auth.database | quote }} + {{- . | nindent 2 }} {{- end }} {{- if .Values.postgresql.args }} - name: DATABASE_ARGS value: {{ .Values.postgresql.args | quote }} {{- end }} -{{- if .Values.postgresql.directUrl }} +{{- with (include "langfuse.getValueOrSecret" (dict "key" "postgresql.directUrl" "value" .Values.postgresql.directUrl) ) }} - name: DIRECT_URL - value: {{ .Values.postgresql.directUrl | quote }} + {{- . | nindent 2 }} {{- end }} -{{- if .Values.postgresql.shadowDatabaseUrl }} +{{- with (include "langfuse.getValueOrSecret" (dict "key" "postgresql.shadowDatabaseUrl" "value" .Values.postgresql.shadowDatabaseUrl) ) }} - name: SHADOW_DATABASE_URL - value: {{ .Values.postgresql.shadowDatabaseUrl | quote }} + {{- . | nindent 2 }} {{- end }} - name: LANGFUSE_AUTO_POSTGRES_MIGRATION_DISABLED value: {{ not .Values.postgresql.migration.autoMigrate | quote }} @@ -275,6 +286,12 @@ Get value of a specific environment variable from additionalEnv if it exists Compare with https://langfuse.com/self-hosting/configuration#environment-variables */}} {{- define "langfuse.redisEnv" -}} +{{- if not (include "langfuse.getEnvVar" (dict "env" $.Values.langfuse.additionalEnv "name" "REDIS_CONNECTION_STRING")) }} +{{- /* Prefer explicit connectionString if provided (supports value or secretKeyRef) */}} +{{- if or (.Values.redis.connectionString.value) (and .Values.redis.connectionString.secretKeyRef.name .Values.redis.connectionString.secretKeyRef.key) }} +- name: REDIS_CONNECTION_STRING + {{- include "langfuse.getRequiredValueOrSecret" (dict "key" "redis.connectionString" "value" .Values.redis.connectionString) | nindent 2 }} +{{- else }} {{- if or .Values.redis.auth.existingSecret .Values.redis.auth.password }} - name: REDIS_PASSWORD {{- if .Values.redis.auth.existingSecret }} @@ -283,15 +300,21 @@ Get value of a specific environment variable from additionalEnv if it exists name: {{ .Values.redis.auth.existingSecret }} key: {{ required "redis.auth.existingSecretPasswordKey is required when using an existing secret" .Values.redis.auth.existingSecretPasswordKey }} {{- else }} - value: {{ required "Using an existing secret or redis.auth.password is required" .Values.redis.auth.password | quote }} + {{- $redisPassword := .Values.redis.auth.password -}} + {{- if kindIs "map" $redisPassword -}} + {{- /* Support password as { value, secretKeyRef } */ -}} + {{- include "langfuse.getRequiredValueOrSecret" (dict "key" "redis.auth.password" "value" $redisPassword) | nindent 2 }} + {{- else -}} + value: {{ required "Using an existing secret or redis.auth.password is required" $redisPassword | quote }} + {{- end }} {{- end }} {{- end }} -{{- if not (include "langfuse.getEnvVar" (dict "env" $.Values.langfuse.additionalEnv "name" "REDIS_CONNECTION_STRING")) }} - name: REDIS_TLS_ENABLED value: {{ .Values.redis.tls.enabled | quote }} - name: REDIS_CONNECTION_STRING value: "{{ if .Values.redis.tls.enabled }}rediss{{ else }}redis{{ end }}://{{ .Values.redis.auth.username }}:$(REDIS_PASSWORD)@{{ include "langfuse.redis.hostname" . }}:{{ .Values.redis.port }}/{{ .Values.redis.auth.database }}" {{- end }} +{{- end }} {{- if .Values.redis.tls.enabled }} {{- if .Values.redis.tls.caPath }} - name: REDIS_TLS_CA_PATH @@ -416,24 +439,45 @@ Return ClickHouse protocol (http or https) {{- . | nindent 2 }} {{- end }} {{- end }} -- name: LANGFUSE_S3_EVENT_UPLOAD_BUCKET -{{- if $.Values.s3.deploy }} - value: {{ required "s3.[eventUpload].bucket is required" (coalesce .Values.s3.eventUpload.bucket .Values.s3.bucket .Values.s3.defaultBuckets) | quote }} -{{- else }} - value: {{ required "s3.[eventUpload].bucket is required" (.Values.s3.eventUpload.bucket | default .Values.s3.bucket) | quote }} -{{- end }} + {{- /* Event Upload Bucket: prefer map or fallback to strings */}} + - name: LANGFUSE_S3_EVENT_UPLOAD_BUCKET + {{- if kindIs "map" .Values.s3.eventUpload.bucket }} + {{- include "langfuse.getRequiredValueOrSecret" (dict "key" ".Values.s3.eventUpload.bucket" "value" .Values.s3.eventUpload.bucket) | nindent 2 }} + {{- else if kindIs "map" .Values.s3.bucket }} + {{- include "langfuse.getRequiredValueOrSecret" (dict "key" ".Values.s3.bucket" "value" .Values.s3.bucket) | nindent 2 }} + {{- else }} + {{- if $.Values.s3.deploy }} + value: {{ required "s3.[eventUpload].bucket is required" (coalesce .Values.s3.eventUpload.bucket .Values.s3.bucket .Values.s3.defaultBuckets) | quote }} + {{- else }} + value: {{ required "s3.[eventUpload].bucket is required" (.Values.s3.eventUpload.bucket | default .Values.s3.bucket) | quote }} + {{- end }} + {{- end }} {{- if .Values.s3.eventUpload.prefix }} - name: LANGFUSE_S3_EVENT_UPLOAD_PREFIX value: {{ .Values.s3.eventUpload.prefix | quote }} {{- end }} -{{- if or .Values.s3.eventUpload.region .Values.s3.region }} -- name: LANGFUSE_S3_EVENT_UPLOAD_REGION - value: {{ .Values.s3.eventUpload.region | default .Values.s3.region | quote }} -{{- end }} -{{- if or .Values.s3.eventUpload.endpoint .Values.s3.endpoint .Values.s3.deploy }} -- name: LANGFUSE_S3_EVENT_UPLOAD_ENDPOINT - value: {{ .Values.s3.eventUpload.endpoint | default .Values.s3.endpoint | default (include "langfuse.s3.endpoint" .) | quote }} -{{- end }} + {{- /* Event Upload Region: map support */}} + {{- if or (kindIs "map" .Values.s3.eventUpload.region) (kindIs "map" .Values.s3.region) (or .Values.s3.eventUpload.region .Values.s3.region) }} + - name: LANGFUSE_S3_EVENT_UPLOAD_REGION + {{- if kindIs "map" .Values.s3.eventUpload.region }} + {{- include "langfuse.getRequiredValueOrSecret" (dict "key" ".Values.s3.eventUpload.region" "value" .Values.s3.eventUpload.region) | nindent 2 }} + {{- else if kindIs "map" .Values.s3.region }} + {{- include "langfuse.getRequiredValueOrSecret" (dict "key" ".Values.s3.region" "value" .Values.s3.region) | nindent 2 }} + {{- else }} + value: {{ .Values.s3.eventUpload.region | default .Values.s3.region | quote }} + {{- end }} + {{- end }} + {{- /* Event Upload Endpoint: map support */}} + {{- if or (kindIs "map" .Values.s3.eventUpload.endpoint) (kindIs "map" .Values.s3.endpoint) .Values.s3.eventUpload.endpoint .Values.s3.endpoint .Values.s3.deploy }} + - name: LANGFUSE_S3_EVENT_UPLOAD_ENDPOINT + {{- if kindIs "map" .Values.s3.eventUpload.endpoint }} + {{- include "langfuse.getRequiredValueOrSecret" (dict "key" ".Values.s3.eventUpload.endpoint" "value" .Values.s3.eventUpload.endpoint) | nindent 2 }} + {{- else if kindIs "map" .Values.s3.endpoint }} + {{- include "langfuse.getRequiredValueOrSecret" (dict "key" ".Values.s3.endpoint" "value" .Values.s3.endpoint) | nindent 2 }} + {{- else }} + value: {{ .Values.s3.eventUpload.endpoint | default .Values.s3.endpoint | default (include "langfuse.s3.endpoint" .) | quote }} + {{- end }} + {{- end }} {{- with (include "langfuse.getS3ValueOrSecret" (dict "key" "accessKeyId" "bucket" "eventUpload" "values" .Values.s3) ) }} - name: LANGFUSE_S3_EVENT_UPLOAD_ACCESS_KEY_ID {{- . | nindent 2 }} @@ -473,24 +517,42 @@ Return ClickHouse protocol (http or https) - name: LANGFUSE_S3_BATCH_EXPORT_ENABLED value: {{ .Values.s3.batchExport.enabled | quote }} {{- if $.Values.s3.batchExport.enabled }} -- name: LANGFUSE_S3_BATCH_EXPORT_BUCKET -{{- if $.Values.s3.deploy }} - value: {{ required "s3.[batchExport].bucket is required" (coalesce .Values.s3.batchExport.bucket .Values.s3.bucket .Values.s3.defaultBuckets) | quote }} -{{- else }} - value: {{ required "s3.[batchExport].bucket is required" (.Values.s3.batchExport.bucket | default .Values.s3.bucket) | quote }} -{{- end }} + - name: LANGFUSE_S3_BATCH_EXPORT_BUCKET + {{- if kindIs "map" .Values.s3.batchExport.bucket }} + {{- include "langfuse.getRequiredValueOrSecret" (dict "key" ".Values.s3.batchExport.bucket" "value" .Values.s3.batchExport.bucket) | nindent 2 }} + {{- else if kindIs "map" .Values.s3.bucket }} + {{- include "langfuse.getRequiredValueOrSecret" (dict "key" ".Values.s3.bucket" "value" .Values.s3.bucket) | nindent 2 }} + {{- else }} + {{- if $.Values.s3.deploy }} + value: {{ required "s3.[batchExport].bucket is required" (coalesce .Values.s3.batchExport.bucket .Values.s3.bucket .Values.s3.defaultBuckets) | quote }} + {{- else }} + value: {{ required "s3.[batchExport].bucket is required" (.Values.s3.batchExport.bucket | default .Values.s3.bucket) | quote }} + {{- end }} + {{- end }} {{- if or .Values.s3.batchExport.prefix .Values.s3.prefix }} - name: LANGFUSE_S3_BATCH_EXPORT_PREFIX value: {{ .Values.s3.batchExport.prefix | default .Values.s3.prefix | quote }} {{- end }} -{{- if or .Values.s3.batchExport.region .Values.s3.region }} -- name: LANGFUSE_S3_BATCH_EXPORT_REGION - value: {{ .Values.s3.batchExport.region | default .Values.s3.region | quote }} -{{- end }} -{{- if or .Values.s3.batchExport.endpoint .Values.s3.endpoint .Values.s3.deploy }} -- name: LANGFUSE_S3_BATCH_EXPORT_ENDPOINT - value: {{ .Values.s3.batchExport.endpoint | default .Values.s3.endpoint | default (include "langfuse.s3.endpoint" .) | quote }} -{{- end }} + {{- if or (kindIs "map" .Values.s3.batchExport.region) (kindIs "map" .Values.s3.region) (or .Values.s3.batchExport.region .Values.s3.region) }} + - name: LANGFUSE_S3_BATCH_EXPORT_REGION + {{- if kindIs "map" .Values.s3.batchExport.region }} + {{- include "langfuse.getRequiredValueOrSecret" (dict "key" ".Values.s3.batchExport.region" "value" .Values.s3.batchExport.region) | nindent 2 }} + {{- else if kindIs "map" .Values.s3.region }} + {{- include "langfuse.getRequiredValueOrSecret" (dict "key" ".Values.s3.region" "value" .Values.s3.region) | nindent 2 }} + {{- else }} + value: {{ .Values.s3.batchExport.region | default .Values.s3.region | quote }} + {{- end }} + {{- end }} + {{- if or (kindIs "map" .Values.s3.batchExport.endpoint) (kindIs "map" .Values.s3.endpoint) .Values.s3.batchExport.endpoint .Values.s3.endpoint .Values.s3.deploy }} + - name: LANGFUSE_S3_BATCH_EXPORT_ENDPOINT + {{- if kindIs "map" .Values.s3.batchExport.endpoint }} + {{- include "langfuse.getRequiredValueOrSecret" (dict "key" ".Values.s3.batchExport.endpoint" "value" .Values.s3.batchExport.endpoint) | nindent 2 }} + {{- else if kindIs "map" .Values.s3.endpoint }} + {{- include "langfuse.getRequiredValueOrSecret" (dict "key" ".Values.s3.endpoint" "value" .Values.s3.endpoint) | nindent 2 }} + {{- else }} + value: {{ .Values.s3.batchExport.endpoint | default .Values.s3.endpoint | default (include "langfuse.s3.endpoint" .) | quote }} + {{- end }} + {{- end }} {{- with (include "langfuse.getS3ValueOrSecret" (dict "key" "accessKeyId" "bucket" "batchExport" "values" .Values.s3) ) }} - name: LANGFUSE_S3_BATCH_EXPORT_ACCESS_KEY_ID {{- . | nindent 2 }} @@ -528,24 +590,42 @@ Return ClickHouse protocol (http or https) value: {{ .Values.s3.batchExport.forcePathStyle | default .Values.s3.forcePathStyle | quote }} {{- end }} {{- end }} -- name: LANGFUSE_S3_MEDIA_UPLOAD_BUCKET -{{- if $.Values.s3.deploy }} - value: {{ required "s3.[mediaUpload].bucket is required" (coalesce .Values.s3.mediaUpload.bucket .Values.s3.bucket .Values.s3.defaultBuckets) | quote }} -{{- else }} - value: {{ required "s3.[mediaUpload].bucket is required" (.Values.s3.mediaUpload.bucket | default .Values.s3.bucket) | quote }} -{{- end }} + - name: LANGFUSE_S3_MEDIA_UPLOAD_BUCKET + {{- if kindIs "map" .Values.s3.mediaUpload.bucket }} + {{- include "langfuse.getRequiredValueOrSecret" (dict "key" ".Values.s3.mediaUpload.bucket" "value" .Values.s3.mediaUpload.bucket) | nindent 2 }} + {{- else if kindIs "map" .Values.s3.bucket }} + {{- include "langfuse.getRequiredValueOrSecret" (dict "key" ".Values.s3.bucket" "value" .Values.s3.bucket) | nindent 2 }} + {{- else }} + {{- if $.Values.s3.deploy }} + value: {{ required "s3.[mediaUpload].bucket is required" (coalesce .Values.s3.mediaUpload.bucket .Values.s3.bucket .Values.s3.defaultBuckets) | quote }} + {{- else }} + value: {{ required "s3.[mediaUpload].bucket is required" (.Values.s3.mediaUpload.bucket | default .Values.s3.bucket) | quote }} + {{- end }} + {{- end }} {{- if or .Values.s3.mediaUpload.prefix .Values.s3.prefix }} - name: LANGFUSE_S3_MEDIA_UPLOAD_PREFIX value: {{ .Values.s3.mediaUpload.prefix | default .Values.s3.prefix | quote }} {{- end }} -{{- if or .Values.s3.mediaUpload.region .Values.s3.region }} -- name: LANGFUSE_S3_MEDIA_UPLOAD_REGION - value: {{ .Values.s3.mediaUpload.region | default .Values.s3.region | quote }} -{{- end }} -{{- if or .Values.s3.mediaUpload.endpoint .Values.s3.endpoint .Values.s3.deploy }} -- name: LANGFUSE_S3_MEDIA_UPLOAD_ENDPOINT - value: {{ .Values.s3.mediaUpload.endpoint | default .Values.s3.endpoint | default (include "langfuse.s3.endpoint" .) | quote }} -{{- end }} + {{- if or (kindIs "map" .Values.s3.mediaUpload.region) (kindIs "map" .Values.s3.region) (or .Values.s3.mediaUpload.region .Values.s3.region) }} + - name: LANGFUSE_S3_MEDIA_UPLOAD_REGION + {{- if kindIs "map" .Values.s3.mediaUpload.region }} + {{- include "langfuse.getRequiredValueOrSecret" (dict "key" ".Values.s3.mediaUpload.region" "value" .Values.s3.mediaUpload.region) | nindent 2 }} + {{- else if kindIs "map" .Values.s3.region }} + {{- include "langfuse.getRequiredValueOrSecret" (dict "key" ".Values.s3.region" "value" .Values.s3.region) | nindent 2 }} + {{- else }} + value: {{ .Values.s3.mediaUpload.region | default .Values.s3.region | quote }} + {{- end }} + {{- end }} + {{- if or (kindIs "map" .Values.s3.mediaUpload.endpoint) (kindIs "map" .Values.s3.endpoint) .Values.s3.mediaUpload.endpoint .Values.s3.endpoint .Values.s3.deploy }} + - name: LANGFUSE_S3_MEDIA_UPLOAD_ENDPOINT + {{- if kindIs "map" .Values.s3.mediaUpload.endpoint }} + {{- include "langfuse.getRequiredValueOrSecret" (dict "key" ".Values.s3.mediaUpload.endpoint" "value" .Values.s3.mediaUpload.endpoint) | nindent 2 }} + {{- else if kindIs "map" .Values.s3.endpoint }} + {{- include "langfuse.getRequiredValueOrSecret" (dict "key" ".Values.s3.endpoint" "value" .Values.s3.endpoint) | nindent 2 }} + {{- else }} + value: {{ .Values.s3.mediaUpload.endpoint | default .Values.s3.endpoint | default (include "langfuse.s3.endpoint" .) | quote }} + {{- end }} + {{- end }} {{- with (include "langfuse.getS3ValueOrSecret" (dict "key" "accessKeyId" "bucket" "mediaUpload" "values" .Values.s3) ) }} - name: LANGFUSE_S3_MEDIA_UPLOAD_ACCESS_KEY_ID {{- . | nindent 2 }} diff --git a/charts/langfuse/templates/validations.yaml b/charts/langfuse/templates/validations.yaml index 5e087f3e..d5080501 100644 --- a/charts/langfuse/templates/validations.yaml +++ b/charts/langfuse/templates/validations.yaml @@ -44,7 +44,8 @@ {{- fail "MinIO requires s3 to be deployed with a forcePathStyle. Set s3.forcePathStyle or s3.eventUpload.forcePathStyle to continue." -}} {{- end -}} -{{- if and (not $.Values.s3.deploy) (not (or $.Values.s3.bucket $.Values.s3.eventUpload.bucket)) -}} +{{- $bucketConfigured := or (and (kindIs "map" $.Values.s3.bucket) (or $.Values.s3.bucket.value $.Values.s3.bucket.secretKeyRef.name)) (and (not (kindIs "map" $.Values.s3.bucket)) $.Values.s3.bucket) (and (kindIs "map" $.Values.s3.eventUpload.bucket) (or $.Values.s3.eventUpload.bucket.value $.Values.s3.eventUpload.bucket.secretKeyRef.name)) (and (not (kindIs "map" $.Values.s3.eventUpload.bucket)) $.Values.s3.eventUpload.bucket) -}} +{{- if and (not $.Values.s3.deploy) (not $bucketConfigured) -}} {{- fail "S3 bucket must be configured for external provider. Set s3.bucket or s3.eventUpload.bucket to continue." -}} {{- end -}} diff --git a/charts/langfuse/values.yaml b/charts/langfuse/values.yaml index d886f8f3..e5b07359 100644 --- a/charts/langfuse/values.yaml +++ b/charts/langfuse/values.yaml @@ -394,10 +394,18 @@ postgresql: # -- Enable PostgreSQL deployment (via Bitnami Helm Chart). If you want to use an external Postgres server (or a managed one), set this to false deploy: true - # -- PostgreSQL host to connect to. If postgresql.deploy is true, this will be set automatically based on the release name. - host: "" - # -- Port of the postgres server to use. Defaults to 5432. - port: null + # -- PostgreSQL host to connect to. If postgresql.deploy is true, this will be set automatically based on the release name. Can be configured by value or existing secret reference. + host: + value: "" + secretKeyRef: + name: "" + key: "" + # -- Port of the postgres server to use. Defaults to 5432. Can be configured by value or existing secret reference. + port: + value: null + secretKeyRef: + name: "" + key: "" # -- Additional database connection arguments args: "" @@ -407,10 +415,33 @@ postgresql: # -- If your database user lacks the CREATE DATABASE permission, you must create a shadow database and configure the "SHADOW_DATABASE_URL". This is often the case if you use a Cloud database. Refer to the Prisma docs for detailed instructions. shadowDatabaseUrl: "" + # -- Optional references to a secret to fetch database connection details + secretRefs: + # -- Reference to a secret for the database host + host: + name: "" + key: "" + # -- Reference to a secret for the database port + port: + name: "" + key: "" + # -- Reference to a secret for the database username + username: + name: "" + key: "" + # -- Reference to a secret for the database name + database: + name: "" + key: "" + # Authentication configuration auth: - # -- Username to use to connect to the postgres database deployed with Langfuse. In case `postgresql.deploy` is set to `true`, the user will be created automatically. - username: postgres + # -- Username to use to connect to the postgres database deployed with Langfuse. In case `postgresql.deploy` is set to `true`, the user will be created automatically. Can be configured by value or existing secret reference. + username: + value: "postgres" + secretKeyRef: + name: "" + key: "" # -- Password to use to connect to the postgres database deployed with Langfuse. In case `postgresql.deploy` is set to `true`, the password will be set automatically. password: "" # -- If you want to use an existing secret for the postgres password, set the name of the secret here. (`postgresql.auth.username` and `postgresql.auth.password` will be ignored and picked up from this secret). @@ -418,8 +449,12 @@ postgresql: # -- The key in the existing secret that contains the password. secretKeys: userPasswordKey: password - # -- Database name to use for Langfuse. - database: postgres_langfuse + # -- Database name to use for Langfuse. Can be configured by value or existing secret reference. + database: + value: "postgres_langfuse" + secretKeyRef: + name: "" + key: "" # -- Additional database connection arguments args: "" @@ -440,10 +475,18 @@ redis: # -- Enable valkey deployment (via Bitnami Helm Chart). If you want to use a Redis or Valkey server already deployed, set to false. deploy: true - # -- Redis host to connect to. If redis.deploy is true, this will be set automatically based on the release name. - host: "" - # -- Redis port to connect to. - port: 6379 + # -- Redis host to connect to. If redis.deploy is true, this will be set automatically based on the release name. Can be configured by value or existing secret reference. + host: + value: "" + secretKeyRef: + name: "" + key: "" + # -- Redis port to connect to. Can be configured by value or existing secret reference. + port: + value: 6379 + secretKeyRef: + name: "" + key: "" # Redis TLS configuration tls: @@ -458,8 +501,12 @@ redis: # Authentication configuration auth: - # -- Username to use to connect to the redis database deployed with Langfuse. In case `redis.deploy` is set to `true`, the user will be created automatically. Set to null for an empty username in the connection string. - username: "default" + # -- Username to use to connect to the redis database deployed with Langfuse. In case `redis.deploy` is set to `true`, the user will be created automatically. Set to null for an empty username in the connection string. Can be configured by value or existing secret reference. + username: + value: "default" + secretKeyRef: + name: "" + key: "" # -- Configure the password by value or existing secret reference. Use URL-encoded passwords or avoid special characters in the password. password: "" # -- If you want to use an existing secret for the redis password, set the name of the secret here. (`redis.auth.password` will be ignored and picked up from this secret). @@ -472,6 +519,12 @@ redis: # Subchart specific settings architecture: standalone primary: + # -- Optional: Direct Redis connection string. If set, takes precedence over host/port/username/password. Can be configured by value or secretKeyRef. + connectionString: + value: "" + secretKeyRef: + name: "" + key: "" # -- Extra flags for the valkey deployment. Must include `--maxmemory-policy noeviction`. extraFlags: - "--maxmemory-policy noeviction" @@ -529,12 +582,24 @@ s3: # -- When set to 's3', uses S3-compatible interface (default behavior) storageProvider: "s3" - # -- S3 bucket to use for all uploads. Can be overridden per upload type. - bucket: "" - # -- S3 region to use for all uploads. Can be overridden per upload type. - region: "auto" - # -- S3 endpoint to use for all uploads. Can be overridden per upload type. - endpoint: "" + # -- S3 bucket to use for all uploads. Can be overridden per upload type. Can be configured by value or existing secret reference. + bucket: + value: "" + secretKeyRef: + name: "" + key: "" + # -- S3 region to use for all uploads. Can be overridden per upload type. Can be configured by value or existing secret reference. + region: + value: "auto" + secretKeyRef: + name: "" + key: "" + # -- S3 endpoint to use for all uploads. Can be overridden per upload type. Can be configured by value or existing secret reference. + endpoint: + value: "" + secretKeyRef: + name: "" + key: "" # -- Whether to force path style on requests. Required for MinIO. Can be overridden per upload type. forcePathStyle: true # -- S3 accessKeyId to use for all uploads. Can be overridden per upload type. @@ -572,13 +637,25 @@ s3: # Event Upload Configuration eventUpload: # -- S3 bucket to use for event uploads. - bucket: "" + bucket: + value: "" + secretKeyRef: + name: "" + key: "" # -- Prefix to use for event uploads within the bucket. prefix: "" - # -- S3 region to use for event uploads. - region: "" - # -- S3 endpoint to use for event uploads. - endpoint: "" + # -- S3 region to use for event uploads. Can be configured by value or existing secret reference. + region: + value: "" + secretKeyRef: + name: "" + key: "" + # -- S3 endpoint to use for event uploads. Can be configured by value or existing secret reference. + endpoint: + value: "" + secretKeyRef: + name: "" + key: "" # -- Whether to force path style on requests. Required for MinIO. forcePathStyle: Null # -- S3 accessKeyId to use for event uploads. @@ -599,13 +676,25 @@ s3: # -- Enable batch export. enabled: true # -- S3 bucket to use for batch exports. - bucket: "" + bucket: + value: "" + secretKeyRef: + name: "" + key: "" # -- Prefix to use for batch exports within the bucket. prefix: "" - # -- S3 region to use for batch exports. - region: "" - # -- S3 endpoint to use for batch exports. - endpoint: "" + # -- S3 region to use for batch exports. Can be configured by value or existing secret reference. + region: + value: "" + secretKeyRef: + name: "" + key: "" + # -- S3 endpoint to use for batch exports. Can be configured by value or existing secret reference. + endpoint: + value: "" + secretKeyRef: + name: "" + key: "" # -- Whether to force path style on requests. Required for MinIO. forcePathStyle: Null # -- S3 accessKeyId to use for batch exports. @@ -626,13 +715,25 @@ s3: # -- Enable media uploads. enabled: true # -- S3 bucket to use for media uploads. - bucket: "" + bucket: + value: "" + secretKeyRef: + name: "" + key: "" # -- Prefix to use for media uploads within the bucket. prefix: "" - # -- S3 region to use for media uploads. - region: "" - # -- S3 endpoint to use for media uploads. - endpoint: "" + # -- S3 region to use for media uploads. Can be configured by value or existing secret reference. + region: + value: "" + secretKeyRef: + name: "" + key: "" + # -- S3 endpoint to use for media uploads. Can be configured by value or existing secret reference. + endpoint: + value: "" + secretKeyRef: + name: "" + key: "" # -- Whether to force path style on requests. Required for MinIO. forcePathStyle: Null # -- S3 accessKeyId to use for media uploads. diff --git a/examples/secret-refs-example.yaml b/examples/secret-refs-example.yaml new file mode 100644 index 00000000..d95d3e65 --- /dev/null +++ b/examples/secret-refs-example.yaml @@ -0,0 +1,93 @@ +# Example: Using secretKeyRef for sensitive values in Langfuse Helm Chart +# This file demonstrates how to use the new `secretKeyRef` feature to source +# connection details from Kubernetes secrets for PostgreSQL and Redis. + +apiVersion: v1 +kind: Secret +metadata: + name: langfuse-db-secrets + namespace: default +type: Opaque +data: + # Base64 encoded values for PostgreSQL + POSTGRES_HOST: "cG9zdGdyZXMtaG9zdC5leGFtcGxlLmNvbQ==" # postgres-host.example.com + POSTGRES_PORT: "NTQzMg==" # 5432 + POSTGRES_USER: "bGFuZ2Z1c2VfdXNlcg==" # langfuse_user + POSTGRES_DB: "bGFuZ2Z1c2VfZGI=" # langfuse_db + +--- +apiVersion: v1 +kind: Secret +metadata: + name: langfuse-redis-secrets + namespace: default +type: Opaque +data: + # Base64 encoded values for Redis + REDIS_HOST: "cmVkaXMtaG9zdC5leGFtcGxlLmNvbQ==" # redis-host.example.com + REDIS_PORT: "NjM3OQ==" # 6379 + REDIS_USER: "ZGVmYXVsdA==" # default + +--- +# Helm values demonstrating the use of `secretKeyRef`. +# Save this as values.yaml and use with: +# helm install langfuse ./charts/langfuse -f values.yaml + +postgresql: + # Set `deploy` to false as we are using an external PostgreSQL instance + deploy: false + + # Use the new `secretKeyRef` to point to the Kubernetes secret + host: + secretKeyRef: + name: langfuse-db-secrets + key: POSTGRES_HOST + port: + secretKeyRef: + name: langfuse-db-secrets + key: POSTGRES_PORT + + # The existing password management is unchanged and can be used alongside + auth: + existingSecret: "my-postgres-password-secret" + secretKeys: + userPasswordKey: "password" + username: + secretKeyRef: + name: langfuse-db-secrets + key: POSTGRES_USER + database: + secretKeyRef: + name: langfuse-db-secrets + key: POSTGRES_DB + +redis: + # Set `deploy` to false to use an external Redis + deploy: false + + host: + secretKeyRef: + name: langfuse-redis-secrets + key: REDIS_HOST + port: + secretKeyRef: + name: langfuse-redis-secrets + key: REDIS_PORT + + auth: + existingSecret: "my-redis-password-secret" + existingSecretPasswordKey: "password" + username: + secretKeyRef: + name: langfuse-redis-secrets + key: REDIS_USER + +# Other configurations remain as needed... +langfuse: + nextauth: + url: "https://langfuse.example.com" + secret: + # The standard secretKeyRef for other values remains unchanged + secretKeyRef: + name: "my-langfuse-app-secrets" + key: "nextauth-secret"