
Developers, I hope you are well out there! A new year and a lot of new promises π
The Sitecore User Group Conference (SUGCON) – Europe 2023, is almost upon us. This time it’s in Malaga in Spain. You should register at once => https://europe.sugcon.events/
Before we start, let’s celebrate and congratulate all the happy Sitecore MVPs. Read all about it – https://www.sitecore.com/company/newsroom/press-releases/2023/01/sitecore-announces-2023-most-valuable-professionals
Hip hip hooray ππ
Today’s post will be all about Argo CD, yes there are others, but ArgoCD is my Number 1 π
What I love about ARGO is that they have a bunch of tools/services, and one of them is… Argo CD Image Updater
A tool to automatically update the container images of Kubernetes workloads that are managed by Argo CD.
The Argo CD Image Updater can check for new versions of the container images that are deployed with your Kubernetes workloads and automatically update them to their latest allowed version using Argo CD.
This means it will watch every change in your container registry, and then update your GitOps repository with the change. You can even skip the part to update in the GitOps repo and instead update directly in the Kubernetes cluster(This approach should only be done in test, never in production).
What I really like about Argo CD Image Updater is that I don’t have to update the GitOps repository anymore after every build( and push) of the docker images. Instead Argo CD Image Updater will do it for us, and that’s a HUGE win π
So today’s post will be about how to setup Argo CD Image Updater in an AKS(Azure Kubernetes Service) cluster and use it π We will assume that you already have installed Argo CD. If not, just follow the instruction here – https://argo-cd.readthedocs.io/en/stable/getting_started/ π
It’s time to install Argo CD Image Updater, let’s follow the instructions => https://argocd-image-updater.readthedocs.io/en/stable/install/installation/
We will install the Image Updater in the same namespace as Argo CD, to install it we just deploy the manifest:
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-image-updater/stable/manifests/install.yaml
Let’s have a look if it’s up? YES, success π

A good idea is to add some extra logging, at least in the beginning. This means we will update the ConfigMap => argocd-image-updater-config. We simply do the following kubectl command :
kubectl edit configmaps --namespace argocd argocd-image-updater-config
It will open up your text editor tool(notepad for me)

Type in you change, save and then close it π
data:
log.level: debug
Ok! Next part is to add a connection to our container registry. You can read about it here => https://argocd-image-updater.readthedocs.io/en/stable/configuration/registries/
This means we will update ConfigMap => argocd-image-updater-config again, and add the following in the data section(right below log.level: debug):
registries.conf: |
registries:
- name: Azure Container Registry
prefix: mycontainerregistry.azurecr.io
api_url: https://mycontainerregistry.azurecr.io
credentials: pullsecret:argocd/mycontainerregistry-secret
Let me go through each “attribute”.
NAME, it’s just a name.
PREFIX, here we set the “Login server” from our Azure Container Registry
API URL, it’s the “Login server” from our Azure Container Registry but with https://
CREDENTIALS, now this part is a bit tricky π
According to the section => https://argocd-image-updater.readthedocs.io/en/stable/basics/authentication/#auth-registries
There are three ways:
- Using a pull secret => https://argocd-image-updater.readthedocs.io/en/stable/basics/authentication/#using-a-pull-secret
- Using a generic secret => https://argocd-image-updater.readthedocs.io/en/stable/basics/authentication/#using-a-generic-secret
- Using an environment variable => https://argocd-image-updater.readthedocs.io/en/stable/basics/authentication/#using-an-environment-variable
I first went for the generic secret, but no luck π¦
*I read somewhere it could work if you used Service Principle.
But pull secret worked π So, to create a pull secret, we will create a docker-registry secret. Again we will do this with a kubectl command:
kubectl -n argocd create secret docker-registry mycontainerregistry-secret --docker-server=mycontainerregistry.azurecr.io --docker-username=mycontainerregistry--docker-password=PASSWORD -o yaml --dry-run=client | kubectl -n argocd apply -f -
Let’s go through the command. But before we start, we need to set “Admin user” to Enabled in our Azure Container Registry:

Ok! We will name the secret with mycontainerregistry-secret. For –docker-server we set the “Login server” from our Azure Container Registry. And for docker-username we will use the “Username” from our Azure Container Registry. And for docker-password we will use one of the passwords from our Azure Container Registry.
Let’s check if the secret is created. Yes, success π

Did you notice the type: kubernetes.io/dockerconfigjson. This means we will have JSON in the secret π Here is the JSON:
{
"auths": {
"mycontainerregistry.azurecr.io": {
"username": "mycontainerregistry",
"password": "PASSWORD",
"auth": "bXljb250YWluZXJyZWdpc3RyeTpQQVNTV09SRA=="
}
}
}
Great! So let us run the following command to update our ConfigMap => argocd-image-updater-config.
kubectl edit configmaps --namespace argocd argocd-image-updater-config
And add the connection info(to the container registry):

The last thing we need to do is to restart the Image Updater. I was going crazy here, and I could not understand why the Image Updater had no access to our Azure Container registry. But after a restart, everything worked. To restart we kill the pod, and it will create itself again π
So now the Image Updater has access to our Azure Container Registry. Next will be to configure/tell our ArgoCD applications how to update images.
There are many ways to configure the ArgoCD application => https://argocd-image-updater.readthedocs.io/en/stable/configuration/images/#configuring-images-for-update
There are four update strategies:
- semver Update to the tag with the highest allowed semantic version
- latest Update to the tag with the most recent creation date
- name Update to the tag with the latest entry from an alphabetically sorted list
- digest Update to the most recent pushed version of a mutable tag
By default, it’s set to use semver, and that’s what we will use π
If you want the Image Updater to update the image directly in your Kubernetes cluster, I would recommend you go for digest. You will have a tag like :latest and then the Image Updater will watch the “digest changes” in your repository. Don’t forget to add the annotation => argocd-image-updater.argoproj.io/myalias.update-strategy: digest
So let’s have a look at one of our ArgoCD applications and see the benefits of using ArgoCD Image Updater:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: nextjs-myapp
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/sandbox/GitOps.Test
targetRevision: main
path: k8/Sandbox/specs/nextjs-myapp
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
selfHeal: true
prune: false
This is a “standard” ArgoCD application. Which will listen to changes(to be more specific, it will listen to changes in the kustomize file) in the path k8/Sandbox/specs/nextjs-myapp in GitOps.Test repository.
Here is the kustomization file for MyApp:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
images:
- name: nextjs-myapp
newName: mycontainerregistry.azurecr.io/sandbox-nextjs-myapp-test
newTag: v1.0.1
resources:
- _deployment.yaml
- _pdb.yaml
- _service.yaml
- _hpa.yaml
Let’s visualize it with a CI/CD workflow(GitHub Actions):
- Developer creates a PR and merges it to the test branch.
- A GitHub Action generates and pushes the docker image(gives it a proper tag name) to the Azure Container Registry.
- The second GitHub Action updates the GitOps repository(the kustomization file) with the new image tag.
ArgoCD listens to the changes in the GitOps repository and syncs the changes to the Kubernetes cluster.

But with ArgoCD Image Updater, we don’t need the step that updates the GitOps repository. That means that the CI/CD workflow will now look like this:

So how do we do this? Well, all we have to do is to update the ArgoCD application MyApp, with “annotations”:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: nextjs-myapp
namespace: argocd
annotations:
argocd-image-updater.argoproj.io/image-list: myalias=mycontainerregistry.azurecr.io/sandbox-nextjs-myapp-test:*
argocd-image-updater.argoproj.io/write-back-method: git
argocd-image-updater.argoproj.io/git-branch: main
argocd-image-updater.argoproj.io/write-back-target: kustomization
argocd-image-updater.argoproj.io/myalias.force-update: "true"
spec:
project: default
source:
repoURL: https://github.com/sandbox/GitOps.Test
targetRevision: main
path: k8/Sandbox/specs/nextjs-myapp
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
selfHeal: true
prune: false
Let’s go through the annotations!
argocd-image-updater.argoproj.io/image-list:
This tells Image Updater what repository to watch,Β myalias=mycontainerregistry.azurecr.io/sandbox-nextjsproxy-myapp-test:*. (The reason for using an alias is that itβs the recommended approach) We set the name to our repository, and with the tag *, it means it will allow anything. This is not recommended. Instead, we should have something like this :~1(It will listen to changes as long as they are in version 1). But since we are using Image Updater in TEST, then theΒ :*Β is perfect for our needsΒ π
argocd-image-updater.argoproj.io/write-back-method:
This tells Image Updater to write to our GitOps repo, meaning it will update the GitOps repo with the latest changes(image tag) from the Azure Container registry.
argocd-image-updater.argoproj.io/git-branch:
This tells what git branch the Image Updater should use.
argocd-image-updater.argoproj.io/write-back-target:
Since we are using Kustomize, the value kustomization means that the Image Updater will update the Kustomize file in our repo.
And that’s it, now we have a running ArgoCD Image Updater that listens to changes in the container registry and then automatically updates the GitOps repository!
If you are still not convinced that Image Updater is your best GitOps friend(in your test environment), then you should check out what my favorite devops guy, DevOpsToolkit, has to say π
Thatβs all for now folks π