Search code examples
kuberneteskubernetes-helmconfigmapkubernetes-statefulset

Helm and Kubernetes: Alternative to immutable ConfigMap with random value


I have a ConfigMap for a StatefulSet, within which I'm generating a uuid that, once generated, needs to stay the same across scale-ups/scale-downs, uninstalls, installs, etc. Pretty much the only time it should be regenerated is after an uninstall + all persistent storage being removed + the ConfigMap itself being removed as well, which would be rare.

The ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
  name: id-store
  annotations:
    helm.sh/resource-policy: keep
  labels:
    {{ .... }}
data:
  uuid: "{{ randAlphaNum 22 }}"
immutable: true

Now this seems to work, but seems like a bit of an anti-pattern. Helm gives an error:

Error: INSTALLATION FAILED: cannot patch "id-store" with kind ConfigMap: ConfigMap "id-store" is invalid: data: Forbidden: field is immutable when `immutable` is set

The deployment goes through and the ConfigMap functions as it should, with the value staying the same. But the combination of the resource-policy annotation and immutable: true might cause issues with helm install --replace (which we don't use currently), and that error message is unpleasant to have hanging around. We do use helm upgrade, and I'm not sure if this approach would be problematic for that command as well.

I can't be the first person to want a value to be generated once with Helm and not be re-rendered, so is there some more idiomatic way to accomplish this?


Solution

  • thanks to David Maze for the linked question in the comments, this config map ended up looking very similar to those. It only differs slightly because, in my case, the uuid is being used to set the Kafka cluster id - because the pods are in a StatefulSet, I need the config map to always persist unless explicitly deleted so that restarted or scaled up pods will use the same cluster id as is stored in existing PVCs. With this, the ConfigMap is only rendered if one doesn't already exist in the Kubernetes instance.

    {{- $deployed_map := lookup "v1" "ConfigMap" .Release.Namespace "id-store" }}
    {{- if or (not $deployed_map) (not $deployed_map.data) }}
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: id-store
      annotations:
        helm.sh/resource-policy: keep
      labels:
        {{- include "kafka.labels" . | nindent 4 }}
    data:
      uuid: "{{ randAlphaNum 22 }}"
    {{ end }}
    

    Without the immutable: true, the error message in my question disappears, and there seem to be no issues when running helm upgrade or helm install --replace as well.