Recently I had to create a Helm-Chart (still not a fan of it, at all!) where the image was different depending on if the helm-chart was used for local development or used in production.

I had to resort to using an if-else-condition that I put into the _helpers.tpl-file so it can be accessed by any deployment-template in the chart.

{{- /*
Set registry to local docker-registy if deploying locally, else use prodution-registry.
If you use := in if-statement, it will declare a new local variable $env which will not impact the value of $env declared outside the if block.
*/}}

{{- define "ImageFunctions" -}}
{{- $Image := "" }}

{{- if (default .root.Values.LOCAL_DEV false) -}}
    {{- $Image = printf "%s:latest" $name | quote -}}
{{- else -}}
    {{- $Image = printf "%s/%s/%s:latest" "image-registry.openshift-image-registry.svc:5000" .root.Release.Namespace $name | quote -}}
{{- end -}}

{{- $Image -}}
{{- end }}

Let’s break it down:

First I define a function called “ImageFunctions” that will be then called in the deployment-templates. This functions first defines an empty Image-variable. This is needed, because if you define the variable only inside the following if-statement, it won’t be accessible outside the statement and we then cannot use it in our deployments.

Then comes the if-else condition. Here I use a Value LOCAL_DEV that is defined in a values-file that will only be used when developing locally. Otherwise it is empty and defaults to false. This way I only have to define this variable once for local development and not have to define it in the values-files for the production environment.

Inside the if function I set the Image-variable to “%s:latest” using a printf-statement. When templating this, it will resolve to for example “frontend-app:latest”. The else-condition does the same, except it prints a different image-name that can be used in production.

The line {{- $Image -}} then propagates the variable to outside the ImageFunctions-functions so it then can be used in the template.

Here’s how to use it in your deployment-template:

{{- $Image := include "ImageFunctions" $dict -}}
---
apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      containers:
        - name: container
          image: {{ $Image }}

Let’s break this down, too:

The first line defines a new variable Image that used the defined ImageFunctions. It will be filled the the Image-variable coming from the function and will contain either frontend-app:latest or image-registry.openshift-image-registry.svc:5000:/frotend-app:latest, depending on if LOCAL_DEV was set to true or false.

Now you can just insert the first line into every of your deployment-templates and then use the $Image-variable. Then the correct image will be used, no matter if you use the chart locally or in production.