home / skills / thebushidocollective / han / helm-values

This skill helps you manage Helm values files and overrides across deployments, ensuring correct inheritance and environment-specific configurations.

npx playbooks add skill thebushidocollective/han --skill helm-values

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
6.3 KB
---
name: helm-values
user-invocable: false
description: Use when managing Helm values files and configuration overrides for customizing Kubernetes deployments.
allowed-tools: []
---

# Helm Values

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
```

Overview

This skill helps manage Helm values files and configuration overrides to customize Kubernetes deployments. It explains values hierarchy, structuring values.yaml, override methods (--set, -f, --set-file), environment-specific files, schema validation, and secure handling of secrets. Use it to create consistent, validated, and environment-aware Helm configurations.

How this skill works

The skill inspects common Helm patterns and recommends how to structure values.yaml, split environment-specific files, and apply overrides with correct precedence. It describes use of --set, --set-string, --set-file, and multiple -f files, plus JSON schema validation and techniques for avoiding committed secrets. It also shows templates for lists, maps, and global values for subchart access.

When to use it

  • When you need consistent configuration across environments (dev/stage/prod)
  • When you must override chart defaults with multiple files or CLI flags
  • When validating values with values.schema.json before deploys
  • When separating secrets from source control or using external secrets
  • When organizing complex lists, maps, and global settings for subcharts

Best practices

  • Organize values.yaml by resource areas (global, app, image, service, ingress, resources, persistence)
  • Use multiple -f files for environment-specific overrides; later files take precedence
  • Prefer values.schema.json to validate types and required fields before install/upgrade
  • Never commit secrets; keep secrets in a separate, ignored file or use existing Kubernetes secrets
  • Document parameters in values.yaml with comments and sensible defaults for production

Example use cases

  • Deploying the same chart to dev and prod using values-development.yaml and values-production.yaml
  • Overriding a single deployment with --set image.tag=2.0.0 during CI/CD pipeline runs
  • Providing large config blobs with --set-file to inject JSON/YAML into Helm values
  • Using global values in a parent chart so subcharts inherit environment or storage settings
  • Validating user-supplied values with values.schema.json to fail fast on bad types

FAQ

What is the precedence order for Helm values?

Helm merges values from lowest to highest precedence: chart defaults, chart values.yaml, parent chart values, -f files (in order), then --set/--set-string/--set-file CLI flags.

How do I avoid committing secrets in values files?

Keep secrets in a separate values-secrets.yaml that is not tracked in Git, or reference existing Kubernetes secrets and set flags to use them; prefer ExternalSecrets or secretKeyRef in templates.