Correctif de #56, qui ne s'appliquait pas. CrowdSec n'a pas été interrompu — le Deployment est resté inchangé — mais l'Application ArgoCD était en SyncError et le correctif n'avait aucun effet.
Ce qui n'allait pas
#56 fixait le nom de machine avec un simple value: crowdsec-lapi dans lapi.env. Le rendu était valide, et au runtime Kubernetes retient bien la dernière des deux définitions — un pod de test le confirmait.
Mais ce n'est pas le runtime qui décide ici, c'est l'apply.
env est une liste à clé de fusion (name). Le strategic merge patch fusionne donc les deux entrées CUSTOM_HOSTNAME en une seule, qui porte alors le valueFrom du chart et notre value. L'API refuse :
Deployment.apps "crowdsec-lapi" is invalid:
spec.template.spec.containers[0].env[5].valueFrom: Invalid value: "":
may not be specified when `value` is not empty
ArgoCD a réessayé cinq fois puis s'est arrêté en SyncError.
Le correctif
Un valueFromdes deux côtés. La fusion écrase alors proprement le fieldPath et laisse une seule entrée valide.
Un fieldRef ne sait lire qu'un champ du pod, et tous ceux qu'expose le chart varient (le nom) ou disent autre chose (k8s-app, type). On pose donc un label dédié machine-name via lapi.podLabels, et on pointe dessus.
Vérification
Cette fois sur le chemin qui compte — kubectl apply --dry-run=server -o json contre le Deployment vivant :
helm template ne voit rien de tout ça : le rendu est valide dans les deux formes. Seule la fusion avec l'objet vivant les distingue. Le commentaire du values.yaml dit explicitement de ne pas « simplifier » en value:, et pourquoi.
Correctif de #56, qui ne s'appliquait pas. **CrowdSec n'a pas été interrompu** — le Deployment est resté inchangé — mais l'Application ArgoCD était en `SyncError` et le correctif n'avait aucun effet.
## Ce qui n'allait pas
#56 fixait le nom de machine avec un simple `value: crowdsec-lapi` dans `lapi.env`. Le rendu était valide, et au runtime Kubernetes retient bien la dernière des deux définitions — un pod de test le confirmait.
Mais ce n'est pas le runtime qui décide ici, c'est **l'apply**.
`env` est une liste à **clé de fusion** (`name`). Le strategic merge patch fusionne donc les deux entrées `CUSTOM_HOSTNAME` en **une seule**, qui porte alors le `valueFrom` du chart **et** notre `value`. L'API refuse :
```
Deployment.apps "crowdsec-lapi" is invalid:
spec.template.spec.containers[0].env[5].valueFrom: Invalid value: "":
may not be specified when `value` is not empty
```
ArgoCD a réessayé cinq fois puis s'est arrêté en `SyncError`.
## Le correctif
Un `valueFrom` **des deux côtés**. La fusion écrase alors proprement le `fieldPath` et laisse une seule entrée valide.
Un `fieldRef` ne sait lire qu'un champ du pod, et tous ceux qu'expose le chart varient (le nom) ou disent autre chose (`k8s-app`, `type`). On pose donc un label dédié `machine-name` via `lapi.podLabels`, et on pointe dessus.
## Vérification
Cette fois sur le chemin qui compte — `kubectl apply --dry-run=server -o json` contre le Deployment vivant :
```json
occurrences de CUSTOM_HOSTNAME après fusion : 1
{"name": "CUSTOM_HOSTNAME",
"valueFrom": {"fieldRef": {"fieldPath": "metadata.labels['machine-name']"}}}
label machine-name : crowdsec-lapi
```
## La leçon, consignée dans le values
`helm template` ne voit rien de tout ça : le rendu est valide dans les deux formes. Seule la fusion avec l'objet vivant les distingue. Le commentaire du `values.yaml` dit explicitement de ne pas « simplifier » en `value:`, et pourquoi.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
#56 fixait le nom de machine de la LAPI avec un simple `value: crowdsec-lapi`
dans `lapi.env`. Ça rendait correctement, et au runtime Kubernetes retient bien
la dernière des deux définitions — un pod de test le confirmait. Mais ce n'est
pas le runtime qui décide : c'est l'apply, et là ça cassait.
`env` est une liste à clé de fusion (`name`). Le strategic merge patch fusionne
donc les deux entrées CUSTOM_HOSTNAME en UNE, qui porte alors le `valueFrom` du
chart ET notre `value`. L'API refuse :
Deployment.apps "crowdsec-lapi" is invalid:
spec.template.spec.containers[0].env[5].valueFrom: Invalid value: "":
may not be specified when `value` is not empty
ArgoCD a réessayé cinq fois puis s'est arrêté en SyncError. Le Deployment est
resté INCHANGÉ — CrowdSec n'a pas été interrompu, mais le correctif n'était pas
appliqué et l'application restait OutOfSync.
Correctif : un `valueFrom` des deux côtés. La fusion écrase alors proprement le
fieldPath et laisse une seule entrée valide. Comme un fieldRef ne sait lire qu'un
champ du pod, et que tous ceux qu'expose le chart varient (le nom) ou disent
autre chose (`k8s-app`, `type`), on pose un label dédié `machine-name` via
`lapi.podLabels` et on pointe dessus.
Vérifié cette fois sur le chemin qui compte :
kubectl apply --dry-run=server -o json
→ une SEULE occurrence de CUSTOM_HOSTNAME, pointant sur
metadata.labels['machine-name'], label valant `crowdsec-lapi`.
La leçon est dans le commentaire du values : `helm template` ne voit rien de
tout ça, le rendu est valide des deux côtés. Seule la fusion avec l'objet vivant
distingue les deux formes.
Co-Authored-By: Claude Opus 5 <[email protected]>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Correctif de #56, qui ne s'appliquait pas. CrowdSec n'a pas été interrompu — le Deployment est resté inchangé — mais l'Application ArgoCD était en
SyncErroret le correctif n'avait aucun effet.Ce qui n'allait pas
#56 fixait le nom de machine avec un simple
value: crowdsec-lapidanslapi.env. Le rendu était valide, et au runtime Kubernetes retient bien la dernière des deux définitions — un pod de test le confirmait.Mais ce n'est pas le runtime qui décide ici, c'est l'apply.
envest une liste à clé de fusion (name). Le strategic merge patch fusionne donc les deux entréesCUSTOM_HOSTNAMEen une seule, qui porte alors levalueFromdu chart et notrevalue. L'API refuse :ArgoCD a réessayé cinq fois puis s'est arrêté en
SyncError.Le correctif
Un
valueFromdes deux côtés. La fusion écrase alors proprement lefieldPathet laisse une seule entrée valide.Un
fieldRefne sait lire qu'un champ du pod, et tous ceux qu'expose le chart varient (le nom) ou disent autre chose (k8s-app,type). On pose donc un label dédiémachine-namevialapi.podLabels, et on pointe dessus.Vérification
Cette fois sur le chemin qui compte —
kubectl apply --dry-run=server -o jsoncontre le Deployment vivant :La leçon, consignée dans le values
helm templatene voit rien de tout ça : le rendu est valide dans les deux formes. Seule la fusion avec l'objet vivant les distingue. Le commentaire duvalues.yamldit explicitement de ne pas « simplifier » envalue:, et pourquoi.🤖 Generated with Claude Code
value:de #56 ne passait pas l'apply