diff --git a/charts/plane-enterprise/Chart.yaml b/charts/plane-enterprise/Chart.yaml index 6a85f88d..15374ca9 100644 --- a/charts/plane-enterprise/Chart.yaml +++ b/charts/plane-enterprise/Chart.yaml @@ -5,7 +5,7 @@ description: Meet Plane. An Enterprise software development tool to manage issue type: application -version: 3.3.0 +version: 3.4.0 appVersion: "3.1.1" home: https://plane.so/ diff --git a/charts/plane-enterprise/README.md b/charts/plane-enterprise/README.md index 39bc2d2d..8b850d49 100644 --- a/charts/plane-enterprise/README.md +++ b/charts/plane-enterprise/README.md @@ -89,8 +89,186 @@ The default value is `"traefik"`. If you are switching to a standard ingress con | `ingress.enabled` | `true` | Master switch — set to `false` to render neither template. | | `ingress.ingressClass` | `traefik` | Selects which template is active (see table above). | | `ingress.traefik.maxRequestBodyBytes` | `20971520` | Max request body size for Traefik's buffering middleware. Ignored when not using Traefik. | +| `ingress.traefik.entryPoints` | `[]` | Traefik entrypoints for the `IngressRoute`. Empty means derive from your SSL settings — see below. Ignored when not using Traefik. | | `ingress.ingress_annotations` | `{}` | Standard `Ingress` annotations. Ignored when `ingressClass` starts with `traefik`. | +### TLS options: choosing how HTTPS is handled + +TLS is **optional**. Your `ssl.*` settings drive two *separate* derivations — +separate because "users are on HTTPS" and "this chart holds the certificate" are +different facts: + +1. whether a `tls:` block is emitted, and which Traefik entrypoint the + `IngressRoute` binds to — both from whether **this chart** terminates TLS; +2. the scheme of every URL Plane is told about itself — `WEB_URL`, + `APP_BASE_URL`, `PI_BASE_URL`, `PLANE_FRONTEND_URL`, `PLANE_API_HOST`, + `PLANE_OAUTH_REDIRECT_URI`, `SILO_API_BASE_URL`, `EXPORT_DOWNLOAD_BASE_URL`. + (`CORS_ALLOWED_ORIGINS` always lists both schemes and is unaffected.) + +Find the row that matches your environment: + +| Your setup | Set | Entrypoint | `tls:` block | App URLs | +| --- | --- | :---: | :---: | :---: | +| No certificate yet — trial, internal network | *nothing* (default) | `web` | — | `http://` | +| You already hold a TLS Secret | `ssl.tls_secret_name` | `websecure` | your Secret | `https://` | +| Let cert-manager issue one | `ssl.createIssuer` + `ssl.generateCerts` | `websecure` | `-ssl-cert` | `https://` | +| TLS terminated upstream (ALB, NLB TLS listener, Cloudflare) | `ssl.externalTermination: true` | `web` | — | `https://` | +| TLS terminated by Traefik's own entrypoint | `ssl.externalTermination: true` + `ingress.traefik.entryPoints: ['websecure']` | `websecure` | — | `https://` | + +Only the `tls:` block requires a Secret this chart can actually see, which is why +the last two rows emit none — the chart never names a Secret it does not create. + +Note the last two rows share a scheme but need **opposite entrypoints**: an +upstream terminator forwards cleartext, which arrives on `web`, whereas a Traefik +entrypoint carrying its own certificate serves TLS on `websecure`. That is why +`ssl.externalTermination` sets the URL scheme only and never moves the +entrypoint. + +#### Option 1 — No TLS, plain HTTP + +The default. Nothing to set; leave the `ssl` block alone and Plane is reachable at +`http://`: + +```yaml +license: + licenseDomain: plane.example.com +ingress: + ingressClass: traefik +``` + +Good for a quick trial, an air-gapped or internal network, or while you are still +sorting out DNS and certificates. **Read the entrypoint caveat below before +relying on it** — and terminate TLS somewhere before exposing Plane on the public +internet. + +#### Option 2 — Bring your own certificate + +Create a `kubernetes.io/tls` Secret in the release namespace and name it: + +```bash +kubectl create secret tls my-tls-secret \ + --cert=fullchain.pem --key=privkey.pem -n plane-ns +``` + +```yaml +ssl: + tls_secret_name: my-tls-secret +``` + +#### Option 3 — Let cert-manager issue the certificate + +Requires cert-manager in the cluster. **Both** flags are needed — `createIssuer` +alone creates an Issuer but no Certificate, and the chart then treats the install +as having no certificate at all: + +```yaml +ssl: + createIssuer: true + generateCerts: true + issuer: http # or cloudflare / digitalocean + email: you@example.com + # token: # required for cloudflare / digitalocean +``` + +The Certificate is written to `-ssl-cert` and the `IngressRoute` +references it. + +#### Option 4 — TLS terminated in front of Plane + +Use this when something ahead of Plane already terminates TLS and this chart +manages no certificate. `ssl.externalTermination` renders every app URL +`https://` and emits no `tls:` block. It does **not** move the entrypoint, so +pick the sub-case that matches where TLS actually ends. + +**4a — an upstream terminator forwards cleartext** (ALB with an ACM cert, NLB +with a TLS listener, Cloudflare, most service meshes). Traffic reaches Traefik as +plain HTTP, so the route stays on `web` — the default: + +```yaml +ssl: + externalTermination: true +``` + +**4b — Traefik's own entrypoint terminates TLS** (`websecure.http.tls=true`, an +ACME `certResolver`, or a default `TLSStore`). Traffic reaches Traefik as TLS, so +the route must bind `websecure` as well: + +```yaml +ssl: + externalTermination: true +ingress: + traefik: + entryPoints: ['websecure'] +``` + +Getting the sub-case wrong is a routing failure, not a certificate failure: a +route bound only to `websecure` never matches cleartext arriving on `web`, so +requests 404 instead of reaching Plane. + +Leave `externalTermination` `false` if you set `ssl.tls_secret_name` or +`ssl.generateCerts`; those already imply HTTPS. Use it *only* for TLS this chart +cannot see. Without it, such an install would advertise `http://` URLs to itself +while being served over HTTPS, breaking OAuth callbacks and export download +links. + +#### Overriding the entrypoint names + +Only needed if your Traefik installation renamed the default `web` / `websecure` +entrypoints, or you want to serve both schemes at once: + +```yaml +ingress: + traefik: + entryPoints: ['websecure', 'web'] # a bare string also works +``` + +Leave it empty (the default) to derive the entrypoint from the table above. This +setting controls the entrypoint *only* — whether a `tls:` block is emitted still +follows your `ssl.*` configuration. It is also how you select `websecure` for +option 4b, where TLS ends at Traefik itself. + +#### Caveat: check your Traefik entrypoints before relying on plain HTTP + +Many Traefik installations redirect `web` to HTTPS in Traefik's own static +configuration: + +```text +--entryPoints.web.http.redirections.entryPoint.to=:443 +--entryPoints.web.http.redirections.entryPoint.scheme=https +--entryPoints.websecure.http.tls=true +``` + +Check yours with: + +```bash +kubectl get deploy -n traefik \ + -o jsonpath='{.spec.template.spec.containers[0].args}' | tr ',' '\n' | grep -i redirect +``` + +If the redirection is present, every plain-HTTP request is answered with a +permanent redirect *before* it reaches a route, so Option 1 cannot serve Plane on +that cluster. Either drop the redirection, or use Option 2/3/4. + +#### Upgrading from 3.3.0 or earlier + +If you configure TLS through `ssl.tls_secret_name` or `ssl.generateCerts` + +`ssl.createIssuer`, the rendered ingress is unchanged and no action is needed. + +One case needs a value added. Earlier releases always bound the Traefik +`IngressRoute` to `websecure` and always emitted a `tls:` block, even when no +certificate was configured — pointing at a `-ssl-cert` Secret that was +never created, so Traefik fell back to its built-in self-signed certificate. If +you relied on that, or on TLS terminated at Traefik itself, adopt Option 4b — +both settings, since `externalTermination` alone leaves the route on `web`: + +```yaml +ssl: + externalTermination: true +ingress: + traefik: + entryPoints: ['websecure'] +``` + ## Installing Plane 1. Open Terminal or any other command-line app that has access to Kubernetes tools on your local system. @@ -870,6 +1048,8 @@ Note: When the email service is enabled, the cert-issuer will be automatically c | ingress.rabbitmqHost | | | Based on above configuration, if you want to expose the `rabbitmq` web console to set of users, use this key to set the `host` mapping or leave it as `EMPTY` to not expose interface. | | ingress.ingressClass | nginx | Yes | Kubernetes cluster setup comes with various options of `ingressClass`. Based on your setup, set this value to the right one (eg. nginx, traefik, etc). Leave it to default in case you are using external ingress provider. | | ingress.ingress_annotations | `{ "nginx.ingress.kubernetes.io/proxy-body-size": "5m" }` | | Ingress controllers comes with various configuration options which can be passed as annotations. Setting this value lets you change the default value to user required. | +| ingress.traefik.entryPoints | `[]` | | Traefik entrypoints the `IngressRoute` binds to. Leave empty to derive them from your `ssl.*` settings (`websecure` when TLS is configured, otherwise `web`). Set explicitly only if your Traefik renamed the default entrypoints, e.g. `['websecure','web']`. Ignored unless `ingressClass` starts with `traefik` | +| ingress.traefik.maxRequestBodyBytes | 20971520 | | Max request body size in bytes for Traefik's buffering middleware (upload size limit). Ignored unless `ingressClass` starts with `traefik` | | ssl.createIssuer | false | | Kubernets cluster setup supports creating `issuer` type resource. After deployment, this is step towards creating secure access to the ingress url. Issuer is required for you generate SSL certifiate. Kubernetes can be configured to use any of the certificate authority to generate SSL (depending on CertManager configuration). Set it to `true` to create the issuer. Applicable only when `ingress.enabled=true` | | ssl.issuer | http | | CertManager configuration allows user to create issuers using `http` or any of the other DNS Providers like `cloudflare`, `digitalocean`, etc. As of now Plane supports `http`, `cloudflare`, `digitalocean` | | ssl.token | | | To create issuers using DNS challenge, set the issuer api token of dns provider like cloudflare`or`digitalocean`(not required for http) | @@ -877,6 +1057,7 @@ Note: When the email service is enabled, the cert-issuer will be automatically c | ssl.email | | | Certificate generation authority needs a valid email id before generating certificate. Required when `ssl.createIssuer=true` | | ssl.generateCerts | false | | After creating the issuers, user can still not create the certificate untill sure of configuration. Setting this to `true` will try to generate SSL certificate and associate with ingress. Applicable only when `ingress.enabled=true` and `ssl.createIssuer=true` | | ssl.tls_secret_name | | | If you have a custom TLS secret name, set this to the name of the secret. Applicable only when `ingress.enabled=true` and `ssl.createIssuer=false` | +| ssl.externalTermination | false | | Set to `true` when TLS is terminated in front of Plane and this chart manages no certificate (cloud load balancer, Cloudflare, service mesh, or a Traefik entrypoint carrying its own cert). All app URLs are rendered `https://`; no `tls:` block is emitted and the Traefik entrypoint is unchanged (stays `web` unless you also set `ingress.traefik.entryPoints: ['websecure']` — see Option 4b). Leave `false` if you set `ssl.tls_secret_name` or `ssl.generateCerts`. See [TLS options](#tls-options-choosing-how-https-is-handled) | ### Common Environment Settings diff --git a/charts/plane-enterprise/questions.yml b/charts/plane-enterprise/questions.yml index 30e436a2..df80c714 100644 --- a/charts/plane-enterprise/questions.yml +++ b/charts/plane-enterprise/questions.yml @@ -1753,6 +1753,22 @@ questions: group: "Ingress" show_if: "ssl.createIssuer=false" +- variable: ssl.externalTermination + label: "TLS Terminated in Front of Plane" + description: "Enable when TLS is terminated before traffic reaches Plane (cloud load balancer, Cloudflare, service mesh, or a Traefik entrypoint carrying its own cert) and this chart manages no certificate. App URLs are rendered https:// but no tls block is emitted. Leave off if you set a TLS secret name or generate certificates. See the chart README's 'TLS options' section." + type: boolean + default: false + group: "Ingress" + show_if: "ingress.enabled=true" + +- variable: ingress.traefik.entryPoints + label: "Traefik Entrypoints Override" + description: "Traefik entrypoints the IngressRoute binds to, e.g. 'websecure'. Leave empty to derive from the SSL settings (websecure when this chart manages a certificate, otherwise web). Required as 'websecure' when TLS is terminated by Traefik's own entrypoint. Ignored unless the ingress class is traefik." + type: string + default: "" + group: "Ingress" + show_if: "ingress.enabled=true" + - variable: external_secrets.rabbitmq_existingSecret label: "RabbitMQ Secrets File Name" type: string diff --git a/charts/plane-enterprise/templates/_helpers.tpl b/charts/plane-enterprise/templates/_helpers.tpl index de139b01..29eca847 100644 --- a/charts/plane-enterprise/templates/_helpers.tpl +++ b/charts/plane-enterprise/templates/_helpers.tpl @@ -292,3 +292,79 @@ reports its own service.name). Call with a dict and nindent, e.g. value: {{ .service | quote }} {{- end -}} {{- end -}} + +{{/* +Returns "true" when THIS CHART has a TLS Secret to point an ingress at: either +the user supplied one via ssl.tls_secret_name, or cert-manager is set up to mint +one (ssl.generateCerts + ssl.createIssuer, which is what gates +templates/certs/certs.yaml). + +Gates the `tls:` blocks. Never widen this to cover externally-terminated TLS -- +referencing a Secret that nothing creates is the bug this helper exists to stop. +*/}} +{{- define "plane.chartManagedCert" -}} + {{- if or .Values.ssl.tls_secret_name (and .Values.ssl.generateCerts .Values.ssl.createIssuer) -}} + true + {{- end -}} +{{- end -}} + +{{/* +Returns "true" when users reach Plane over https://, whoever terminates it. + +That is either a chart-managed certificate, or ssl.externalTermination for TLS +handled in front of Plane -- a cloud load balancer, Cloudflare, a service mesh, +or a Traefik entrypoint with its own certificate (`websecure.http.tls=true`). +The chart owns no Secret in that second case, so this must NOT be used to emit a +`tls:` block; use plane.chartManagedCert for that. + +Drives ONLY the scheme of every self-referential URL handed to the app +(APP_BASE_URL, PLANE_FRONTEND_URL, PLANE_OAUTH_REDIRECT_URI, +EXPORT_DOWNLOAD_BASE_URL, ...). + +Deliberately NOT the Traefik entrypoint. "Users are on https" says nothing about +which entrypoint traffic arrives on: an upstream terminator (ALB, NLB TLS +listener, Cloudflare) forwards cleartext, which lands on `web`, while a Traefik +entrypoint carrying its own certificate lands on `websecure`. Those need +opposite entrypoints from the same value, so the entrypoint derives from +plane.chartManagedCert instead and ingress.traefik.entryPoints overrides it. +*/}} +{{- define "plane.tlsEnabled" -}} + {{- if or (eq (include "plane.chartManagedCert" .) "true") .Values.ssl.externalTermination -}} + true + {{- end -}} +{{- end -}} + +{{/* +Traefik entrypoint names for the IngressRoute. + +Honours an explicit ingress.traefik.entryPoints override (some clusters rename +the defaults, and it is the way to select `websecure` when Traefik's own +entrypoint terminates TLS); otherwise derives them from whether THIS CHART +terminates TLS, so an install with SSL left off is reachable over plain HTTP +instead of serving Traefik's fallback self-signed certificate. + +Keyed on plane.chartManagedCert, NOT plane.tlsEnabled: with TLS terminated +upstream the chart must still bind `web`, because the terminator forwards +cleartext and a route attached only to `websecure` would never match it. + +An empty value is the "derive it" sentinel, never a literal empty list -- the +CRD requires at least one entrypoint. A bare string is accepted and wrapped into +a single-item list, since `--set ingress.traefik.entryPoints=websecure` yields a +scalar and would otherwise render a list-less mapping the CRD rejects. +Caller must nindent to the correct depth. +*/}} +{{- define "plane.traefikEntryPoints" -}} + {{- with .Values.ingress.traefik.entryPoints -}} + {{- if kindIs "string" . -}} + {{- toYaml (list .) -}} + {{- else -}} + {{- toYaml . -}} + {{- end -}} + {{- else -}} + {{- if eq (include "plane.chartManagedCert" $) "true" -}} +- websecure + {{- else -}} +- web + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/charts/plane-enterprise/templates/config-secrets/app-env.yaml b/charts/plane-enterprise/templates/config-secrets/app-env.yaml index 7675020d..970de2bd 100644 --- a/charts/plane-enterprise/templates/config-secrets/app-env.yaml +++ b/charts/plane-enterprise/templates/config-secrets/app-env.yaml @@ -82,7 +82,7 @@ data: CELERY_BROKER_POOL_LIMIT: {{ .Values.env.celery_broker_pool_limit | quote }} {{- if .Values.env.web_url}} WEB_URL: {{ .Values.env.web_url | default "" | quote }} - {{- else if or .Values.ssl.tls_secret_name (and .Values.ssl.createIssuer .Values.ssl.generateCerts) }} + {{- else if eq (include "plane.tlsEnabled" .) "true" }} WEB_URL: "https://{{ .Values.license.licenseDomain }}" {{- else }} WEB_URL: "http://{{ .Values.license.licenseDomain }}" @@ -90,7 +90,7 @@ data: LIVE_BASE_URL: "http://{{ .Release.Name }}-live.{{ .Release.Namespace }}.svc.{{ .Values.env.default_cluster_domain | default "cluster.local" }}:3000/" LIVE_BASE_PATH: "/live" - {{- if or .Values.ssl.tls_secret_name (and .Values.ssl.createIssuer .Values.ssl.generateCerts) }} + {{- if eq (include "plane.tlsEnabled" .) "true" }} PI_BASE_URL: "https://{{ .Values.license.licenseDomain }}" {{- else }} PI_BASE_URL: "http://{{ .Values.license.licenseDomain }}" diff --git a/charts/plane-enterprise/templates/config-secrets/live-env.yaml b/charts/plane-enterprise/templates/config-secrets/live-env.yaml index 5f249ce6..645a5796 100644 --- a/charts/plane-enterprise/templates/config-secrets/live-env.yaml +++ b/charts/plane-enterprise/templates/config-secrets/live-env.yaml @@ -36,7 +36,7 @@ data: LIVE_SENTRY_ENVIRONMENT: {{ .Values.env.live_sentry_environment | default "" | quote }} LIVE_SENTRY_TRACES_SAMPLE_RATE: {{ .Values.env.live_sentry_traces_sample_rate | default "" | quote }} LIVE_BASE_PATH: "/live" - {{- if or .Values.ssl.tls_secret_name (and .Values.ssl.createIssuer .Values.ssl.generateCerts) }} + {{- if eq (include "plane.tlsEnabled" .) "true" }} PI_BASE_URL: "https://{{ .Values.license.licenseDomain }}" {{- else }} PI_BASE_URL: "http://{{ .Values.license.licenseDomain }}" @@ -49,7 +49,7 @@ data: IFRAMELY_URL: http://{{ .Release.Name }}-iframely.{{ .Release.Namespace }}.svc.{{ .Values.env.default_cluster_domain | default "cluster.local" }}:8061/ {{- end }} - {{- if or .Values.ssl.tls_secret_name (and .Values.ssl.createIssuer .Values.ssl.generateCerts) }} + {{- if eq (include "plane.tlsEnabled" .) "true" }} EXPORT_DOWNLOAD_BASE_URL: {{ .Values.env.export_download_base_url | default (printf "https://%s" .Values.license.licenseDomain) | quote }} {{- else }} EXPORT_DOWNLOAD_BASE_URL: {{ .Values.env.export_download_base_url | default (printf "http://%s" .Values.license.licenseDomain) | quote }} diff --git a/charts/plane-enterprise/templates/config-secrets/pi-api-env.yaml b/charts/plane-enterprise/templates/config-secrets/pi-api-env.yaml index 6a9fff9a..66670e98 100644 --- a/charts/plane-enterprise/templates/config-secrets/pi-api-env.yaml +++ b/charts/plane-enterprise/templates/config-secrets/pi-api-env.yaml @@ -93,7 +93,7 @@ data: LIVE_BASE_URL: "http://{{ .Release.Name }}-live.{{ .Release.Namespace }}.svc.{{ .Values.env.default_cluster_domain | default "cluster.local" }}:3000/" LIVE_BASE_PATH: "/live" - {{- if or .Values.ssl.tls_secret_name (and .Values.ssl.createIssuer .Values.ssl.generateCerts) }} + {{- if eq (include "plane.tlsEnabled" .) "true" }} PLANE_FRONTEND_URL: "https://{{ .Values.license.licenseDomain }}" {{- else }} PLANE_FRONTEND_URL: "http://{{ .Values.license.licenseDomain }}" @@ -101,7 +101,7 @@ data: {{- if .Values.env.pi_envs.plane_api_host }} PLANE_API_HOST: {{ .Values.env.pi_envs.plane_api_host | quote }} - {{- else if or .Values.ssl.tls_secret_name (and .Values.ssl.createIssuer .Values.ssl.generateCerts) }} + {{- else if eq (include "plane.tlsEnabled" .) "true" }} PLANE_API_HOST: "https://{{ .Values.license.licenseDomain }}" {{- else }} PLANE_API_HOST: "http://{{ .Values.license.licenseDomain }}" @@ -120,7 +120,7 @@ data: CORS_ALLOWED_ORIGINS: "http://{{ .Values.license.licenseDomain }},https://{{ .Values.license.licenseDomain }}" {{- end }} - {{- if or .Values.ssl.tls_secret_name (and .Values.ssl.createIssuer .Values.ssl.generateCerts) }} + {{- if eq (include "plane.tlsEnabled" .) "true" }} PLANE_OAUTH_REDIRECT_URI: "https://{{ .Values.license.licenseDomain }}/pi/api/v1/oauth/callback/" {{- else }} PLANE_OAUTH_REDIRECT_URI: "http://{{ .Values.license.licenseDomain }}/pi/api/v1/oauth/callback/" diff --git a/charts/plane-enterprise/templates/config-secrets/silo.yaml b/charts/plane-enterprise/templates/config-secrets/silo.yaml index 7fdfc50a..c4fa1b5d 100644 --- a/charts/plane-enterprise/templates/config-secrets/silo.yaml +++ b/charts/plane-enterprise/templates/config-secrets/silo.yaml @@ -95,7 +95,7 @@ data: CORS_ALLOWED_ORIGINS: "http://{{ .Values.license.licenseDomain }},https://{{ .Values.license.licenseDomain }}" {{- end }} - {{- if or .Values.ssl.tls_secret_name (and .Values.ssl.createIssuer .Values.ssl.generateCerts) }} + {{- if eq (include "plane.tlsEnabled" .) "true" }} APP_BASE_URL: "https://{{ .Values.license.licenseDomain }}" {{- else }} APP_BASE_URL: "http://{{ .Values.license.licenseDomain }}" @@ -104,7 +104,7 @@ data: API_BASE_URL: "http://{{ .Release.Name }}-api.{{ .Release.Namespace }}.svc.{{ .Values.env.default_cluster_domain | default "cluster.local" }}:8000/" API_INTERNAL_BASE_URL: "http://{{ .Release.Name }}-api.{{ .Release.Namespace }}.svc.{{ .Values.env.default_cluster_domain | default "cluster.local" }}:8000/" - {{- if or .Values.ssl.tls_secret_name (and .Values.ssl.createIssuer .Values.ssl.generateCerts) }} + {{- if eq (include "plane.tlsEnabled" .) "true" }} SILO_API_BASE_URL: "https://{{ .Values.license.licenseDomain }}" {{- else }} SILO_API_BASE_URL: "http://{{ .Values.license.licenseDomain }}" diff --git a/charts/plane-enterprise/templates/ingress-traefik.yaml b/charts/plane-enterprise/templates/ingress-traefik.yaml index 3aac24cf..2c75f218 100644 --- a/charts/plane-enterprise/templates/ingress-traefik.yaml +++ b/charts/plane-enterprise/templates/ingress-traefik.yaml @@ -9,7 +9,7 @@ metadata: namespace: {{ .Release.Namespace }} spec: entryPoints: - - websecure + {{- include "plane.traefikEntryPoints" . | nindent 4 }} routes: @@ -117,7 +117,9 @@ spec: - name: {{ .Release.Name }}-web port: 3000 + {{- if eq (include "plane.chartManagedCert" .) "true" }} tls: secretName: {{ default (printf "%s-ssl-cert" .Release.Name) .Values.ssl.tls_secret_name }} + {{- end }} {{- end }} diff --git a/charts/plane-enterprise/values.yaml b/charts/plane-enterprise/values.yaml index 56f03792..779d6d67 100644 --- a/charts/plane-enterprise/values.yaml +++ b/charts/plane-enterprise/values.yaml @@ -48,6 +48,16 @@ ingress: # ingress_annotations: { "nginx.ingress.kubernetes.io/proxy-body-size": "5m", "nginx.ingress.kubernetes.io/proxy-buffer-size": "16k" } traefik: maxRequestBodyBytes: 20971520 # in bytes (default: 20 MiB) + # Traefik entrypoints the IngressRoute attaches to. Leave empty to derive them + # from your SSL settings, which is what you want in almost every case: + # - TLS configured (ssl.tls_secret_name, or generateCerts + createIssuer) + # -> ['websecure'], and a `tls:` block is emitted. + # - No TLS configured -> ['web'], plain HTTP, and NO `tls:` block. Use this + # to reach Plane over http:// while you are still sorting out DNS/certs, + # or when TLS is terminated upstream (cloud LB, Cloudflare, a service mesh). + # Set explicitly only if your Traefik install renamed the default entrypoints, + # e.g. entryPoints: ['websecure', 'web'] or ['https']. + entryPoints: [] ssl: tls_secret_name: '' # If you have a custom TLS secret name @@ -58,6 +68,25 @@ ssl: server: https://acme-v02.api.letsencrypt.org/directory email: plane@example.com generateCerts: false + # Set true when TLS is terminated IN FRONT of Plane and this chart manages no + # certificate of its own -- a cloud load balancer, Cloudflare, a service mesh, + # or a Traefik entrypoint that carries its own cert (websecure.http.tls=true). + # + # The chart then renders every self-referential URL handed to the app + # (APP_BASE_URL, PLANE_FRONTEND_URL, PLANE_OAUTH_REDIRECT_URI, + # EXPORT_DOWNLOAD_BASE_URL, ...) with an https:// scheme. No `tls:` block is + # emitted, because there is no Secret for this chart to reference. + # + # This does NOT change the Traefik entrypoint. An upstream terminator (ALB, + # NLB TLS listener, Cloudflare) forwards cleartext, which arrives on `web` -- + # the default. If TLS is instead terminated by Traefik's own entrypoint + # (websecure.http.tls=true), also set: + # ingress.traefik.entryPoints: ['websecure'] + # otherwise the route binds `web` and never matches the TLS traffic. + # + # Leave false if you set tls_secret_name or generateCerts -- those already + # imply https. This is only for TLS this chart cannot see. + externalTermination: false # ============================================================ # Pod Security (Kubernetes Pod Security Admission "restricted")