---
title: "Helm: Create a Secret Only If It Does Not Exist (lookup)"
source: "https://support.tools/reusing-kubernetes-secrets-helm-templates/"
published: 2024-10-07
categories: ["Kubernetes","Helm","Security"]
tags: ["Helm","Kubernetes","Secrets","DevOps"]
---


Kubernetes Secrets are an essential part of securing sensitive information such as passwords, API keys, and certificates. When using Helm to manage your Kubernetes deployments, there are often cases where you need to reuse existing Secrets rather than creating new ones. This is a common requirement in scenarios where Secrets are managed externally or shared across multiple applications.

In this post, we will explore how to reuse existing Kubernetes Secrets within your Helm templates, ensuring efficient management and security for your workloads.

## Quick answer

Use Helm's `lookup` function to read the Secret from the cluster. If it exists, reuse its value; if not, generate one. This keeps a generated password stable across `helm upgrade`:

```yaml
{{- $existing := lookup "v1" "Secret" .Release.Namespace "my-secret" }}
apiVersion: v1
kind: Secret
metadata:
  name: my-secret
type: Opaque
data:
  {{- if $existing }}
  password: {{ index $existing.data "password" }}
  {{- else }}
  password: {{ randAlphaNum 24 | b64enc }}
  {{- end }}
```

To skip rendering the Secret entirely when it already exists, wrap the manifest in `{{- if not $existing }}` ... `{{- end }}` and add the `helm.sh/resource-policy: keep` annotation, so a later upgrade that no longer renders it does not delete it (Helm stops managing a kept resource).

`lookup` returns an empty value under `helm template` and client-side `--dry-run`, because Helm does not contact the API server in those modes, so the "not found" branch renders there. Use `helm install|upgrade --dry-run=server` to test against the real cluster. Pods then consume the Secret with `valueFrom.secretKeyRef`, shown below.

### Why Reuse Existing Secrets?

In Kubernetes, Secrets allow you to store and manage sensitive information securely. However, in complex environments with multiple applications, you might have scenarios where Secrets are already created (e.g., by another team or tool like Vault). Reusing these Secrets in Helm charts has several benefits:

- **Avoid Duplication**: There’s no need to recreate Secrets that already exist.
- **Consistency**: Ensures that sensitive data such as API tokens or certificates are consistent across multiple applications.
- **Security**: Reduces the risk of misconfiguration and exposure by relying on pre-existing, securely managed Secrets.

### Accessing Existing Secrets in Helm

To reference an existing Secret in a Helm chart, you need to ensure that the deployment resource is configured to mount or use the Secret without recreating it. This can be done using the `tpl` function or conditionally creating Secrets in the chart’s templates.

#### Example: Referencing an Existing Secret in a Pod

Let’s consider a scenario where a **Secret** named `my-secret` already exists, and we want to reuse it in our Helm template. The Secret contains a database password that will be injected into the environment of a container.

Here’s an example of how to reference that Secret in a **Deployment** template:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: my-app-image
        env:
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: my-secret
              key: db-password
```

In this example, we are not creating a new Secret but referencing the existing `my-secret` Kubernetes Secret, where the key `db-password` contains the database password.

#### Using `tpl` to Dynamically Reference Secrets

If the Secret name or key is dynamic and passed as a value, you can use Helm’s `tpl` function to insert those values into the template dynamically.

In your `values.yaml`:

```yaml
existingSecretName: my-secret
existingSecretKey: db-password
```

In the Helm template:

```yaml
env:
- name: DB_PASSWORD
  valueFrom:
    secretKeyRef:
      name: {{ tpl .Values.existingSecretName . }}
      key: {{ tpl .Values.existingSecretKey . }}
```

The `tpl` function allows you to evaluate the values as templates, giving you the flexibility to dynamically inject them during deployment.

### Conditionally Create a Secret if It Doesn't Exist

In some cases, you may want to conditionally create a Secret in your Helm chart if it doesn’t already exist. You can use Helm’s templating features to check if a Secret is provided and only create a new one if necessary.

Here’s an example of conditionally creating a Secret based on the existence of a value:

In `values.yaml`:

```yaml
secret:
  create: false
  name: my-secret
  data:
    username: admin
    password: adminpassword
```

In the Helm template:

```yaml
{{- if .Values.secret.create -}}
apiVersion: v1
kind: Secret
metadata:
  name: {{ .Values.secret.name }}
type: Opaque
data:
  username: {{ .Values.secret.data.username | b64enc }}
  password: {{ .Values.secret.data.password | b64enc }}
{{- end }}
```

In this example, the Secret is only created if `secret.create` is set to `true`. Otherwise, the existing Secret is used. This flag does not check the cluster; to create the Secret only when it is actually missing, use the `lookup` pattern from the Quick answer.

### Best Practices for Reusing Secrets

- **Consistent Naming**: Use consistent and clear names for Secrets across your applications to avoid confusion.
- **Secure Access**: Ensure that only the necessary applications and namespaces have access to Secrets by using RBAC and proper namespace scoping.
- **Version Control**: Avoid hardcoding sensitive data directly in Helm charts or values files. Use external tools like Vault or AWS Secrets Manager to manage secrets securely.
- **Template Validation**: Always validate that the referenced Secrets exist before deployment to avoid failures.

### Conclusion

Reusing existing Kubernetes Secrets in Helm templates allows you to manage sensitive data efficiently, reduce duplication, and maintain consistency across applications. By leveraging Helm’s templating features, you can dynamically reference existing Secrets or conditionally create them if needed.

This approach ensures that your Kubernetes deployments remain secure, scalable, and easy to maintain without sacrificing flexibility or increasing risk. Whether you’re managing multi-environment applications or simply reducing resource overhead, reusing Secrets is a valuable technique in any Kubernetes environment.

