5

I have what I would consider a common use case but I am really struggling to find a solution:

I want to reuse a variable in Kustomize patches in our deployments. Specifically, we are using commit IDs to reference image tags (Use Case A) and k8s Jobs related to the deployments (Use Case B).

We use a setup where for each ArgoCD app we have a /base/ folder and /overlays/[environment-name], this base is patched with a kustomization.yaml.

Use Case A:

A very straightforward usage - in /overlays/[environment-name] we have a kustomization.yaml which uses:

images:
- name: our-aws-repo-url
  newName: our-aws-repo-url
  newTag: commit-id

Works like a charm since we can re-use this both for the Deployment itself as well as its related Jobs all with one commit reference.

Use Case B:

The problem:

We use N Jobs to e.g. do migrations for 0 downtime deployments where we run alembic containers that run the migration and we have a waitforit initContainer that listens for the Job to get completed i.e. when the migration was successful in order to deploy.

The problem is now that I need to touch 4 files in one service's overlay to patch the id everywhere (which we use to recognize the Job):

  • deployment.yaml like so:
- image: groundnuty/k8s-wait-for:v1.4
  imagePullPolicy: IfNotPresent
  args: 
   - "job"
   - "job-commit-id"
  • job.yaml itself to change re-trigger of Job for new deployment/potential migration:
apiVersion: batch/v1
kind: Job
metadata:
  name: job-commit-id

  • kustomization.yaml as described in Use Case A.

What I think should be possible instead is to:

  1. define variable commit-id somehow in kustomization.yaml and
  2. for Use Case A & B do something like:
apiVersion: batch/v1
kind: Job
metadata:
  name: job-${commit-id}

- image: groundnuty/k8s-wait-for:v1.4
  imagePullPolicy: IfNotPresent
  args: 
   - "job"
   - "job-${commit-id}"
images:
- name: our-aws-repo-url
  newName: our-aws-repo-url
  newTag: ${commit-id}

Goal: when developers do PRs for releases, they should only touch one reference to the commit ID to prevent typos etc. (also easier to review instead of checking commit ID in N places)

Caveat: I am sure there is also another way to do migrations instead of Jobs but this is generally a common thing: how to re-use a variable inside kustomize.

I know I can reference ENV variable in kustomize but I want to reuse a variable within the manifests.

CodeWizard
  • 128,036
  • 21
  • 144
  • 167
tech4242
  • 2,348
  • 2
  • 23
  • 33
  • Why not using helm chart with values? this way you "patch" (upgrade) the helm with your new values and you use the desired variables as values – CodeWizard Sep 28 '21 at 15:42
  • 1
    I am asking a question for kustomize specifically because that is what we opted for. I am aware that Helm can do this but I'd rather ask about this first instead of refactoring all of our deployments for this reason alone. Helm has a lot of other complexity I really don't need. – tech4242 Sep 28 '21 at 15:48
  • You can use Kustomization edit to update your Kustomization resources as well, which can lead out that you will have a script for the updates – CodeWizard Sep 28 '21 at 15:50
  • @CodeWizard can you be more specific? do you mean a CLI command? keep in mind that we are using ArgoCD which actually deploys the manifests – tech4242 Sep 28 '21 at 16:01
  • I know you are using ArgoCD, read about it here: https://argoproj.github.io/argo-cd/user-guide/parameters/, you should use `.argocd-source.yaml` – CodeWizard Sep 28 '21 at 16:03

1 Answers1

1

but I want to reuse a variable within the manifests.

This is not how you typically work with Kustomize. Its a good thing that things are declarative and explicit when working with Kustomize.

when developers do PRs for releases, they should only touch one reference to the commit ID to prevent typos etc. (also easier to review instead of checking commit ID in N places)

yes and no.

That there is a change in four places should not be seen as a problem, in my opinion. That there is human toil to update four places is the problem.

The solution to human toil is typically automation. By using yq in an automated pipeline (e.g. Jenkins - or a shellscript) can you automate your manifest-update to take a single parameter - this can optionally be automated directly for each build after you have a git "commit id" available. The pipeline need to run four yq-commands to update the four Yaml fields. See e.g. assign operation and github action - pipeline example. No other variables are needed.

Jonas
  • 121,568
  • 97
  • 310
  • 388
  • I like the approach and I like the idea behind `yq` - just need to find a way for my service repo to checkout the manifest repo and update the field & make PR but I guess that's a separate issue :) I'll see if I can stich it together – tech4242 Sep 30 '21 at 13:34
  • 3
    Update: we solved the issue as you suggested! Took us a minute but we have been using it now for a week and we have already saved quite a lot of time so big thanks! We also decided to package it in a GH workflow (GH Action soon) so people with a similar setup can benefit from the approach as well. https://github.com/kranushealth/gitops-release-pr – tech4242 Oct 14 '21 at 15:57