We have some database migration jobs that we occationally want to run before deploy a new version of an app. The common approach for this in ArgoCD seems to be to use PreSync hooks, which I have tested and which seems to work, but I'm finding it a little bit limited in terms of functionality, and am unsure if I'm missing something or if that's just how it is.
How I would like it to work, is to only run the db migration jobs when they have changed in some way (most likely a new image), however the way presync jobs seem to be designed (and understandably so) is to always run the specified job on every sync. Functionally, this is fine, the migration job will take ~20 seconds to start and finish and end up doing nothing, however it's clearly not ideal to have this happen for every single unrelated change.
I'm hoping there is some way of accomplishing this "ArgoCD natively" that's I'm just missing.
The job template i'm using currently (and which runs each sync) is this:
{{- define "project.migration_job" -}}
{{- $appsettings := (get .Values.global.apps .name) }}
---
apiVersion: batch/v1
kind: Job
metadata:
generateName: {{ .name }}-
annotations:
argocd.argoproj.io/hook: PreSync
spec:
template:
spec:
automountServiceAccountToken: false
containers:
- name: {{ .name }}
image: "{{ .Values.global.repo }}/{{ .name }}:{{ $appsettings.image }}"
resources:
requests:
memory: {{ $appsettings.memory | default "256Mi" | quote }}
cpu: {{ $appsettings.cpu | default "75m" | quote }}
limits:
memory: {{ $appsettings.memory | default "256Mi" | quote }}
cpu: {{ $appsettings.cpu | default "75m" | quote }}
env:
{{- include "project.environment_variables" (dict "Values" .Values "env" .env) | trim | nindent 12 -}}
{{- include "project.secret_environment_variables" (dict "Values" .Values "secrets" .secrets) | trim | nindent 12 }}
restartPolicy: Never
backoffLimit: 2
{{ end -}}
Thanks for any help.