Skip to content
Published on

Helm Chart Design Best Practices: Naming, Values Design, GitOps Integration

Authors

1. Naming Conventions

1.1 Standard Labels

{{- define "my-chart.labels" -}}
app.kubernetes.io/name: {{ include "my-chart.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/component: "backend"
app.kubernetes.io/part-of: "my-platform"
app.kubernetes.io/managed-by: {{ .Release.Service }}
helm.sh/chart: {{ include "my-chart.chart" . }}
{{- end }}

2. Values Design

image:
  repository: nginx
  tag: '1.25'
  pullPolicy: IfNotPresent

2.2 Defaults Strategy

replicaCount: 1
resources:
  limits:
    cpu: 500m
    memory: 512Mi
  requests:
    cpu: 100m
    memory: 128Mi
autoscaling:
  enabled: false
  minReplicas: 1
  maxReplicas: 10
ingress:
  enabled: false
podAnnotations: {}
nodeSelector: {}
tolerations: []
affinity: {}
extraEnvVars: []

3. Multi-Environment Management

3.1 Values File Layering

helm upgrade --install my-app ./my-chart \
  -f values-common.yaml \
  -f values-production.yaml \
  --set image.tag=v2.1.0

4. Subcharts and Umbrella Charts

4.1 Umbrella Chart

# Chart.yaml
dependencies:
  - name: frontend
    version: '2.x.x'
    repository: 'file://charts/frontend'
  - name: backend-api
    version: '3.x.x'
    repository: 'file://charts/backend-api'
  - name: redis
    version: '17.x.x'
    repository: 'https://charts.bitnami.com/bitnami'
    condition: redis.enabled

5. GitOps Integration

5.1 ArgoCD + Helm

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
spec:
  source:
    repoURL: https://github.com/myorg/helm-charts
    targetRevision: main
    path: charts/my-app
    helm:
      releaseName: my-app
      valueFiles:
        - values.yaml
        - values-production.yaml
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

5.2 Flux + HelmRelease

apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: my-app
  namespace: production
spec:
  interval: 10m
  chart:
    spec:
      chart: my-app
      version: '>=1.0.0'
      sourceRef:
        kind: HelmRepository
        name: my-charts
  values:
    replicaCount: 3
    image:
      tag: v2.1.0
  upgrade:
    remediation:
      retries: 3

6. Security Best Practices

6.1 Immutable Tags

image:
  tag: 'v2.1.0' # Never use "latest"

6.2 External Secret Management

Use helm-secrets, External Secrets Operator, or Sealed Secrets instead of plaintext secrets in values.

6.3 SecurityContext Defaults

podSecurityContext:
  runAsNonRoot: true
  runAsUser: 1000
  seccompProfile:
    type: RuntimeDefault
containerSecurityContext:
  allowPrivilegeEscalation: false
  readOnlyRootFilesystem: true
  capabilities:
    drop: ['ALL']

7. Summary

  1. Naming and labels: Follow Kubernetes official label standards, 63-char limit
  2. Values design: Nested structure, sensible defaults, extension points
  3. Multi-environment: Values file layering for environment-specific config
  4. Subcharts/umbrella: Balance component independence with deployment convenience
  5. GitOps integration: Declarative deployment via ArgoCD Application or Flux HelmRelease
  6. Security: Immutable tags, external secret management, default SecurityContext
  7. Maintenance: SemVer, CHANGELOG, deprecation strategy