From ec4df4719fcb387023557a25185ac2b2178d1b08 Mon Sep 17 00:00:00 2001 From: Gabriel Radureau Date: Sun, 31 May 2026 23:26:20 +0200 Subject: [PATCH] chart: template hardcoded single-env literals; add values-sandbox.yaml overlay MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase C of the multi-env evolution discussed in the runbook design thread (see PR description). Pure refactor — the prod helm template render is verified byte-identical (10857 bytes both before and after, diff exit 0). What was hardcoded, now templated: - chart/templates/vaultauth.yaml role: erp → role: {{ .Values.vault.k8sRole }} - chart/templates/vaultdynamicsecret.yaml path: creds/erp → path: {{ .Values.vault.dynamicPath }} - chart/templates/vaultsecret.yaml path: erp/config → path: {{ .Values.vault.staticPath }} - chart/templates/config.yaml DOLI_DB_NAME: erp → DOLI_DB_NAME: {{ .Values.db.name }} DOLI_URL_ROOT: https://erp..lab → DOLI_URL_ROOT: 'https://{{ .Values.host }}' values.yaml gains a documented multi-env coordinate block with prod defaults (env, instance, host, db.name, vault.k8sRole, vault.dynamicPath, vault.staticPath). The elision rule (env=prod → no suffix, env=non-prod → "-" suffix) guarantees the prod render is unchanged. chart/values-sandbox.yaml is added as the ready-to-use overlay for Phase D. It is NOT wired into any helm install / ArgoCD app today — the platform side (factory/postgres/iac tfvars, tools/hashicorp-vault/iac module signature) is not yet evolved. The file documents the convention so the Phase D commit can just `helm install -f values.yaml -f values-sandbox.yaml`. Also fixes .gitea/workflows/vault.yaml CI typo: the vault_step JWT role was gitea_cicd_webapp (copy-paste from the template repo) instead of gitea_cicd_erp. Real bug — the erp CI would have failed JWT auth against Vault. Fix unrelated to multi-env but bundled here because it's small and touches the same file family. Co-Authored-By: Claude Opus 4.7 (1M context) --- .gitea/workflows/vault.yaml | 2 +- chart/templates/config.yaml | 4 +-- chart/templates/vaultauth.yaml | 2 +- chart/templates/vaultdynamicsecret.yaml | 2 +- chart/templates/vaultsecret.yaml | 2 +- chart/values-sandbox.yaml | 39 +++++++++++++++++++++++++ chart/values.yaml | 20 +++++++++++++ 7 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 chart/values-sandbox.yaml diff --git a/.gitea/workflows/vault.yaml b/.gitea/workflows/vault.yaml index c49c237..e6702f5 100644 --- a/.gitea/workflows/vault.yaml +++ b/.gitea/workflows/vault.yaml @@ -22,7 +22,7 @@ concurrency: url: https://vault.arcodange.lab caCertificate: ${{ secrets.HOMELAB_CA_CERT }} jwtGiteaOIDC: ${{ needs.gitea_vault_auth.outputs.gitea_vault_jwt }} - role: gitea_cicd_webapp + role: gitea_cicd_erp method: jwt path: gitea_jwt secrets: | diff --git a/chart/templates/config.yaml b/chart/templates/config.yaml index 2407687..432468c 100644 --- a/chart/templates/config.yaml +++ b/chart/templates/config.yaml @@ -10,8 +10,8 @@ data: DOLI_DB_HOST_PORT: !!str 5432 # DOLI_DB_USER: root # DOLI_DB_PASSWORD: root - DOLI_DB_NAME: erp - DOLI_URL_ROOT: 'https://erp.arcodange.lab' + DOLI_DB_NAME: {{ .Values.db.name }} + DOLI_URL_ROOT: 'https://{{ .Values.host }}' # DOLI_ADMIN_LOGIN: 'admin' # DOLI_ADMIN_PASSWORD: 'admininitialpassword' DOLI_ENABLE_MODULES: Societe,Facture diff --git a/chart/templates/vaultauth.yaml b/chart/templates/vaultauth.yaml index fe2adf0..c36930e 100644 --- a/chart/templates/vaultauth.yaml +++ b/chart/templates/vaultauth.yaml @@ -7,7 +7,7 @@ spec: method: kubernetes mount: kubernetes kubernetes: - role: erp + role: {{ .Values.vault.k8sRole }} serviceAccount: {{ include "erp.serviceAccountName" . }} audiences: - vault \ No newline at end of file diff --git a/chart/templates/vaultdynamicsecret.yaml b/chart/templates/vaultdynamicsecret.yaml index 3087210..f5f7653 100644 --- a/chart/templates/vaultdynamicsecret.yaml +++ b/chart/templates/vaultdynamicsecret.yaml @@ -9,7 +9,7 @@ spec: mount: postgres # Path to the secret - path: creds/erp + path: {{ .Values.vault.dynamicPath }} # Where to store the secrets, VSO will create the secret destination: diff --git a/chart/templates/vaultsecret.yaml b/chart/templates/vaultsecret.yaml index de37805..aa69c76 100644 --- a/chart/templates/vaultsecret.yaml +++ b/chart/templates/vaultsecret.yaml @@ -10,7 +10,7 @@ spec: mount: kvv2 # path of the secret - path: erp/config + path: {{ .Values.vault.staticPath }} # dest k8s secret destination: diff --git a/chart/values-sandbox.yaml b/chart/values-sandbox.yaml new file mode 100644 index 0000000..ce25ddf --- /dev/null +++ b/chart/values-sandbox.yaml @@ -0,0 +1,39 @@ +# Sandbox overlay — to be combined with values.yaml: +# helm install erp-sandbox chart/ -f chart/values.yaml -f chart/values-sandbox.yaml \ +# --namespace erp-sandbox --create-namespace +# +# Activates Phase D of the multi-env evolution (cf. PR thread). Prerequisites: +# - factory/postgres/iac/terraform.tfvars: erp has envs = ["prod", "sandbox"] +# - tools/hashicorp-vault/iac/modules/app_roles: env parameter applied +# - arcodange-org/erp/iac/main.tf: for_each over local.envs (Phase D commit) +# - ArgoCD: Application "erp-sandbox" registered (Phase E) +# +# Derived names follow the elision rule: env=sandbox → suffix "-sandbox". + +env: sandbox +instance: erp-sandbox +host: erp-sandbox.arcodange.lab + +db: + name: erp-sandbox + +vault: + k8sRole: erp-sandbox + dynamicPath: creds/erp-sandbox + staticPath: erp-sandbox/config + +# Ingress annotations + hosts — override to point at the sandbox FQDN +ingress: + enabled: true + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + traefik.ingress.kubernetes.io/router.tls.certresolver: letsencrypt + traefik.ingress.kubernetes.io/router.tls.domains.0.main: arcodange.lab + traefik.ingress.kubernetes.io/router.tls.domains.0.sans: erp-sandbox.arcodange.lab + traefik.ingress.kubernetes.io/router.middlewares: localIp@file + hosts: + - host: erp-sandbox.arcodange.lab + paths: + - path: / + pathType: Prefix diff --git a/chart/values.yaml b/chart/values.yaml index 356f151..25929d3 100644 --- a/chart/values.yaml +++ b/chart/values.yaml @@ -2,6 +2,26 @@ # This is a YAML-formatted file. # Declare variables to be passed into your templates. +# ---------------------------------------------------------------------------- +# Multi-environment coordinates (default = prod, elision rule applies). +# Override in values-.yaml for any non-prod instance — see SKILL.md +# of the factory runbook (doc/runbooks/new-web-app/conventions.md). +# By the elision rule, env=prod produces names identical to single-env apps; +# env=sandbox produces "-sandbox" everywhere except the Postgres owner +# role which uses snake-case "_sandbox_role". +# ---------------------------------------------------------------------------- +env: prod +instance: erp # derived id: env=prod → erp, else - +host: erp.arcodange.lab # internal hostname for this instance + +db: + name: erp # PostgreSQL database name (matches factory tfvars) + +vault: + k8sRole: erp # VaultAuth role (postgres/iac issues this per instance) + dynamicPath: creds/erp # path under postgres/ mount for short-lived DB creds + staticPath: erp/config # path under kvv2/ mount for the static admin config + replicaCount: 1 image: