helm generic chart to use as multiple deployments for different installations

6/24/2021

Lets say I have a Helm chart "ManagementModule", and it has few env variables like as follows.

env1:[value1, value2, value3]

env2: "fixValue"

env3: "dynamic"

Now, my requirement is as follows: 1. if the target is Customer X environment, create just one deployment with 3 replica may be with name management-module. this requirement is straightforward but it should work with below case as well

  1. If the target is Customer Y environment, create 3 different deployments with 2 replica each with below env variable.

-- deployment-name: management-module-1

   env1:[value1]

   env2: "fixValue"

   env3: "dynamic1"

-- deployment-name: management-module-2

   env1:[value2]

   env2: "fixValue"

   env3: "dynamic2"

-- deployment-name: management-module-3

   env1:[value3]

   env2: "fixValue"

   env3: "dynamic2"

Second case just wants to have different deployments working on their set of environment values and independent of each other. The chart should support both ways deployments

Can I achieve it through templates/charts? Any suggestions, how we can achieve these 2 set of deployments with single chart?

-- sakura
kubernetes
kubernetes-helm
openshift

1 Answer

7/1/2021

Answer based on this. hence the CW.

You can use _*.tpl files to define generic templates, They are located in ./templates/_*.tpl (. being the directory with global Chart.yaml and values.yaml). Also by defaul in helm global values override local values. Solution to this can be found here.

By using these 2 techniques in conjunction you can make generic templates and only use values.yaml to render what you want to render.

For example:

# values.yaml
global:
  defaults:
    switches:
      volumesEnabled: false
      ingressEnabled: false
    ingress:
      host: "generic-host.com"
    volumes:
      volumeName: "generic-volume-name"

subchart1:
  defaultOverrides:
    switches:
      volumesEnabled: true
  volumes:
    volumeName: "not-so-generic-name"

subchart2:
  defaultOverrides:
    switches:
      volumesEnabled: true
      ingressEnabled: true

Then templates (java is just for grouping templates in one category, you can try to guess in which language my backend microservices are written :) )

# ./templates/java/_deployment.tpl

{{- define "templates.java.deployment" }}
{{- $properties := merge .Values.defaultOverrides $.Values.global.defaults -}}
{{*/ generic deployment structure */}}
{{- if $properties.switches.volumesEnabled -}}
volume: {{ $properties.volumes.volumeName }}
{{- end }}
{{*/ generic deployment structure */}}
{{- end }}
# ./templates/java/_ingress.tpl

{{- define "templates.java.ingress" }}
{{- $properties := merge .Values.defaultOverrides $.Values.global.defaults -}}
{{- if $properties.switches.ingressEnabled -}}
host: {{ $properties.ingress.host }}
{{*/ generic ingress structure */}}
{{- end }}
{{- end }}

And then subchart templates

# ./charts/subchart1/templates/deployment.yaml

{{ include "templates.java.deployment" . }}
./charts/subchart1/templates/ingress.yaml:

{{ include "templates.java.ingress" . }}
subchart2 has exactly the same includes.

In the end we will have:

  • subchart1:
    • has deployment
    • volumeName is overriden from local values with "not-so-generic-name"
    • ingress is not rendered at all
  • subchart2:
    • has deployment
    • volumeName is default from global values
    • ingress host is default from global values

But I would say that it's a bad practice to generlize to much, because it will make your templates overly complex. In my case I found 2 distinct groups which have nearly identical manifests within them (basically frontend and backend) and made a set of _*.tpl files for each of them and settings default values for each group respectivelly in global values.yaml.

-- p10l
Source: StackOverflow