Skip to content

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:

  1. infrastructure.yaml - Deploys external Helm charts from public registries (Bitnami, Jetstack, etc.)
  2. 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

  1. Self-Contained Charts: When migrating a chart like extra-secrets from Jenkins X, all files go in one directory - easier to reason about and maintain

  2. Clear Separation of Concerns:

  3. infrastructure/ = Configuration for external Helm charts
  4. charts/ = Complete custom Helm charts with values

  5. Standard Helm Pattern: Helm charts traditionally include their values files - this follows that convention

  6. Easier Discovery: Developers can find everything related to a custom chart in one location

  7. ApplicationSet Simplicity: The custom-charts ApplicationSet can reference values using simple relative paths:

    valueFiles:
      - $values/global/values.yaml
      - values-{{.env}}.yaml  # Relative to chart directory
    

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 use charts/
  • 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

  1. applicationsets/custom-charts.yaml
  2. Changed valueFiles path from $values/infrastructure/{{.path.basename}}/values-{{.env}}.yaml
  3. To: values-{{.env}}.yaml (relative to chart path)

  4. README.md

  5. Updated directory structure documentation
  6. Updated "Add Custom Chart" examples

  7. docs/applicationsets.md

  8. Updated custom charts explanation
  9. Updated example chart structure

  10. IMPLEMENTATION-SUMMARY.md

  11. Updated custom-charts ApplicationSet description
  12. 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.

  • ApplicationSets auto-discovery pattern (documented in docs/applicationsets.md)
  • Value hierarchy: global → environment → service (documented in README.md)

References