Documentation/Buki/Helm/ skills /helm-values

📖 helm-values

Use when managing Helm values files and configuration overrides for customizing Kubernetes deployments.



Overview

Managing values files and configuration overrides in Helm.

Values Hierarchy

Helm merges values from multiple sources (lower precedence first):

  1. Built-in default values
  2. Chart's values.yaml
  3. Parent chart's values
  4. Values files specified with -f (can be multiple)
  5. Individual parameters with --set

values.yaml Structure

Organize by Resource

# Global settings
global:
  environment: production
  domain: example.com

# Application settings
app:
  name: myapp
  version: "1.0.0"

# Image settings
image:
  repository: myregistry/myapp
  pullPolicy: IfNotPresent
  tag: ""  # Overrides appVersion

# Service settings
service:
  type: ClusterIP
  port: 80
  targetPort: 8080

# Ingress settings
ingress:
  enabled: false
  className: nginx
  annotations: {}
  hosts:
    - host: myapp.example.com
      paths:
        - path: /
          pathType: Prefix
  tls: []

# Resources
resources:
  limits:
    cpu: 500m
    memory: 512Mi
  requests:
    cpu: 250m
    memory: 256Mi

# Persistence
persistence:
  enabled: false
  storageClass: ""
  accessMode: ReadWriteOnce
  size: 8Gi

Override Strategies

Override with File

# Single file
helm install myrelease ./mychart -f custom-values.yaml

# Multiple files (later files override earlier)
helm install myrelease ./mychart \
  -f values-base.yaml \
  -f values-production.yaml

Override with --set

# Single value
helm install myrelease ./mychart --set image.tag=2.0.0

# Multiple values
helm install myrelease ./mychart \
  --set image.tag=2.0.0 \
  --set replicaCount=5

# Nested values
helm install myrelease ./mychart \
  --set ingress.enabled=true \
  --set ingress.hosts[0].host=myapp.com

Override with --set-string

# Force string type (useful for numeric-looking strings)
helm install myrelease ./mychart \
  --set-string version="1.0"

Override with --set-file

# Read value from file
helm install myrelease ./mychart \
  --set-file config=./config.json

Environment-Specific Values

values-development.yaml

replicaCount: 1

image:
  tag: "dev-latest"
  pullPolicy: Always

resources:
  limits:
    cpu: 200m
    memory: 256Mi

ingress:
  enabled: true
  hosts:
    - host: dev.myapp.com

postgresql:
  enabled: true

values-production.yaml

replicaCount: 5

image:
  tag: "1.0.0"
  pullPolicy: IfNotPresent

resources:
  limits:
    cpu: 1000m
    memory: 1Gi

ingress:
  enabled: true
  hosts:
    - host: myapp.com
  tls:
    - secretName: myapp-tls
      hosts:
        - myapp.com

postgresql:
  enabled: false
  external:
    host: prod-db.example.com

Global Values

Parent Chart values.yaml

global:
  environment: production
  storageClass: fast-ssd

  postgresql:
    auth:
      existingSecret: db-credentials

Subchart Access

# In subchart template
environment: {{ .Values.global.environment }}

Schema Validation

values.schema.json

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": ["image"],
  "properties": {
    "replicaCount": {
      "type": "integer",
      "minimum": 1,
      "maximum": 10
    },
    "image": {
      "type": "object",
      "required": ["repository"],
      "properties": {
        "repository": {
          "type": "string"
        },
        "tag": {
          "type": "string"
        },
        "pullPolicy": {
          "type": "string",
          "enum": ["Always", "IfNotPresent", "Never"]
        }
      }
    },
    "service": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "enum": ["ClusterIP", "NodePort", "LoadBalancer"]
        },
        "port": {
          "type": "integer",
          "minimum": 1,
          "maximum": 65535
        }
      }
    }
  }
}

Secrets in Values

Don't Commit Secrets

# values.yaml - public defaults
database:
  host: ""
  username: ""
  password: ""

# values-secrets.yaml - not in git
database:
  host: "prod-db.example.com"
  username: "dbuser"
  password: "super-secret"

Use External Secrets

# values.yaml
database:
  useExistingSecret: true
  existingSecretName: db-credentials
# In template
{{- if .Values.database.useExistingSecret }}
secretKeyRef:
  name: {{ .Values.database.existingSecretName }}
  key: password
{{- else }}
value: {{ .Values.database.password | quote }}
{{- end }}

Complex Value Structures

Lists

# values.yaml
extraEnvVars:
  - name: LOG_LEVEL
    value: info
  - name: API_KEY
    valueFrom:
      secretKeyRef:
        name: api-secret
        key: key
# template
{{- range .Values.extraEnvVars }}
- name: {{ .name }}
  {{- if .value }}
  value: {{ .value | quote }}
  {{- else if .valueFrom }}
  valueFrom:
    {{- toYaml .valueFrom | nindent 4 }}
  {{- end }}
{{- end }}

Maps

# values.yaml
annotations:
  prometheus.io/scrape: "true"
  prometheus.io/port: "9090"

labels:
  team: platform
  environment: production
# template
annotations:
  {{- range $key, $value := .Values.annotations }}
  {{ $key }}: {{ $value | quote }}
  {{- end }}

Best Practices

Document Values

# values.yaml with comments
## Number of replicas
## @param replicaCount - Number of pod replicas
replicaCount: 3

## Image configuration
## @param image.repository - Docker image repository
## @param image.tag - Docker image tag (defaults to Chart appVersion)
image:
  repository: myapp
  tag: ""

Sensible Defaults

# Provide production-ready defaults
replicaCount: 3  # Not 1

resources:
  limits:
    cpu: 500m
    memory: 512Mi
  requests:
    cpu: 500m  # Same as limit for guaranteed QoS
    memory: 512Mi

Feature Flags

# Allow enabling/disabling features
features:
  metrics:
    enabled: true
    port: 9090

  tracing:
    enabled: false
    endpoint: ""

View Computed Values

# See final merged values
helm get values myrelease

# See all values (including defaults)
helm get values myrelease --all

# Template with values
helm template myrelease ./mychart -f custom-values.yaml