agentleFS
11me11me/skillbox/helm-chart-developer/SKILL.md

helm-chart-developer

Skill4 starsChanged 10 months agoMITView on GitHub

Helm chart authoring, values.yaml design, GitOps with Flux HelmRelease, External Secrets Operator integration. Use for creating and debugging Helm charts.

The file

We split this skill into the rules it gives an agent

10 rules. About 0 are common, 5 are distinctive, and 5 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈5

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 5

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use this skill when:

    line 12
  2. Distinctive:

    Rule: If adding manifests, ALWAYS use these API versions.

    line 36
  3. Distinctive:

    If CRD/apiVersion mismatch detected in repo, STOP and propose migration plan.

    line 37
  4. Distinctive:

    Before completing any Helm chart work:

    line 43
  5. Very specific:

    Run /helm-validate to execute all checks.

    line 54
  6. Very specific:

    Default rule: Use refreshPolicy: OnChange for predictable GitOps-driven updates.

    line 131
  7. Very specific:

    Use spec.dependsOn in HelmRelease when app depends on:

    line 160
  8. Very specific:

    OpenAPI validation: Use install.disableOpenAPIValidation: true in HelmRelease if needed.

    line 212
  9. Very specific:

    NEVER put secrets in values.yaml: No passwords, tokens, API keys, credentials.

    line 213
  10. Distinctive:

    Only references to Secret/ExternalSecret names.

    line 214

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Helm Chart Developer

Purpose / When to Use

Use this skill when:

  • Creating new Helm charts from scratch
  • Converting raw Kubernetes manifests to Helm
  • Designing values.yaml API and schema
  • Setting up GitOps deployment with Flux HelmRelease
  • Integrating External Secrets Operator (ESO)
  • Debugging helm template, helm lint, helm install --dry-run
  • Setting up multi-environment overlays (dev/prod)

Version & API Compatibility

Always use these API versions:

ComponentAPI VersionNotes
Helm ChartapiVersion: v2Helm 3+ charts
Flux HelmReleasehelm.toolkit.fluxcd.io/v2Current stable
Flux HelmRepositorysource.toolkit.fluxcd.io/v1Current stable
Flux Kustomizationkustomize.toolkit.fluxcd.io/v1Current stable
ExternalSecretexternal-secrets.io/v1ESO v1 API
ClusterSecretStoreexternal-secrets.io/v1With spec.conditions[].namespaceSelector

Target baseline: Kubernetes 1.29+, Helm 3.14+, Flux v2.3+, ESO 0.10+

Rule: If adding manifests, ALWAYS use these API versions. If CRD/apiVersion mismatch detected in repo, STOP and propose migration plan.

See VERSIONS.md for full compatibility matrix.

Definition of Done (DoD)

Before completing any Helm chart work:

  1. Linting: helm lint . passes
  2. Template rendering: helm template <release> . succeeds
  3. Schema validation (optional): helm template . | kubeconform -strict
  4. Dry-run: helm install <release> . --dry-run --debug works
  5. Two secrets modes validated:
    • GitOps mode: --set secrets.existingSecretName=<name>
    • Chart-managed ESO: --set secrets.externalSecret.enabled=true
  6. API versions match the compatibility table above

Run /helm-validate to execute all checks.

Step-by-Step Workflow

1. Chart Structure

charts/app/
├── Chart.yaml
├── values.yaml
├── templates/
│   ├── _helpers.tpl
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   ├── externalsecret.yaml  # optional, gated
│   ├── hpa.yaml
│   ├── pdb.yaml
│   └── serviceaccount.yaml

2. Values API Contract

See reference-gitops-eso.md for full details.

Key sections:

  • image: repository, tag, pullPolicy
  • secrets: existingSecretName, externalSecret.*, inject.envFrom
  • service: enabled, type, port
  • ingress: enabled, className, hosts, tls
  • resources: requests, limits
  • autoscaling: enabled, minReplicas, maxReplicas

3. Secrets Integration

Mode A: ExternalSecret in Overlay (Recommended)

Chart only references secret by name:

# values.yaml
secrets:
  existingSecretName: "app-secrets"
  inject:
    envFrom: true

ExternalSecret lives in GitOps overlay, not in chart.

Mode B: Chart-Managed ExternalSecret (Optional)

Chart renders ExternalSecret when enabled:

secrets:
  externalSecret:
    enabled: true
    refreshInterval: 1h
    refreshPolicy: OnChange
    secretStoreRef:
      kind: ClusterSecretStore
      name: aws-secrets-manager
    dataFrom:
      extractKey: "fce/dev/app"
    target:
      name: "app-secrets"
      creationPolicy: Owner

Secrets Determinism (ESO)

refreshPolicy options:

PolicyBehaviorUse Case
OnChangeUpdates when ExternalSecret manifest changesGitOps (default, recommended)
CreatedOnceNever updates after creationImmutable credentials
PeriodicUpdates on interval (refreshInterval)Legacy, auto-rotation

Default rule: Use refreshPolicy: OnChange for predictable GitOps-driven updates.

Manual refresh (debug/runbook):

kubectl annotate es <name> force-sync=$(date +%s) --overwrite

4. Flux + Kustomize Recipe

Values Composition Order (important!):

  1. Chart defaults (charts/app/values.yaml)
  2. Environment values (apps/dev/app/values.yaml)
  3. ConfigMap via Kustomize generator
  4. HelmRelease valuesFrom references ConfigMap
  5. HelmRelease spec.values patches (highest priority)

See snippets:

  • flux-helmrelease.base.yaml
  • flux-helmrelease.dev.patch.yaml
  • kustomize.configmapgenerator.yaml

Critical Kustomize settings:

generatorOptions:
  disableNameSuffixHash: true  # MUST have, otherwise names change on every apply

Flux Ordering

Use spec.dependsOn in HelmRelease when app depends on:

  • CRDs (external-secrets, cert-manager)
  • ExternalSecrets/SecretStores
  • Ingress controllers, databases

Example:

spec:
  dependsOn:
    - name: external-secrets
      namespace: external-secrets

5. ESO Patterns

ClusterSecretStore (cluster-wide):

apiVersion: external-secrets.io/v1
kind: ClusterSecretStore
metadata:
  name: aws-secrets-manager
spec:
  conditions:
    - namespaceSelector:
        matchLabels:
          eso.fce.global/enabled: "true"
  provider:
    aws:
      service: SecretsManager
      region: me-central-1

ExternalSecret (per app/env):

apiVersion: external-secrets.io/v1
kind: ExternalSecret
spec:
  refreshPolicy: OnChange  # GitOps-deterministic
  secretStoreRef:
    kind: ClusterSecretStore
    name: aws-secrets-manager
  dataFrom:
    - extract:
        key: fce/dev/app
  target:
    name: app-secrets
    creationPolicy: Owner

6. Pitfalls

  • CRD ordering: ESO CRDs must exist before ExternalSecret. Use Flux Kustomization dependsOn.
  • OpenAPI validation: Use install.disableOpenAPIValidation: true in HelmRelease if needed.
  • NEVER put secrets in values.yaml: No passwords, tokens, API keys, credentials. Only references to Secret/ExternalSecret names. This is non-negotiable.

Examples

Prompts that should activate this skill:

  1. "Create a Helm chart for my Node.js app"
  2. "Convert these Kubernetes manifests to Helm"
  3. "Add External Secrets integration to my chart"
  4. "Set up Flux HelmRelease for my app"
  5. "Debug why helm template is failing"
  6. "Design values.yaml schema for multi-environment deployment"
  7. "Add ingress with TLS to my Helm chart"
  8. "Integrate AWS Secrets Manager with my chart"
  9. "Set up Kustomize overlays for dev and prod"
  10. "Fix helm lint errors in my chart"

Anti-Patterns

❌ Avoid✅ Instead
Hardcode secrets in values.yamlUse ExternalSecret with secretStoreRef
Single values.yaml for all envsKustomize overlays per environment
HelmRelease v2beta1 / v2beta2 APIUse helm.toolkit.fluxcd.io/v2
Manual Secret creationESO with ClusterSecretStore
Inline helm values in HelmReleaseExternal values.yaml + patches via valuesFrom
Skip helm lint / helm templateAlways validate with /helm-validate
refreshPolicy: Periodic for GitOpsUse refreshPolicy: OnChange for determinism
Kustomize namesSuffixHash: trueAlways disableNameSuffixHash: true for ConfigMaps
Put ExternalSecret in Helm chartPut ExternalSecret in GitOps overlay (Mode A)
Skip dependsOn for CRDsUse spec.dependsOn for external-secrets, cert-manager

Related Files

  • VERSIONS.md - Version compatibility matrix
  • reference-gitops-eso.md - Full GitOps + ESO reference
  • snippets/ - Ready-to-use YAML snippets

Version History

  • 1.1.0 — Add version compatibility, secrets determinism, Flux ordering
  • 1.0.0 — Initial release with Flux + ESO patterns

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.