improve helm chart templating to dynamically create connection url for postgresql and redis from credential secrets
Description ๐ฃ
#3408 This change addresses new improvements with the PostgreSQL and Redis connection configuration in the Infisical Helm chart:
- Added support for building PostgreSQL & Redis connection URI string from secrets
- Added SSL connection support with configurable SSL mode and root certificate path for Postgres
- Added documentation to the helm-chart which identifies the new configureable parameters
Type โจ
- [ ] Bug fix
- [ ] New feature
- [x] Improvement
- [ ] Breaking change
- [x] Documentation
Tests ๐ ๏ธ
First test is to do a dry-run with the new values.yaml and inspect the deployment and the job variables to see if the postgres and redis URIs have been populated correctly
values.yaml
infisical:
enabled: true # -- Enable Infisical chart deployment
name: infisical # -- Sets the name of the deployment within this chart
# -- Number of pod replicas for high availability
replicaCount: 3
image:
repository: infisical/infisical
# -- Specific version tag of the Infisical image. View the latest version here https://hub.docker.com/r/infisical/infisical
tag: "v0.122.0-postgres"
kubeSecretRef: "infisical-secrets"
resources:
limits:
memory: 600Mi
requests:
cpu: 350m
extraVolumes:
- name: postgres-ca-cert
secret:
secretName: self-signed-ca-key-pair
items:
- key: ca.crt
path: postgres-ca.crt
extraVolumeMounts:
- name: postgres-ca-cert
mountPath: /etc/custom-certs
readOnly: true
ingress:
enabled: false
nginx:
enabled: false
postgresql:
# -- Enables an in-cluster PostgreSQL deployment. To achieve HA for Postgres, we recommend deploying https://github.com/zalando/postgres-operator instead.
enabled: false
customURIParameters:
enabled: true
host: "pg-infisical-rw.infisical.svc.cluster.local"
port: "5432"
database: "pg-infisical"
username:"pg-infisical-admin"
passwordSecret:
name: "infisical-pg-admin-credentials-secret"
key: "password"
ssl:
enabled: true
mode: "verify-ca"
rootCertPath: "/etc/custom-certs/postgres-ca.crt"
redis:
enabled: false
# -- Build a custom Redis connection string from parameters
customURIParameters:
# -- Set to true if using custom URI parameters for Redis connection
enabled: true
# -- Redis host
host: "redis-infisical-master.infisical.svc.cluster.local"
# -- Port for Redis connection. Default is 6379
port: 6379
# -- Secret containing Redis password
passwordSecret:
# -- Kubernetes secret name containing the Redis password
name: "infisical-redis-admin-credentials-secret"
# -- Key name in the Kubernetes secret that holds the Redis password
key: "redis-password"
Then run:
helm install infisical-test ./infisical-standalone --dry-run --debug -f values.yaml > rendered.yaml
Then inspect:
rendered.yaml - Deployment
# Source: infisical-standalone/templates/infisical.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: infisical-test-infisical-standalone-infisical
...
labels:
component: "infisical"
app: infisical-standalone
release: infisical-test
chart: infisical-standalone-1.5.0
heritage: Helm
spec:
replicas: 3
...
template:
...
spec:
serviceAccountName: infisical-test-infisical
initContainers:
- name: "migration-init"
image: "ghcr.io/groundnuty/k8s-wait-for:no-root-v2.0"
imagePullPolicy: IfNotPresent
args:
- "job"
- "infisical-test-schema-migration-1"
volumeMounts:
- mountPath: /etc/custom-certs
name: postgres-ca-cert
readOnly: true
containers:
- name: infisical-standalone-infisical
image: "infisical/infisical:v0.122.0-postgres"
...
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: infisical-pg-admin-credentials-secret
key: password
- name: DB_CONNECTION_URI
value: "postgresql://pg-infisical-admin:$(DB_PASSWORD)@pg-infisical-rw.infisical.svc.cluster.local:5432/pg-infisical?sslmode=verify-ca&sslrootcert=/etc/custom-certs/postgres-ca.crt"
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: infisical-redis-admin-credentials-secret
key: redis-password
- name: REDIS_URL
value: "redis://default:$(REDIS_PASSWORD)@redis-infisical-master.infisical.svc.cluster.local:6379"
envFrom:
- secretRef:
name: infisical-secrets
...
volumeMounts:
- mountPath: /etc/custom-certs
name: postgres-ca-cert
readOnly: true
volumes:
- name: postgres-ca-cert
secret:
items:
- key: ca.crt
path: postgres-ca.crt
secretName: self-signed-ca-key-pair
rendered.yaml - Job
# Source: infisical-standalone/templates/schema-migration-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: "infisical-test-schema-migration-1"
labels:
helm.sh/chart: "infisical-standalone-1.5.0"
spec:
...
template:
metadata:
name: "infisical-test-create-tables"
...
spec:
serviceAccountName: infisical-test-infisical
restartPolicy: OnFailure
volumes:
- name: postgres-ca-cert
secret:
items:
- key: ca.crt
path: postgres-ca.crt
secretName: self-signed-ca-key-pair
containers:
- name: infisical-schema-migration
image: "infisical/infisical:v0.122.0-postgres"
command: ["npm", "run", "migration:latest"]
volumeMounts:
- mountPath: /etc/custom-certs
name: postgres-ca-cert
readOnly: true
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: infisical-pg-admin-credentials-secret
key: password
- name: DB_CONNECTION_URI
value: "postgresql://pg-infisical-admin:$(DB_PASSWORD)@pg-infisical-rw.infisical.svc.cluster.local:5432/pg-infisical?sslmode=verify-ca&sslrootcert=/etc/custom-certs/postgres-ca.crt"
envFrom:
- secretRef:
name: infisical-secrets
Additional Tests
Follow my documentation on how to get Infisical up and running with cloudnative-pg with TLS support and proper secret management with the helm chart from this PR.
Following these steps yields me to be able to open Infisical in my browser:
After creating an account:
- [x] I have read the contributing guide, agreed and acknowledged the code of conduct. ๐
Summary by CodeRabbit
Summary by CodeRabbit
-
New Features
- Added customizable connection settings for PostgreSQL and Redis, including credential management, host/port, and SSL/TLS options.
- Enabled mounting of additional volumes for enhanced security, such as custom CA certificates.
- Enhanced environment variable configuration for deployment and migration jobs to support flexible connection strings.
-
Documentation
- Updated Helm chart README with detailed instructions and examples for new database and cache configuration parameters.
Walkthrough
This pull request updates the Infisical Helm chart by introducing new customURIParameters configuration options for PostgreSQL and Redis. These options allow users to specify custom connection parameters such as username, password (via Kubernetes secrets), host, port, and database name. For PostgreSQL, SSL settings including enablement, SSL mode, and root certificate path are also configurable. The Helm chart templates are modified to conditionally set environment variables for database and Redis connection strings and passwords based on these custom parameters when enabled. Additionally, the schema migration job is enhanced with support for extra Kubernetes volumes and volume mounts to facilitate mounting custom CA certificates for PostgreSQL TLS verification. Two new Helm template helpers are added to generate connection strings from the custom URI parameters for PostgreSQL and Redis. New configuration options extraVolumes and extraVolumeMounts are introduced to allow mounting additional volumes into the Infisical pod.
[!TIP]
โก๐ฌ Agentic Chat (Pro Plan, General Availability)
- We're introducing multi-step agentic chat in review comments and issue comments, within and outside of PR's. This feature enhances review and issue discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments and add commits to existing pull requests.
๐ Recent review details
Configuration used: CodeRabbit UI Review profile: CHILL Plan: Pro
๐ฅ Commits
Reviewing files that changed from the base of the PR and between 04d434c354461d22f21fe4b9436040d7ce31236f and 11cecfc7adfd8757e7bbd76af29c75eff812074e.
๐ Files selected for processing (1)
-
helm-charts/infisical-standalone-postgres/README.md(2 hunks)
๐ง Files skipped from review as they are similar to previous changes (1)
- helm-charts/infisical-standalone-postgres/README.md
๐ชง Tips
Chat
There are 3 ways to chat with CodeRabbit:
- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
-
I pushed a fix in commit <commit_id>, please review it. -
Generate unit testing code for this file. -
Open a follow-up GitHub issue for this discussion.
-
- Files and specific lines of code (under the "Files changed" tab): Tag
@coderabbitaiin a new review comment at the desired location with your query. Examples:-
@coderabbitai generate unit testing code for this file. -
@coderabbitai modularize this function.
-
- PR comments: Tag
@coderabbitaiin a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:-
@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase. -
@coderabbitai read src/utils.ts and generate unit testing code. -
@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format. -
@coderabbitai help me debug CodeRabbit configuration file.
-
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.
CodeRabbit Commands (Invoked using PR comments)
-
@coderabbitai pauseto pause the reviews on a PR. -
@coderabbitai resumeto resume the paused reviews. -
@coderabbitai reviewto trigger an incremental review. This is useful when automatic reviews are disabled for the repository. -
@coderabbitai full reviewto do a full review from scratch and review all the files again. -
@coderabbitai summaryto regenerate the summary of the PR. -
@coderabbitai generate docstringsto generate docstrings for this PR. -
@coderabbitai resolveresolve all the CodeRabbit review comments. -
@coderabbitai configurationto show the current CodeRabbit configuration for the repository. -
@coderabbitai helpto get help.
Other keywords and placeholders
- Add
@coderabbitai ignoreanywhere in the PR description to prevent this PR from being reviewed. - Add
@coderabbitai summaryto generate the high-level summary at a specific location in the PR description. - Add
@coderabbitaianywhere in the PR title to generate the title automatically.
CodeRabbit Configuration File (.coderabbit.yaml)
- You can programmatically configure CodeRabbit by adding a
.coderabbit.yamlfile to the root of your repository. - Please see the configuration documentation for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation:
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
Documentation and Community
- Visit our Documentation for detailed information on how to use CodeRabbit.
- Join our Discord Community to get help, request features, and share feedback.
- Follow us on X/Twitter for updates and announcements.
I want to be able to use the PostgreSQL sub-chart with an existing secret. Currently, when .Values.postgresql.enabled: true the helper method will be used to fill the environment variable. That one uses the .Values.portgresql.auth.password which is really confusing when using .Values.portgresql.auth.existingSecret instead, because it will still use "root" as password in the deployment and migrator.
I want to be able to use the PostgreSQL sub-chart with an existing secret. Currently, when
.Values.postgresql.enabled: truethe helper method will be used to fill the environment variable. That one uses the.Values.portgresql.auth.passwordwhich is really confusing when using.Values.portgresql.auth.existingSecretinstead, because it will still use "root" as password in the deployment and migrator.
I understand what you are saying, however there are limitation to this part. The Bitnami PostgreSQL chart expects configuration values under specific paths, .Values.postgresql.auth.username, .Values.postgresql.auth.password, and .Values.postgresql.auth.database are passed directly to create and configure the PostgreSQL instance. The sub-chart I believe should be used more for development purposes, so we can easily bootstrap a password to test.
For production, this is not the best practice, hence you should have an external postgres cluster, which is where I am trying to make improvements with this PR, so you can create a more secure connection with secrets, and be able to rotate those secrets in the future without having to deal with updating the DB URI.
Actionable comments posted: 1
๐งน Nitpick comments (1)
helm-charts/infisical-standalone-postgres/templates/_helpers.tpl (1)>
93-107: Well-structured PostgreSQL connection string helper with secure password handling.The new helper effectively builds PostgreSQL connection strings from custom parameters with SSL support. Using the
${DB_PASSWORD}placeholder enables secure injection of credentials at runtime. Consider adding parameter validation to ensure all required fields are present before constructing the connection string. This would prevent potentially malformed connection strings if a user misconfigures values.{{- define "infisical.customPostgresDBConnectionString" -}} {{- if .Values.postgresql.customURIParameters.enabled -}} {{- $pgParams := .Values.postgresql.customURIParameters -}} +{{- if and $pgParams.username $pgParams.host $pgParams.port $pgParams.database -}} {{- $sslParams := "" -}} {{- if $pgParams.ssl.enabled -}} +{{- if and $pgParams.ssl.mode $pgParams.ssl.rootCertPath -}} {{- $sslParams = printf "?sslmode=%s&sslrootcert=%s" $pgParams.ssl.mode $pgParams.ssl.rootCertPath -}} +{{- else -}} +{{- $sslParams = printf "?sslmode=disable" -}} +{{- end -}} {{- end -}} {{- printf "postgresql://%s:${DB_PASSWORD}@%s:%s/%s%s" $pgParams.username $pgParams.host $pgParams.port $pgParams.database $sslParams -}} +{{- else -}} +{{- fail "PostgreSQL custom URI parameters missing required fields (username, host, port, database)" -}} +{{- end -}} {{- else -}} {{- print "" -}} {{- end -}} {{- end -}}๐ Review details
The logic to set the ssl disable was a really good catch, after testing this is the value when postgres.customURIParameters.ssl.enable is set to false.
- name: DB_CONNECTION_URI
value: postgresql://pg-infisical-admin:${DB_PASSWORD}@pg-infisical-rw.infisical.svc.cluster.local:5432/pg-infisical?sslmode=disable
the {ENV_VAR} syntax is wrong, and is throwing errors when running the second test, actually deploying Infisical to a Kubernetes cluster. I will continue testing and fix any remaining bugs and make sure I am able to deploy using the new settings and original settings
After reviewing the bugs, and running both tests (Dry Run & Full Deployment), I have been able to successfully deploy Infisical in a Kubernetes Cluster with Custom URI Parameters. With the new updates I've moved the functionality of dynamically creating the URI to _helpers.tpl and kept the templates cleaner.
Along with the testing, I've Identified the following case where the redis username must be set to default, or else we get the following error thrown:
[ioredis] Unhandled error event: ReplyError: WRONGPASS invalid username-password pair or user is disabled.
at parseError (/backend/node_modules/redis-parser/lib/parser.js:179:12)
at parseType (/backend/node_modules/redis-parser/lib/parser.js:302:14)
[ioredis] Unhandled error event: ReplyError: WRONGPASS invalid username-password pair or user is disabled.
at parseError (/backend/node_modules/redis-parser/lib/parser.js:179:12)
at parseType (/backend/node_modules/redis-parser/lib/parser.js:302:14)
ReplyError: WRONGPASS invalid username-password pair or user is disabled.
at parseError (/backend/node_modules/redis-parser/lib/parser.js:179:12)
at parseType (/backend/node_modules/redis-parser/lib/parser.js:302:14) {
command: { name: 'auth', args: [ 'joe', 'infisical-pg-admin' ] }
}
This is related to the following issue with bitnami/redis: https://github.com/bitnami/charts/issues/7709 - the bitnami/redis chart does not support any username, and default is the default username for redis instances. Unless someone has a use-case for custom redis username, I don't see the need to implement something we can't really test.
Below you will find screenshots from my deployment and screenshots of being able to access the infisical deployment in the browser to a domain name and create our superuser.
Lens:
Super User Sign Up:
Logged in:
Let me know if there is anything else I can do to improve this PR!