Kubernetes
Helm
Secrets Management
DevOps
Cloud Computing

How to reference kubernetes secrets in helm chart?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In a Helm chart, you usually do not read secret values directly during template rendering. Instead, you reference the name of an existing Kubernetes Secret from the resources your chart creates, such as a Deployment, StatefulSet, or Job. The two most common patterns are exposing secret keys as environment variables or mounting the secret as a volume.

Reference A Secret As Environment Variables

A typical deployment template injects specific secret keys into container environment variables.

yaml
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4  name: {{ include "myapp.fullname" . }}
5spec:
6  template:
7    spec:
8      containers:
9        - name: app
10          image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
11          env:
12            - name: DB_USER
13              valueFrom:
14                secretKeyRef:
15                  name: {{ .Values.existingSecret.name }}
16                  key: username
17            - name: DB_PASSWORD
18              valueFrom:
19                secretKeyRef:
20                  name: {{ .Values.existingSecret.name }}
21                  key: password

And in values.yaml:

yaml
existingSecret:
  name: my-database-secret

This pattern is simple and works well when the application already expects configuration through environment variables.

Mount A Secret As A Volume

If the application needs certificate files, key files, or structured secret data, mounting the secret as a volume is often cleaner.

yaml
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4  name: {{ include "myapp.fullname" . }}
5spec:
6  template:
7    spec:
8      containers:
9        - name: app
10          image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
11          volumeMounts:
12            - name: app-secret
13              mountPath: /etc/app-secret
14              readOnly: true
15      volumes:
16        - name: app-secret
17          secret:
18            secretName: {{ .Values.existingSecret.name }}

This makes the secret available as files inside the container.

Creating The Secret In The Chart

Sometimes the chart itself is responsible for creating the secret. In that case, you template the Secret resource and then reference its name from the workload.

yaml
1apiVersion: v1
2kind: Secret
3metadata:
4  name: {{ include "myapp.fullname" . }}-secret
5type: Opaque
6stringData:
7  username: {{ .Values.secret.username | quote }}
8  password: {{ .Values.secret.password | quote }}

Then the deployment can reference {{ include "myapp.fullname" . }}-secret.

This works, but be careful: putting raw secrets in values.yaml or Helm release history has operational and security implications. Many teams prefer referencing a pre-created secret instead.

Know The Difference Between Referencing And Looking Up

Helm templates can reference a secret name very easily because that is just string substitution. Actually looking up secret data from the cluster at render time is different and is not the normal pattern for application configuration.

If you truly need to inspect an existing cluster secret during rendering, Helm has a lookup function in newer versions, but that creates tighter coupling to cluster state and is often harder to reason about than explicitly passing the secret name.

For most charts, the clean rule is:

  • Helm renders the resource templates
  • Kubernetes injects the secret into the pod at runtime

Common Pitfalls

The most common mistake is confusing Helm values with Kubernetes secrets. A value such as .Values.password is just template input, not a cluster secret by itself.

Another issue is hard-coding secret names in templates instead of making them configurable through values. That makes the chart harder to reuse across environments.

It is also easy to expose sensitive data accidentally by storing secret contents in plain values.yaml files committed to source control.

Finally, remember that secret key names must match the actual keys stored in the Kubernetes Secret. A correct secret name with the wrong key still breaks the pod.

Summary

  • In Helm, you usually reference a Kubernetes secret by name from a workload template.
  • Use secretKeyRef for environment variables and secret volumes for file-based access.
  • Make the secret name configurable through chart values.
  • Creating secrets inside the chart is possible, but storing secret values in Helm inputs has tradeoffs.
  • Keep Helm rendering and Kubernetes secret injection conceptually separate.

Course illustration
Course illustration

All Rights Reserved.