My issue: Create 32 similar crons in a Kubernetes cluster

Last week, I found myself in front of a refactoring issue. I had a Kubernetes cluster managed with Helm and I had 32 crons to transform into CronJob resources and to create and deploy. All those crons are very similar as they are Symfony commands: they are all based on the app image which is launched with a specific command such as

bin/console my:first:cron

I did not want to write 32 Helm templates for two reasons:

it is hard to maintain. Let’s imagine I want to add a configMap that applies to all of them, I will need to do it 32 times without error or without forgetting one

it is really boring to write.

One Helm template to rule them all

Here is a way to do it with only one short file.

First write one cronjob.yaml using helm :

apiVersion: batch/v1beta1

kind: CronJob

metadata:

name: "my-first-cron"

labels: {{ include "kubernetes.labels" . | indent 4 }}

spec:

schedule: "*/10 * * * *"

successfulJobsHistoryLimit: 0

jobTemplate:

spec:

template:

spec:

restartPolicy: Never

containers:

- image: "{{ .Values.cronjob.repository }}:{{ .Values.image.tag }}"

name: "my-first-cron"

args:

- sh

- -c

- |

sleep 2s

"./bin/console --env=prod my:first:comand"

sleep 30

imagePullPolicy:{{ .Values.image.pullPolicy }}

ports:

- name: http

containerPort: 80

protocol: TCPn

And then use the `range` instruction for iterative resource creation:

{{- range $job, $val := .Values.cronjob.crons }}

apiVersion: batch/v1beta1

kind: CronJob

metadata:

name: {{ .name }}

labels: {{ include "kubernetes.labels" $ | indent 4 }}

spec:

schedule: {{ .schedule | quote}}

successfulJobsHistoryLimit: 0

jobTemplate:

spec:

template:

spec:

restartPolicy: Never

containers:

- image: "{{ $.Values.cronjob.repository }}:{{ $.Values.image.tag }}"

name: {{ .name }}

args:

- sh

- -c

- |

sleep 2s

"./bin/console --env=prod {{ .command}}"

sleep 30

imagePullPolicy: {{ $.Values.image.pullPolicy }}

ports:

- name: http

containerPort: 80

protocol: TCP

---

{{- end}}

Finally modify your values.yaml the following way:

>cronjob:

repository: XXXX

crons:

"0":

name: my-first-cron

command: my:first:cron

schedule: "*/10 * * * *"

"1":

name: my-second-cron

command: my:second:cron

schedule: « */3 * * * *"{{- end}}

Here are two things I wish to outline:

Usually to use values stored in your values.yaml file, you do it this way : .Values.XXX.XXX. However, inside the `range` instruction, you need to call it this way $.Values.XXX.XXX

However, inside the `range` instruction, you need to call it this way The 3 dashes at the end are important otherwise, only the last cron of your list will be launched.

I hope this article helps you, don’t hesitate to leave us feedbacks!

If you want to know more about CronJob resource, here is the documentation link or about Helm, here is the Getting Started page.