refactor: make this a reusable deployment, not ours

Every environment value is a ${VAR} for the caller to substitute: hostname,
images, storage, ingress class, TLS issuer, Vault server and path, timezone,
retention. Nothing in k8s/ names a host, a realm, an agent or an estate.

Removed: the Flux plumbing under dev/, which described one deployment, and the
ExternalSecret pulling a specific agent's Keycloak client secret. Both belong to
whoever deploys this. The lab CA ConfigMap goes with them — the mount stays,
parameterised and marked optional, because 'trust a private CA' is a property of
an environment and not of n8n.

The README is now the template's: how to consume it, what every variable means,
and the three things it deliberately does not do.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Stéphane Tailland
2026-08-29 13:10:05 +02:00
parent c4747a6149
commit d68d20c6f4
18 changed files with 141 additions and 247 deletions
+7 -8
View File
@@ -1,17 +1,16 @@
# cert-manager issues this into the `n8n-tls` Secret, from the same
# ClusterIssuer as the rest of the estate.
# cert-manager issues this into the `n8n-tls` Secret.
#
# Deliberately not a copy of a certificate committed to git: the private key
# stays in the cluster, is rotated by cert-manager, and never reaches a repo.
# Deliberately not a certificate copied into the repo: the private key is
# generated in the cluster, rotated by cert-manager, and never reaches git.
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: n8n-tls
namespace: n8n
namespace: ${NAMESPACE}
spec:
secretName: n8n-tls
dnsNames:
- n8n.sttlab.local
- ${N8N_HOSTNAME}
issuerRef:
name: sttlab-local-ca
kind: ClusterIssuer
name: ${TLS_ISSUER_NAME}
kind: ${TLS_ISSUER_KIND}
+5 -5
View File
@@ -2,24 +2,24 @@ apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: n8n
namespace: n8n
namespace: ${NAMESPACE}
annotations:
# The editor pushes execution progress over a long-lived connection, and
# imports can be large. Buffering it defeats the first; the default body
# size defeats the second.
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
nginx.ingress.kubernetes.io/proxy-body-size: ${INGRESS_BODY_SIZE}
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-buffering: "off"
nginx.ingress.kubernetes.io/proxy-http-version: "1.1"
spec:
ingressClassName: nginx
ingressClassName: ${INGRESS_CLASS}
tls:
- hosts:
- n8n.sttlab.local
- ${N8N_HOSTNAME}
secretName: n8n-tls
rules:
- host: n8n.sttlab.local
- host: ${N8N_HOSTNAME}
http:
paths:
- path: /