6

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.

Cesar
  • 2,027
  • 2
  • 18
  • 29

1 Answers1

0

I don't know if there's a native solution, but this could help:

In your PreSync hook:

  1. IMAGE_TAG_TO_DEPLOY: Get the image tag that will be deployed from the source repo (Ex.: curl -LSs https://x-access-token:"$GITHUB_TOKEN@raw.githubusercontent.com/company/project/master/path-to-image-tag.yaml" and parse the image tag value)
  2. COMMIT_ID_TO_DEPLOY: Find the commit ID that corresponds to IMAGE_TAG_TO_DEPLOY
  3. COMMIT_ID_DEPLOYED: Find the commit ID pointed to by a git tag named currently-deployed
  4. If COMMIT_ID_TO_DEPLOY == COMMIT_ID_DEPLOYED, end the PreSync Hook
  5. Perform the required actions for the PreSync hook.
  6. Add the git tag currently-deployed to COMMIT_ID_TO_DEPLOY in your git repo
Elifarley
  • 1,310
  • 3
  • 16
  • 23