3.9 KiB
ADR-0012: String-interpolated Helm values from user config.yaml
Status: Accepted Category: COMMUNICATION Date decided: Project inception Date documented: 2026-05-13
Context
ArgoCD deploys are driven by Helm charts whose values.yaml files are produced per-build by deployArgoCD.groovy. The inputs are a service's deployment.yaml plus a handful of pipeline-derived fields (image tag, pod resources, JVM heap, etc.). Helm chart values.yaml is itself a templating surface — Helm's own {{ .Values.x }} syntax reads these files at install time — so anything produced here is interpreted as a template by the next layer, not as plain data.
Decision
deployArgoCD.groovy builds the rendered values.yaml by string-substituting fields into a stub template via chained .replaceAll() calls, rather than constructing it via a YAML library or a typed DTO and re-serialising. The team treats Helm's chart-values surface as a template-on-template stack: re-serialising via a YAML library would re-introduce template-syntax escaping problems (quoting {{ }}, preserving multi-line string semantics, handling Helm-specific structural tags) — keeping the entire pipeline string-native is the simpler invariant.
Alternatives Considered
No alternatives were explicitly evaluated by the team during this interview. The "use a typed YAML library / DTO and re-serialise" approach was acknowledged as the obvious counter-proposal but was rejected on the template-on-template grounds above.
Consequences
Positive:
- The renderer stays a one-layer string substitution — easy to read, easy to debug from a Jenkins console log.
- No risk of a typed re-serialisation silently re-escaping Helm
{{ }}templates or stripping comments. - Matches the rest of the pipeline, which is string-and-
shheavy.
Negative:
- User-supplied config values are not validated against a schema before substitution — a service's
deployment.yamlcontaining unescaped quotes, colons, or newlines can produce a malformedvalues.yaml(review-learnings PR #343 flagged this). - The implicit YAML-injection risk depends on every consumer service writing well-formed
deployment.yaml— there is no guardrail in the library itself. - Adding a new field requires editing the template stub AND the substitution chain in
deployArgoCD.groovytogether — easy to drift.
Neutral:
- The decision lives entirely in
deployArgoCD.groovy; switching strategies in future would be local to that file.
Constraints
- Helm chart values are interpreted as templates downstream — any solution must preserve template literals without escaping them.
- The shared library runs in the Jenkins sandbox, which constrains which Java / Groovy serialisation APIs are safely callable.
Current Assessment
- Adequate with caveats — the strategy is defensible, but the lack of input-validation guardrails (the YAML-injection surface called out in review learnings) remains an open risk. A targeted schema-validation pass before substitution would mitigate it without changing the rendering strategy.
Related Decisions
- ADR-0007: GitOps Deployments via Strict 4-Step ArgoCD Sync Sequence — the deploy mechanism that consumes the rendered
values.yaml. - ADR-0009: JVM Heap Auto-Derived from Pod memory_request — another pipeline-derived input to the same
values.yaml.
Notes
- Key files:
src/com/meesho/stages/deployArgoCD.groovy - Open risk: review-learnings PR #343 flagged the YAML-injection surface — input validation is the recommended mitigation.
- Discovery id: COMMUNICATION-2