1
votes

I am writing helm charts and it creates one deployment and one statefulset component.

Now I want to generate uuid and send the value to both k8s components.

I a using uuid function to generate the uuid. But need help how I can send this value to both components.

Here is my chart folder structure --

  • projectdir
    • chart1
      • templates
        • statefulset.yaml
    • chart2
      • templates
        • deployment.yaml
    • helperchart
      • templates
        • _helpers.tpl

I have to write the logic to generate the uuid in _helpers.tpl.

3
This question is very vague and doesn't contain any code or details. Please provide some more information so people can help you effectively.Derek

3 Answers

0
votes

Edit: It seems defining it in the _helpers.tpl does not work - thank you for pointing it out.

I have lookup it up a bit, and it seems currently the only way to achieve that is to put both of the manifests, separated by --- to the same file under the templates/. See the following example, where the UUID is defined in the first line and then used in the both Deployment and the StatefulSet:

{{- $mySharedUuid := uuidv4 -}}

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "uuid-test.fullname" . }}-1
  labels:
    {{- include "uuid-test.labels" . | nindent 4 }}
  annotations:
    my-uuid: {{ $mySharedUuid }}
spec:
...
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: {{ include "uuid-test.fullname" . }}-2
  labels:
    {{- include "uuid-test.labels" . | nindent 4 }}
  annotations:
    my-uuid: {{ $mySharedUuid }}
spec:
...

After templating, the output is:

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: uuid-test-app-1
  labels:
    helm.sh/chart: uuid-test-0.1.0
    app.kubernetes.io/name: uuid-test
    app.kubernetes.io/instance: uuid-test-app
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
  annotations:
    my-uuid: fe0346f5-a963-4ca1-ada0-af17405f3155
spec:
...
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: uuid-test-app-2
  labels:
    helm.sh/chart: uuid-test-0.1.0
    app.kubernetes.io/name: uuid-test
    app.kubernetes.io/instance: uuid-test-app
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
  annotations:
    my-uuid: fe0346f5-a963-4ca1-ada0-af17405f3155
spec:
...

See the same issue: https://github.com/helm/helm/issues/6456

Note that this approach will still cause the UUID to be regenerated when you do a helm upgrade. To circumvent that, you would need to use another workaround along with this one.

0
votes

As suggested in helm issue tracker https://github.com/helm/helm/issues/6456, we have to put both components in same file and looks like thats the only solution right now.

Its a surprise, Helm not supporting cache the value to share across charts/components. I wish Helm support this feature in future.

0
votes

You should explicitly pass the value in as a Helm value; don't try to generate it in the chart.

The other answers to this question highlight a couple of the issues you'll run into. @UtkuÖzdemir notes that every time you call the Helm uuidv4 function it will create a new random UUID, so you can only call that function once in the chart ever; and @srr further notes that there's no way to persist a generated value like this, so if you helm upgrade the chart the UUID value will be regenerated, which will cause all of the involved Kubernetes objects to be redeployed.

The Bitnami RabbitMQ chart has an interesting middle road here. One of its configuration options is an "Erlang cookie", also a random string that needs to be consistent across all replicas and upgrades. On an initial install it generates a random value if one isn't provided, and tells you how to retrieve it from a Secret; but if .Release.IsUpgrade then you must provide the value directly, and the error message explains how to get it from your existing deployment.

You may be able to get around the "only call uuidv4 once ever" problem by putting the value into a ConfigMap or Secret, and then referencing it from elsewhere. This works only if the only place you use the UUID value is in an environment variable, or something else that can have a value injected from a secret; it won't help if you need it in an annotation or label.

apiVersion: v1
kind: Secret
metadata:
  name: {{ template "chart.name" . }}
data:
  the-uuid: {{ .Values.theUuid | default uuidv4 | b64enc }}
  {{-/*    this is the only place uuidv4 ^^^^^^ is called at all */}}
env:
  - name: THE_UUID
    valueFrom:
      secretKeyRef:
        name: {{ template "chart.name" . }}
        key: the-uuid