Argo Image Updater
Author: Gourav Shah
Publisher: School of Devops
Version : v2024.06.04.01
Project: Connect CI Pipeline set up with Argo Workflow and Argo Events with the CD Pipeline created with ArgoCD and Argo Rollouts. Set up a workflow where
- Whenever there is change to the
main
branch of the application code, it triggers the CI Pipeline with Argo Events + Argo Workflow. The result of this is a new image being published to the container registery. - Set up a watcher which is monitor the container registry, this is where argo image updater comes in. Whenever a new tag with a certain pattern is available in the registry, update the image tag in the
main
branch of the deployment repo with it. Auto commit to GitHub. - Change to the image tag should be automatically picked up by Argo CD and it should trigger the deployment to staging. Since its been integrated with argo rollouts, it implments the release strategy (e.g. Blue/Green) configured with the rollout spec.
- Deployment to prod is just one pull request away. Whenever the change (e.g. new image tag) is merged from master to release branch, prod deployment should get triggered based on another application deployment flow set up with Argo CD. And that GitOps in action for you...
Set up automatic Image Updater with ArgoCD
Install Argo CD Image Updater as,
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-image-updater/stable/manifests/install.yaml
Create a Secret with your GitHub credentials so that the image updater can discover and commit the image tags to git repository.
kubectl -n argocd create secret generic git-creds \
--from-literal=username=xxxxxx \
--from-literal=password=ghp_yyyyyy
Note : replace xxxxxx
with your GitHub Username and ghp_yyyyyy
with GitHub Access Token with write access to repository. If you do not already have token, create it from GitHub
Marking Staging Application for Auto Image Updates
When you set up staging deployment, ArgoCD has created a application object for you. You would need to add a few annotations to it so that the Image Updater knows that this application is been marked for image auto update.
Observe the existing application created from ArgoCD UI as,
kubectl get application -n argocd
kubectl describe application -n argocd vote-staging
specifically observe the annotations
Annotations: <none>
To update this application with appropriate annotations create a patch file with the name and content given below,
File : argo_applications_vote-staging_patch.yaml
metadata:
annotations:
argocd-image-updater.argoproj.io/git-branch: main
argocd-image-updater.argoproj.io/image-list: myimage=xxxxxx/vote
argocd-image-updater.argoproj.io/myimage.allow-tags: regexp:^[0-9a-f]{7}$
argocd-image-updater.argoproj.io/myimage.ignore-tags: latest, dev
argocd-image-updater.argoproj.io/myimage.update-strategy: latest
argocd-image-updater.argoproj.io/myimage.kustomize.image-name: schoolofdevops/vote
argocd-image-updater.argoproj.io/myimage.force-update: "true"
argocd-image-updater.argoproj.io/write-back-method: git:secret:argocd/git-creds
argocd-image-updater.argoproj.io/write-back-target: "kustomization:../base"
Source: Mark Staging App for Automatic Image Updates from Argo
Where,
- Replace
xxxxxx/vote
with your own repo in theargocd-image-updater.argoproj.io/image-list
annotation.
Apply the above patch as,
kubectl patch application --type=merge -n argocd vote-staging --patch-file argo_applications_vote-staging_patch.yaml
Validate annotations are added,
kubectl describe application -n argocd vote-staging
[sample output]
...
Labels: <none>
Annotations: argocd-image-updater.argoproj.io/git-branch: main
argocd-image-updater.argoproj.io/image-list: myimage=initcron/argovote
argocd-image-updater.argoproj.io/myimage.allow-tags: regexp:^[0-9a-f]{7}$
argocd-image-updater.argoproj.io/myimage.force-update: true
argocd-image-updater.argoproj.io/myimage.ignore-tags: latest, dev
argocd-image-updater.argoproj.io/myimage.kustomize.image-name: schoolofdevops/vote
argocd-image-updater.argoproj.io/myimage.update-strategy: latest
argocd-image-updater.argoproj.io/write-back-method: git:secret:argocd/git-creds
argocd-image-updater.argoproj.io/write-back-target: kustomization:../base
API Version: argoproj.io/v1alpha1
Kind: Application
...
If everything goes well, within a few minutes, you should see a commit to the main branch of the vote-deploy
repository that you have.
And a few minutes after that, you should see the staging deployment on ArgoCD pick up the newly updated image tag and deploy it.
You could tally it from Rollout Dashboard that it has picked up the new image with commit hash as tag
and also validate with
kubectl describe application -n argocd vote-staging
where you should see the following in the output status
Summary:
Images:
initcron/vote:52eea4d
Sync:
Compared To:
Destination:
Namespace: staging
Server: https://kubernetes.default.svc
Source:
From now, its just matter of creating a pull request and merging it to release branch to deploy to prod.
You could check the logs for the image updater which is running in argocd
namespace by using a command similar to
kubectl logs -f -l "app.kubernetes.io/name=argocd-image-updater" -n argocd
Thats all ! If you have gotten till here, congratulate yourself as you have just built a simplistic but completely working modern CI/CD Pipeline ! Hurray !!