<@ULVA73B9P> how can I configure my prefect server...
# ask-marvin
s
@Marvin how can I configure my prefect server to use TLS with my postgresql database? I am self-hosting a prefect server and have an RDS instance for the prefect database. I think I need to set SQLAlchemyTLSSettings in my helm chart (I am deploying with EKS)
m
thought for 387.2 seconds
You’re on the right track — in Prefect 3.x you enable DB TLS via the SQLAlchemy TLS settings. In Kubernetes/Helm that means: - mounting a CA bundle into the server pods, and - setting the
PREFECT_SERVER_DATABASE_SQLALCHEMY_CONNECT_ARGS_TLS_*
env vars for every Prefect Server pod that talks to Postgres (API and background services) Key docs: - Settings reference: Prefect 3 Settings reference - Helm charts: Prefect Helm repoprefect-server chart - RDS certs: AWS RDS SSL docs • global bundle: RDS global-bundle.pem What to set - Use the async driver: your connection URL should be
postgresql+asyncpg://...
- Enable TLS: -
PREFECT_SERVER_DATABASE_SQLALCHEMY_CONNECT_ARGS_TLS_ENABLED=true
- Optionally point to a CA file: -
PREFECT_SERVER_DATABASE_SQLALCHEMY_CONNECT_ARGS_TLS_CA_FILE=/path/to/rds-ca.pem
- Keep hostname verification on unless you know you need to relax it: -
PREFECT_SERVER_DATABASE_SQLALCHEMY_CONNECT_ARGS_TLS_CHECK_HOSTNAME=true
Example: mount the RDS CA and set env vars Below is a concrete pattern you can adapt to your chart. The exact values keys differ slightly by chart version, so if you share
helm show values prefecthq/prefect-server --version 2025.6.4170433
, I can tailor this to your chart verbatim. Many users place these under
server.extraEnv
,
server.extraVolumes
, and
server.extraVolumeMounts
(and the same for any separate “services” deployment). 1) Create a ConfigMap (or Secret) with the RDS CA bundle:
Copy code
apiVersion: v1
kind: ConfigMap
metadata:
  name: rds-ca-bundle
data:
  global-bundle.pem: |
    -----BEGIN CERTIFICATE-----
    ...paste contents of global-bundle.pem...
    -----END CERTIFICATE-----
2) Reference it from the Prefect Server pods and set the TLS env vars. The pattern looks like this:
Copy code
server:
  # If your chart splits API and services, repeat these for both.
  extraEnv:
    # Prefer a single connection URL with the asyncpg driver
    - name: PREFECT_SERVER_DATABASE_CONNECTION_URL
      valueFrom:
        secretKeyRef:
          name: prefect-db-credentials
          key: url
    - name: PREFECT_SERVER_DATABASE_SQLALCHEMY_CONNECT_ARGS_TLS_ENABLED
      value: "true"
    - name: PREFECT_SERVER_DATABASE_SQLALCHEMY_CONNECT_ARGS_TLS_CA_FILE
      value: /etc/ssl/rds/global-bundle.pem
    # Optional: keep hostname checks on unless you have a good reason
    - name: PREFECT_SERVER_DATABASE_SQLALCHEMY_CONNECT_ARGS_TLS_CHECK_HOSTNAME
      value: "true"

  extraVolumeMounts:
    - name: rds-ca
      mountPath: /etc/ssl/rds
      readOnly: true

  extraVolumes:
    - name: rds-ca
      configMap:
        name: rds-ca-bundle
        items:
          - key: global-bundle.pem
            path: global-bundle.pem
If you don’t want to embed the CA in a ConfigMap, you can also mount it via the External Secrets Operator as a Secret; the
extraVolumes
section would then reference
secret:
instead of
configMap:
. Environment variable names (for completeness) -
PREFECT_SERVER_DATABASE_CONNECTION_URL
(e.g., `postgresql+asyncpg://USER:PASSWORD@HOST:5432/DBNAME`) -
PREFECT_SERVER_DATABASE_SQLALCHEMY_CONNECT_ARGS_TLS_ENABLED
-
PREFECT_SERVER_DATABASE_SQLALCHEMY_CONNECT_ARGS_TLS_CA_FILE
-
PREFECT_SERVER_DATABASE_SQLALCHEMY_CONNECT_ARGS_TLS_CERT_FILE
(client cert; rarely used with RDS) -
PREFECT_SERVER_DATABASE_SQLALCHEMY_CONNECT_ARGS_TLS_KEY_FILE
(client key; rarely used with RDS) -
PREFECT_SERVER_DATABASE_SQLALCHEMY_CONNECT_ARGS_TLS_CHECK_HOSTNAME
Verifying it works - After deploy, connect to your DB and run:
Copy code
SELECT ssl, version FROM pg_stat_ssl WHERE pid = pg_backend_pid();
You should see
ssl = t
and a TLS version for Prefect connections. About password rotation with External Secrets - Prefect reads DB credentials from env at process start. When the Secret changes, Kubernetes updates the Secret object, but running Pods do not automatically refresh env vars; you’ll need a rollout to pick up the new password. - Options: - Use a controller to trigger restarts on Secret changes (e.g., Stakater Reloader). - If your chart supports it, include a checksum annotation derived from the Secret so a Helm upgrade triggers a rollout when the Secret changes. - With ESO, continue to source
PREFECT_SERVER_DATABASE_CONNECTION_URL
(or password) from the synced Secret via
valueFrom.secretKeyRef
so rotations only require a restart, not a chart change. Would you like me to produce an exact
values.yaml
for your chart version (2025.6.4170433)? If you can paste the output of:
Copy code
helm show values prefecthq/prefect-server --version 2025.6.4170433
I’ll map these snippets to the precise keys your chart exposes.