From 2ea469af1e9f82b2583254c6642e3bde10e2dc05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Tailland?= Date: Mon, 31 Aug 2026 07:57:08 +0200 Subject: [PATCH] Default the optional env-secret slots optional: true covers a Secret that does not exist; it does not cover the variable being unset. Flux substitutes in strict mode, so the unused second slot failed the whole build and every change to this repo since has silently stopped reaching the cluster. Co-Authored-By: Claude Opus 5 --- README.md | 2 +- k8s/n8n/deployment.yaml | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 9b1136f..ea6418d 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ The namespace must exist first, and so must the AppRole Secret the store reads. | `TLS_ISSUER_NAME`, `TLS_ISSUER_KIND` | a cert-manager issuer, e.g. `ClusterIssuer` | | `VAULT_SERVER`, `VAULT_MOUNT`, `VAULT_SECRET_PATH` | where the two secrets live | | `VAULT_STORE_NAME`, `VAULT_APPROLE_SECRET` | the `ClusterSecretStore` this creates, and the AppRole Secret in `external-secrets` it authenticates with | -| `EXTRA_ENV_SECRET`, `EXTRA_ENV_SECRET_2` | Secrets whose keys become environment variables for workflows. Two slots, because a deployment's environment usually comes from more than one owner. Both `optional`, so an unused slot needs no placeholder | +| `EXTRA_ENV_SECRET`, `EXTRA_ENV_SECRET_2` | Secrets whose keys become environment variables for workflows. Two slots, because a deployment's environment usually comes from more than one owner. Both carry defaults and are `optional`, so an unused slot needs neither a variable nor a Secret. Substitution runs in strict mode — without the default, leaving one unset fails the whole build | | `EXTRA_CA_CONFIGMAP` | a ConfigMap with `ca.crt`, mounted and set as `NODE_EXTRA_CA_CERTS`, so workflows can call internal TLS endpoints without verification being disabled. Marked `optional`, so an absent one is not an error | | `BLOCK_ENV_ACCESS` | `"true"` blocks `$env` in workflow expressions. n8n's default, and the right one wherever more than one team writes workflows: any workflow can otherwise read any variable in the pod. `"false"` is how a secret reaches a workflow without being committed in its JSON | | `EXECUTIONS_MAX_AGE_HOURS` | how long executions are kept. n8n keeps them for ever by default, which turns the database into a log | diff --git a/k8s/n8n/deployment.yaml b/k8s/n8n/deployment.yaml index 5f26b9c..5183ee5 100644 --- a/k8s/n8n/deployment.yaml +++ b/k8s/n8n/deployment.yaml @@ -81,13 +81,19 @@ spec: # # Two slots rather than one, because a deployment's environment # usually comes from more than one owner — credentials the platform - # holds, and credentials a workflow's own estate holds. Both are - # marked optional, so an unused slot needs no placeholder Secret. + # holds, and credentials a workflow's own estate holds. + # + # `optional: true` covers a Secret that does not exist; the `:=` + # defaults cover the *variable* not being set. Both are needed, and + # only the first was here: Flux substitutes in strict mode, so an + # unused slot failed the whole build rather than being skipped, and + # every later change to this repo silently stopped reaching the + # cluster. - secretRef: - name: ${EXTRA_ENV_SECRET} + name: ${EXTRA_ENV_SECRET:=n8n-extra-env} optional: true - secretRef: - name: ${EXTRA_ENV_SECRET_2} + name: ${EXTRA_ENV_SECRET_2:=n8n-extra-env-2} optional: true volumeMounts: - name: data