Sayon Roy Choudhury
Sayon Roy Choudhury

Reputation: 167

Helm create secret from env file

Kubectl provides a nice way to convert environment variable files into secrets using:

$ kubectl create secret generic my-env-list --from-env-file=envfile

Is there any way to achieve this in Helm? I tried the below snippet but the result was quite different:

kind: Secret
metadata:
  name: my-env-list
data:
  {{ .Files.Get "envfile" | b64enc }}

Upvotes: 5

Views: 5557

Answers (2)

Frank Escobar
Frank Escobar

Reputation: 696

I would like to use env files but it seems to be helm doesn't support that yet. Instead of using an env file you could use a yaml file.

I mean to convert from this env file

#envfile

MYENV1=VALUE1
MYENV2=VALUE2

to this yaml file (verify the yaml format, always it should be an empty space after the colon)

#envfile.yaml

MYENV1: VALUE1
MYENV2: VALUE2

After this, you should move the envfile.yaml generated in the root folder of your helm chart (same level of values yaml files)

You have to set up your secret.yaml in this way:

apiVersion: v1
kind: Secret
metadata:
  name: my-secret
  annotations:
    checksum/config: {{ (tpl (.Files.Glob "envfile.yaml").AsSecrets . ) | sha256sum }}
type: Opaque
data:
{{- $v := $.Files.Get "envfile.yaml" | fromYaml }}
{{- range $key, $val := $v }}
{{ $key | indent 2 }}: {{ $val | b64enc }}
{{- end}}

We are iterating in the data property the envfile.yaml generated and encoding the value to base64. The result secret will be the next:

kubectl get secret my-secret -o yaml


apiVersion: v1
data:
  MYENV1: VkFMVUUx
  MYENV2: VkFMVUUy
kind: Secret
metadata:
  annotations:
    checksum/config: 8365925e9f9cf07b2a2b7f2ad8525ff79837d67eb0d41bb64c410a382bc3fcbc
  creationTimestamp: "2022-07-09T10:25:16Z"
  labels:
    app.kubernetes.io/managed-by: Helm
  name: my-secret
  resourceVersion: "645673"
  uid: fc2b3722-e5ef-435e-85e0-57c63725bd8b
type: Opaque

Also, I'm using checksum/config annotation to update the secret object every time a value is updated.

Upvotes: 2

mdaniel
mdaniel

Reputation: 33231

It appears kubectl just does the simple thing and only splits on a single = character so the Helm way would be to replicate that behavior (helm has regexSplit which will suffice for our purposes):

apiVersion: v1
kind: Secret
data:
  {{ range .Files.Lines "envfile" }}
  {{   if . }}
  {{     $parts := regexSplit "=" . 2 }}
  {{     index $parts 0  }}: {{ index $parts 1 | b64enc }}
  {{   end }}
  {{ end }}

that {{ if . }} is because .Files.Lines returned an empty string which of course doesn't comply with the pattern

Be aware that kubectl's version accepts barewords looked up from the environment which helm has no support for doing, so if your envfile is formatted like that, this specific implementation will fail

Upvotes: 5

Related Questions