ADR-001: Custom Chart Values Co-Location¶
Status¶
Approved - 2025-01-12
Context¶
The cluster-gitops repository uses two ApplicationSets to manage Helm chart deployments:
- infrastructure.yaml - Deploys external Helm charts from public registries (Bitnami, Jetstack, etc.)
- custom-charts.yaml - Deploys custom charts maintained in this repository
Problem¶
Initially, both ApplicationSets stored their values files in the infrastructure/ directory:
infrastructure/
cert-manager/ # External chart from Jetstack
config.yaml
values.yaml
extra-secrets/ # Custom chart from cluster-gitops
values-staging.yaml
values-production.yaml
charts/
extra-secrets/ # Custom chart source
Chart.yaml
templates/
This created confusion:
- Why are custom chart values stored separately from the chart itself?
- The infrastructure/ folder mixed two different concepts (external vs custom)
- Values were not co-located with the charts they configure
Question¶
Where should custom chart values files be stored?
Options:
A. Keep current structure - Both external and custom charts use infrastructure/ for values
- Pro: Single location for all infrastructure-related values
- Con: Confusing separation of custom chart from its values
- Con: Mixes external and custom chart concepts
B. Merge ApplicationSets - Combine infrastructure.yaml and custom-charts.yaml - Pro: Single ApplicationSet to maintain - Con: Complex logic to handle both external and local charts - Con: Different source patterns (chart vs path) harder to template
C. Co-locate custom chart values - Store values with the chart in charts/
- Pro: Self-contained custom charts (chart + values together)
- Pro: Clear separation: infrastructure/ = external, charts/ = custom
- Pro: Easier to migrate charts from other systems (all files in one place)
- Con: Values in different locations depending on chart type
Decision¶
Option C: Co-locate custom chart values with charts
Custom charts stored in charts/ will have their environment-specific values files alongside the chart:
charts/
extra-secrets/
Chart.yaml
values.yaml # Default values
values-staging.yaml # Staging overrides
values-production.yaml # Production overrides
templates/
external-secrets.yaml
infrastructure/
cert-manager/ # External chart only
config.yaml # Points to Jetstack repo
values.yaml # Values for external chart
Rationale¶
-
Self-Contained Charts: When migrating a chart like
extra-secretsfrom Jenkins X, all files go in one directory - easier to reason about and maintain -
Clear Separation of Concerns:
infrastructure/= Configuration for external Helm charts-
charts/= Complete custom Helm charts with values -
Standard Helm Pattern: Helm charts traditionally include their values files - this follows that convention
-
Easier Discovery: Developers can find everything related to a custom chart in one location
-
ApplicationSet Simplicity: The custom-charts ApplicationSet can reference values using simple relative paths:
Consequences¶
Positive¶
- Clearer structure - No confusion about where values belong
- Self-contained - Custom charts are complete packages
- Easier migration - Moving charts from other systems is straightforward
- Better maintainability - Related files stay together
Negative¶
- Two patterns for values - External charts use
infrastructure/, custom charts usecharts/ - Documentation needed - Must clearly explain the two different approaches
Neutral¶
- No breaking changes yet - This is implementation of new structure, no existing charts to migrate
Implementation¶
Files Modified¶
- applicationsets/custom-charts.yaml
- Changed valueFiles path from
$values/infrastructure/{{.path.basename}}/values-{{.env}}.yaml -
To:
values-{{.env}}.yaml(relative to chart path) -
README.md
- Updated directory structure documentation
-
Updated "Add Custom Chart" examples
-
docs/applicationsets.md
- Updated custom charts explanation
-
Updated example chart structure
-
IMPLEMENTATION-SUMMARY.md
- Updated custom-charts ApplicationSet description
- Updated "Add Custom Chart" workflow
Migration Guide¶
When adding a new custom chart:
# Create chart structure
mkdir -p charts/my-chart/templates
# Create Chart.yaml
cat > charts/my-chart/Chart.yaml <<EOF
apiVersion: v2
name: my-chart
version: 0.1.0
description: My custom chart
EOF
# Create default values
cat > charts/my-chart/values.yaml <<EOF
# Default values for my-chart
replicaCount: 1
EOF
# Create environment-specific values
cat > charts/my-chart/values-staging.yaml <<EOF
# Staging overrides
replicaCount: 2
EOF
cat > charts/my-chart/values-production.yaml <<EOF
# Production overrides
replicaCount: 3
EOF
# Add templates
# ... create Kubernetes manifests in templates/
# Commit and push
git add charts/my-chart
git commit -m "feat: add my-chart custom chart"
git push
ApplicationSet will automatically discover and deploy to both environments.
Related Decisions¶
- ApplicationSets auto-discovery pattern (documented in docs/applicationsets.md)
- Value hierarchy: global → environment → service (documented in README.md)
References¶
- ArgoCD ApplicationSets Documentation
- Helm Best Practices - Values Files
- Slack discussion: 2025-01-12 "Custom chart values location"