Documentation/Tools/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

yaml
# 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

bash
# 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

bash
# 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

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

Override with --set-file

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

Environment-Specific Values

values-development.yaml

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

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

yaml
global:
  environment: production
  storageClass: fast-ssd

  postgresql:
    auth:
      existingSecret: db-credentials

Subchart Access

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

Schema Validation

values.schema.json

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

yaml
# 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

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

Complex Value Structures

Lists

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

Maps

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

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

Best Practices

Document Values

yaml
# 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

yaml
# 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

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

  tracing:
    enabled: false
    endpoint: ""

View Computed Values

bash
# 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