Tians
Tians

Reputation: 483

How to reference kubernetes secrets in helm chart?

I want to make some deployments in kubernetes using helm charts. Here is a sample override-values yaml that I use:

imageRepository: ""

ocbb:
    imagePullPolicy: IfNotPresent
    TZ: UTC
    logDir: /oms_logs
    tnsAdmin: /oms/ora_k8
    LOG_LEVEL: 3
    wallet:
        client: 
        server: 
        root:
    db:
        deployment:
            imageName: init_db
            imageTag:
        host: 192.168.88.80
        port:
        service:
        alias:
        schemauser: pincloud
        schemapass:
        schematablespace: pincloud
        indextablespace: pincloudx
        nls_lang: AMERICAN_AMERICA.AL32UTF8
        charset: AL32UTF8
        pipelineschemauser: ifwcloud
        pipelineschemapass:
        pipelineschematablespace: ifwcloud
        pipelineindextablespace: ifwcloudx
        pipelinealias:
        queuename:

In this file I have to set some values involving credentials, for example schemapass, pipelineschemapass... Documentation states I have to generate kubernetes secrets to do this and add this key to my yaml file with the same path hierarchy.

I generated some kubernetes secrets, for example:

kubectl create secret generic schemapass --from-literal=password='pincloud'

Now I don't know how to reference this newly generated secret in my yaml file. Any tip about how to set schemapass field in yaml chart to reference kubernetes secret?

Upvotes: 24

Views: 129883

Answers (4)

waldenlaker
waldenlaker

Reputation: 181

I had some similar requirement like this as well. You don't need to refer to the existing secret, you could use Kyverno to sync a new secret and use it in another chart. You could even massage the secret data to whatever format you want. Luckily, in my situation, we already have Kyverno in our platform, so it is just easy to add a new policy.

But definitely checkout Kyverno if it is an option for you.

https://kyverno.io/

Upvotes: 0

Darren Bishop
Darren Bishop

Reputation: 2585

There is actually a lookup function, but it's fraught with controversy and can be tricky to debug

lookup apiVersion, kind, namespace, name -> resource or resource list

I have only managed to get it to work referencing secrets from the same chart (pointless); I ideally want to get at a value in a secret that I deploy through other means prior.

The application consumes a config file (it is what it is), which I am trying to curate on the fly via a helm template, have the entire file stored in the chart's secret, and volume-mount that within a deployment template.

I may well open a SO-post


UPDATE 2023/07/02: I have since discovered External Secrets Operator (ESO)

What ESO Does For You

ESO nicely separates the concerns of input secrets and output secrets.

Input Secrets:

With its pluggable design you can source Secrets (and ConfigMaps) from Kubernetes (essentially internal secrets) or sensitive -data from AWS (e.g. Secrets Manager, Parameter Store) and other cloud providers (external secrets).

Output Secrets:

Based on input secrets you can either:

  • Map them one-to-one into a Secret
  • Map them many-to-one, using templating to generate a Secret e.g. containing a config file, where it safely inlines DB credentials
How You Can Use ESO

So with ESO, your Helm Chart's values.yaml is free to support a UX for those familiar with using Helm.

Pro-Tip: Don't leak your application's configuration structure in to your values.yaml, thus tightly coupling the two; make use of the 'facade' opportunity the latter presents you.

You can now define whatever notation you want, in your values.yaml, to indicate/reference a secret that should be used (and from where).

Idea: A possible reference format could be:
secret://external-secret-store/external/secret/path/or/name#key-within-external-secret
This adopts a familiar URI-style, which predates Kubernetes/Helm, therefore should be fairly intuitive to your users out-of-the-box

Your templates/*.yaml can then interpret those references to generate:

  1. ExternalSecrets, which in-turn inject and supervise Secrets, and
  2. Deployments, for example, that reference those injected Secrets as volumes or environment-variables.
Example: A concrete application of this approach using the OP's (abbreviated) values.yaml:
imageRepository: ""

ocbb:
    ...
    db:
        ...
        schemauser: secret://my-parameter-store/ocbb/db/schema-credentials#username
        schemapass: secret://my-parameter-store/ocbb/db/schema-credentials#password

Insight: The values.yaml has a structure of your choosing and you know ocbb.db.schemapass, etc, are credentials and may reference secrets, so you template accordingly.

  • my-parameter-store: an ESO concept, setup to point to AWS Parameter Store
  • /ocbb/db/schema-credentials: an AWS concept, the path to the parameter in AWS Parameter Store
  • username,password: the keys in the JSON object i.e. the parameter in AWS Parameter Store

Upvotes: 6

Mostafa Wael
Mostafa Wael

Reputation: 3846

You can reference K8S values -whether secrets or not- in Helm by specifying them in your container as environment variables.

let your deployment be mongo.yml

--
kind: Deployment
   --
      --
      containers:
        --
        env:
        - name: DB_URL
          valueFrom:
            configMapKeyRef:
              name: mongo-config
              key: mongo-url
        - name: MONGO_INITDB_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mongo-secret
              key: mongo-password  

Where mongo-secret is

apiVersion: v1
kind: Secret
metadata:
  name: mongo-secret
type: Opaque
data:
  mongo-user: bW9uZ291c2Vy
  mongo-password: bW9uZ29wYXNzd29yZA==

and mongo-config is

apiVersion: v1
kind: ConfigMap
metadata:
  name: mongo-config
data:
  mongo-url: mongo-service

Upvotes: 6

Rafał Leszko
Rafał Leszko

Reputation: 5541

You cannot use Kubernetes secret in your values.yaml. In values.yaml you only specify the input parameters for the Helm Chart, so it could be the secret name, but not the secret itself (or anything that it resolved).

If you want to use the secret in your container, then you can insert it as an environment variable:

env:
- name: SECRET_VALUE_ENV
  valueFrom:
    secretKeyRef:
      name: schemapass
      key: password

You can check more in the Hazelcast Enterprise Helm Chart. We do exactly that. You specify the secret name in values.yaml and then the secret is injected into the container using environment variable.

Upvotes: 41

Related Questions