0
votes

I am beginner in helm chart templating and I'm looking for best practise. I would like to create a helm chart template enough generics to use same chart for all team project (backend, front-end,..) On order to make it generics I can let developer to specify list of many cases in values.yml (volumes for deployment, network policy ingress egress etc...). And i could keep the kubernetes template deployment, service etc.. Enough generics to never mention any specific keys. So the developer could only modify values yml for add values for their application behavior.

The disadvantage is that the kubernetes generics template will not contain any logic about the application , and the generic template will be hard to maintain (because it will handle every possible case). The advantage is that the developer doesn't need to understand helm because they will not modify the kubernetes template.

So you have any experience about that?

1
I wouldn't recommend it. If your requirement is that service maintainers write at most minimal YAML, a Go-based Kubernetes operator will be easier to write and maintain, than building the same functionality only using the Helm template system. As you note the "generic template" eventually becomes as complex as the YAML, at which point it's easier to write (and Google) the standard YAML than the template inputs. - David Maze
The advantage to helm is also the release management for the chart version the upgrade, rollback.. However i think that is really complex to manipulate helm template yml when it become complex with use of range functions and others... With kubernetes go based operator, may i have a release management of the deployed applications? Maybe I can keep helm strategy and choose client developers to choose helm backend template or helm front-end template etc i have prepared to give coherent and quick start for helm app, they could complete kub template if they need. - julus

1 Answers

1
votes

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 - https://github.com/helm/helm/issues/5676

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.