chart: template hardcoded single-env literals; add values-sandbox.yaml overlay

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 → "<app>-<env>" 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) <noreply@anthropic.com>
This commit is contained in:
2026-05-31 23:26:20 +02:00
parent 444886b91a
commit ec4df4719f
7 changed files with 65 additions and 6 deletions

View File

@@ -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: |

View File

@@ -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

View File

@@ -7,7 +7,7 @@ spec:
method: kubernetes
mount: kubernetes
kubernetes:
role: erp
role: {{ .Values.vault.k8sRole }}
serviceAccount: {{ include "erp.serviceAccountName" . }}
audiences:
- vault

View File

@@ -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:

View File

@@ -10,7 +10,7 @@ spec:
mount: kvv2
# path of the secret
path: erp/config
path: {{ .Values.vault.staticPath }}
# dest k8s secret
destination:

39
chart/values-sandbox.yaml Normal file
View File

@@ -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

View File

@@ -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-<env>.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 "<app>-sandbox" everywhere except the Postgres owner
# role which uses snake-case "<app>_sandbox_role".
# ----------------------------------------------------------------------------
env: prod
instance: erp # derived id: env=prod → erp, else <app>-<env>
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: