From chogos
Helm chart development best practices. Use when creating, modifying, or reviewing Helm charts, templates, values files, Chart.yaml, or any Kubernetes resource templates under a helm/ directory.
How this skill is triggered — by the user, by Claude, or both
Slash command
/chogos:developing-helm-chartsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
- `Chart.yaml` (capitalized), all template files lowercase with dashed notation (`my-configmap.yaml`).
Chart.yaml (capitalized), all template files lowercase with dashed notation (my-configmap.yaml)..yaml for YAML output, .tpl for non-formatted content.mychart/
Chart.yaml
values.yaml
templates/
deployment.yaml
service.yaml
_helpers.tpl
tests/
charts/
crds/
.helmignore
apiVersion: v2. Semantic versioning for version, separate appVersion.name, description, type, version.maintainers, home, sources, keywords for discoverability.type: application (deployable) or library (reusable).serverHost, not server-host or ServerHost).--set compatibility.yes→bool, 0777→octal).{{ int $value }}.image.*, service.*, ingress.*).global sparingly. Support env-specific value files.Create values.schema.json alongside values.yaml. Helm validates values against this schema on install, upgrade, lint, and template:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"required": ["image"],
"properties": {
"replicaCount": {
"type": "integer",
"minimum": 1
},
"image": {
"type": "object",
"required": ["repository"],
"properties": {
"repository": { "type": "string" },
"tag": { "type": "string" },
"pullPolicy": {
"type": "string",
"enum": ["Always", "IfNotPresent", "Never"]
}
}
}
}
}
"true" where boolean expected, string where integer needed.helm lint — schema violations are reported as errors.{{- }} for whitespace control. Two spaces, never tabs.{{ and before }}.{{- define "nginx.fullname" }}.{{ .Values.image.tag | quote }}.required for mandatory values: {{ required "Image repo required" .Values.image.repository }}.include over template (pipeable, better errors)._helpers.tpl for reusable snippets.app.kubernetes.io/*):
app.kubernetes.io/name: {{ include "chart.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/component: webserver # role within the architecture
app.kubernetes.io/part-of: my-platform # higher-level application
app.kubernetes.io/managed-by: {{ .Release.Service }}
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
name, instance, and managed-by.selectorLabels helper — same labels in Deployment selector and Service selector.rbac.create: true and serviceAccount.create: true.readOnlyRootFilesystem: true, drop all capabilities.automountServiceAccountToken: false unless required.existingSecret pattern.helm-secrets (SOPS backend) to store encrypted values in Git. Supports Age, AWS KMS, GCP KMS, PGP:
helm secrets encrypt values-prod.yaml > values-prod.enc.yaml # encrypt
helm secrets upgrade myapp ./chart -f values-prod.enc.yaml # deploy (auto-decrypts)
For Kubernetes-native secret sync, prefer External Secrets Operator (ESO): syncs secrets from Vault, AWS Secrets Manager, or GCP Secret Manager directly into Secret objects — no secrets in Git at all, even encrypted.latest or floating tags.image.repository and image.tag. Default pullPolicy: IfNotPresent.livenessProbe and readinessProbe.version: ~1.2.3.https:// repository URLs. OCI registries also supported (default since Helm 3.8):
dependencies:
- name: postgresql
version: "~15.5.0"
repository: "oci://registry-1.docker.io/bitnamicharts"
helm push mychart-0.1.0.tgz oci://ghcr.io/org/charts. No helm repo add needed.condition: somechart.enabled.helm dependency update after Chart.yaml changes.crds/ directory (static YAML, not templated).Most production charts are deployed via ArgoCD or Flux, not manual helm install. Design charts with GitOps in mind.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
source:
repoURL: https://github.com/org/charts
chart: my-app
targetRevision: 1.2.0
helm:
valueFiles:
- values-prod.yaml
destination:
server: https://kubernetes.default.svc
namespace: my-app
syncPolicy:
automated:
prune: true
selfHeal: true
HelmRelease with remediation.retries and rollback on failure.See patterns/gitops-integration.md for Flux HelmRelease, multi-environment structure, and automated image updates.
- [ ] Scaffold chart structure (see patterns/chart-scaffolding.md)
- [ ] Configure Chart.yaml metadata
- [ ] Design values.yaml with sensible defaults
- [ ] Implement templates with standard labels
- [ ] Add security contexts and RBAC
- [ ] Write helm-unittest tests
- [ ] Run validation loop (below)
helm lint --strict charts/* — fix warnings and errors (includes schema validation if values.schema.json exists)helm template charts/* --validate — fix rendering issueshelm-unittest — fix failing testscheckov or kube-scorect lint (chart-testing) for CI-level validationhelm template mychart/ --values values.yaml — verify output without a cluster.helm-unittest for assertion-based template tests. Place in templates/tests/:
# templates/tests/deployment_test.yaml
suite: deployment
tests:
- it: should set replicas from values
set:
replicaCount: 3
asserts:
- equal:
path: spec.replicas
value: 3
- it: should use the correct image
asserts:
- matchRegex:
path: spec.template.spec.containers[0].image
pattern: ^my-app:.*
ct lint (chart-testing) combines lint + install in a kind cluster. Use in CI pipelines.kube-score or checkov on rendered templates.Hooks execute at specific release lifecycle points. Annotate resources (never use labels):
| Hook | Runs | Use case |
|---|---|---|
pre-install | Before first install | DB migration, pre-flight checks |
post-install | After first install | Seed data, notifications |
pre-upgrade | Before upgrade | DB migration, backup |
post-upgrade | After upgrade | Cache warm-up, smoke test |
pre-delete | Before delete | Backup, cleanup external resources |
pre-rollback | Before rollback | Snapshot current state |
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "mychart.fullname" . }}-migrate
annotations:
"helm.sh/hook": pre-upgrade,pre-install
"helm.sh/hook-weight": "-5"
"helm.sh/hook-delete-policy": before-hook-creation
"-5", "0", "10").before-hook-creation (delete previous hook resource before creating new), hook-succeeded (delete after success), hook-failed (delete after failure).helm package --sign.Full chart template: See patterns/chart-scaffolding.md for a production-ready scaffold Values design: See patterns/values-design.md for grouping, type coercion, overrides Security hardening: See patterns/security-hardening.md for SecurityContext, RBAC, NetworkPolicy, secrets GitOps integration: See patterns/gitops-integration.md for ArgoCD, Flux, multi-environment values, automated image updates Anti-patterns: See anti-patterns.md for common mistakes with corrected versions
app.kubernetes.io/* label specificationnpx claudepluginhub chogos/claude-skills --plugin chogosProvides quick reference for Helm chart structure, Chart.yaml config, Go templating, values patterns, commands, dependencies, testing, and security best practices. Activates on Chart.yaml, values.yaml, templates/.
Creates, tests, validates, and packages Helm charts for Kubernetes using helm create, lint, template, package commands on Chart.yaml, values.yaml, templates, and dependencies.
Validates and audits Helm charts with linting, template rendering, YAML/schema checks, CRD verification, dry-runs, and security best practices.