By .
This article follows on from the previous blogpost Setting up a GitOps Cloud-Native continuous integration pipeline on OpenShift/Kubernetes published a few weeks earlier on the blog of SoKube. This will show how to further optimize the GitOps Cloud Native pipeline with the ArgoCD Image Updater tool introduced in the previous article. This tool, which is still experimental and part of the Argo project, will enable us to avoid the internship updating the GitOps deployment repository.
We’ll be starting with the simple Fruitz application, which lets you add and delete a list of fruits. In the previous blogpost, we fixed a bug that prevented users from adding fruit with more than 6 characters, and extended this limit to 9 using a complete integration chain based on Tekton Pipelines for Continuous Integration (CI) and ArgoCD for Continuous Deployment (CD).
In this blogpost, we’ll be working in the same way. We’ll be implementing the functionality enabling the addition of fruit whose number of characters can be less than or equal to 10 (instead of 9 up to now). To do this, we’ll be introducing the ArgoCD Image Updater plugin to set up an even more advanced Cloud-Native GitOps pipeline.
ArgoCD Image Updater is part of the Argo project. It is currently under active development and is offered on an experimental basis. ArgoCD Image Updater is a plugin that integrates with the ArgoCD tool, enabling it to automatically update the image of a Kubernetes pod managed by ArgoCD.
The ArgoCD Image Updater tool checks whether a new version of the application (container image) is available according to a certain predefined pattern, automatically updates the GitOps deployment repository and uses the new image version within the Kubernetes cluster.
To do this, the tool will periodically monitor the container repository where container images are deployed, and detect the arrival of a new version of the application based on the appearance of a new tag following one of the strategies proposed by ArgoCD Image Updater. Here is the list of update strategies proposed by the tool:
semver: Update to the most recent authorized version according to defined constraints,
latest: Update to the latest image version (last tag),
name: Update to the latest version based on a list of tags sorted alphabetically,
digest: Updates to the most recent version of a mutable tag,
Tag filtering: Allows users to define their own update rules.
ArgoCD Image Updater can then automatically update the deployment GitOps repository to maintain the single source of truth principle and avoid merge conflicts within the GitOps repository.
Depending on the synchronization policy defined for the application, ArgoCD will automatically deploy the new image version or mark the application as out of sync. You can trigger the image update manually by synchronizing the application. Thanks to full integration with ArgoCD, advanced features such as synchronization or RBAC authorizations on application-type resources are fully supported.
ℹ️ Note that ArgoCD Image Update only supports Kubernetes deployments based on Helm or Kustomize.
To tell an ArgoCD Application to use ArgoCD Image Updater, simply add Kubernetes annotations.
The demonstration of the GitOps Cloud-Native pipeline based on the ArgoCD Image Updater tool will consist in updating the Fruitz application composed of two microservices:
For this demonstration, the GitOps pipeline will be implemented solely on the Quarkus Fruitz Quarkus Java microservice. It will consist of a standard CI (Continuous Integration) orchestrated by OpenShift Pipelines (Tekton) and a CD (Continuous Deployment) managed by OpenShift GitOps and ArgoCD Image Updater.
The Fruitz Deploy GitOps repository will use the Helm package manager to deploy the application within the OpenShift cluster. To respect the GitOps model, the application code and the deployment code are hosted in two separate repositories on the GitLab.com platform.
At the time of the previous blogpost, the Fruitz application had been deployed and we had added 2 more fruits:
Let’s go back to the application and try adding the Watermelon fruit.
As the Watermelon fruit has a number of characters equal to 10, and the Fruitz application is voluntarily limited to a size of 9 characters per fruit, the addition of this new fruit failed. We can see the error logs from the ArgoCD graphical interface:
The aim of this tutorial is to correct the bug once again and extend the character limit to 10 for fruit names. This process will showcase the functionality of the ArgoCD Image Updater tool with ArgoCD as part of a GitOps Cloud-Native integration chain.
As a reminder, before the integration of the ArgoCD Image Updater tool, the Tekton pipeline consisted of 4 tasks:
As described in the introduction to this blogpost, the ArgoCD Image Updater tool will enable us to completely decouple the IC from the CD. The CI and the CD have independent life cycles, and ArgoCD Image Updater allows us to bypass the "update-helm-deployment-repository" stage of updating the GitOps deployment repository. The tool itself will now redeploy the new version of the microservice.
You can delete the Tekton task via the OpenShift console or with the following command:
oc --namespace cicd delete task update-helm-deployment-repository
You must also modify the Tekton fruitz-quarkus pipeline by removing the reference to the update-helm-deployment-repository task:
Pipeline fruitz-quarkus
:
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: fruitz-quarkus
namespace: cicd
spec:
workspaces:
- name: shared-workspace
resources:
- name: git-source-fruitz-application
type: git
- name: git-source-fruitz-deployment
type: git
params:
- name: buildRevision
- name: buildRevisionShort
- name: buildRevisionBranch
tasks:
- name: maven-package
taskRef:
name: maven-package
resources:
inputs:
- name: git-source-fruitz-application
resource: git-source-fruitz-application
workspaces:
- name: shared-workspace
workspace: shared-workspace
- name: container-image-build-push
taskRef:
name: container-image-build-push
params:
- name: buildRevision
value: $(params.buildRevision)
- name: buildRevisionShort
value: $(params.buildRevisionShort)
- name: buildRevisionBranch
value: $(params.buildRevisionBranch)
- name: mavenProjectVersion
value: $(tasks.maven-package.results.mavenProjectVersion)
resources:
inputs:
- name: git-source-fruitz-application
resource: git-source-fruitz-application
workspaces:
- name: shared-workspace
workspace: shared-workspace
runAfter:
- maven-package
- name: scan-trivy
taskRef:
name: scan-trivy
params:
- name: dockerImageFullName
value: $(tasks.container-image-build-push.results.dockerImageFullName)
workspaces:
- name: shared-workspace
workspace: shared-workspace
runAfter:
- container-image-build-push
The Tekton fruitz-quarkus pipeline now consists of only 3 tasks:
There are two ways to install the ArgoCD Image Updater tool:
In this tutorial, we’ll install ArgoCD Image Updater and ArgoCD (already installed) in the same cluster. For more information, please consult the official documentation
To install the ArgoCD Image Updater tool in the openshift-gitops namespace, enter the following commands:
git clone https://github.com/argoproj-labs/argocd-image-updater
cd argocd-image-updater
oc -n openshift-gitops apply -f manifests/install.yaml
The argocd-image-updater/manifests/install.yaml manifest contains all the Kubernetes resources needed to run the tool (Service Account, RBAC, ConfigMap, Deployment, etc.).
Once the objects have been created, you can check that the installation has been carried out correctly with the following command:
oc -n openshift-gitops get all -l app.kubernetes.io/name=argocd-image-updater
NAME READY STATUS RESTARTS AGE
pod/argocd-image-updater-764ff8ddb7-45bn6 1/1 Running 0 55s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/argocd-image-updater 1/1 1 1 55s
NAME DESIRED CURRENT READY AGE
replicaset.apps/argocd-image-updater-764ff8ddb7 1 1 1 55s
ArgoCD Image Updater is now installed in the cluster, but requires some configuration to become functional. As mentioned in the introduction, we use GitLab for Source Code Management (SCM) and also to host our container images (GitLab Container Registry).
To be able to automatically update image versions and respect the fundamental pillars of GitOps, ArgoCD Image Updater needs to be able to monitor the container registry to detect the appearance of new versions, but also to be able to write (write-back) to the GitOps deployment repository. To do this, we need to enable ArgoCD Image Updater to connect to the container registry and write to the GitLab repository. We need to create two Kubernetes secrets:
First, create a GitLab access token and grant it read-only access to the registry. In Preferences → Access Token, create a token with the scope read_registry.
Retrieve the token and create the gitlab-registry-credentials secret on the OpenShift cluster using the following commands:
GITLAB_USER_NAME=samiamoura
GITLAB_SECRET_TOKEN=YOUR_PRIVATE_GITLAB_TOKEN
GITLAB_EMAIL_ADDRESS=sami.amoura@sokube.ch
oc create secret docker-registry gitlab-registry-credentials
--docker-server=registry.gitlab.com
--docker-username=$GITLAB_USER_NAME
--docker-password=$GITLAB_SECRET_TOKEN
--docker-email=$GITLAB_EMAIL_ADDRESS
--namespace openshift-gitops
Create the git-creds secret containing the SSH private key enabling access to the GitOps repository using the following commands:
Create the file containing the private key :
cat << EOF > ./.gitlab-ssh-private-key.key
-----BEGIN OPENSSH PRIVATE KEY-----
...
-----END OPENSSH PRIVATE KEY-----
EOF
ℹ️ Don’t forget to enter your SSH private key.
Create the OpenShift secret containing the private key
oc -n openshift-gitops create secret generic git-creds
--from-file=sshPrivateKey=./.gitlab-ssh-private-key.key
You now need to tell ArgoCD Image Updater how to configure the container registry. To do this, add/edit the argocd-image-updater-config ConfigMap and the registries.conf file, providing it with the following information:
The credentials to be used: pullsecret:openshift-gitops/gitlab-registry-credentials
using the pullsecret gitlab-registry-credentials in the openshift-gitops namespace (OpenShift secret previously created)
Create/edit the ConfigMap using the following commands:
ConfigMap argocd-image-updater-config
:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-image-updater-config
namespace: openshift-gitops
data:
registries.conf: |
registries:
- name: GitLab Container Registry
api_url: https://registry.gitlab.com
prefix: registry.gitlab.com
credentials: pullsecret:openshift-gitops/gitlab-registry-credentials
Finally, we need to integrate ArgoCD Image Updater with ArgoCD and let it know which ArgoCD application will be using this new function. To do this, simply add annotations to the ArgoCD fruitz-helm application manifest.
Here are the annotations to add and their descriptions:
argocd-image-updater.argoproj.io/write-back-method
: allows you to specify how to update an application’s images, as well as the credentials to be used. Two methods are available:
argocd-image-updater.argoproj.io/image-list
: defines which image is to be updated and monitored in the container registry and assigns an alias to itargocd-image-updater.argoproj.io/<image_alias>.update-strategy
: allows you to define the type of update strategyargocd-image-updater.argoproj.io/<image_alias>.helm.image-tag
: sets the path of the yaml key specifying the image tag to be updated (replaced) in the values.yaml Helm file when ArgoCD Image Updater detects a new image version.Modification of the ArgoCD fruitz-helm application manifest with the addition of the following annotations:
ConfigMap argocd-image-updater-config
:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: fruitz-helm
annotations:
argocd-image-updater.argoproj.io/write-back-method: git:secret:openshift-gitops/git-creds
argocd-image-updater.argoproj.io/image-list: backend=registry.gitlab.com/sokube-io/sample-apps/fruitz/fruitz-quarkus/fruitz-quarkus
argocd-image-updater.argoproj.io/backend.update-strategy: latest
argocd-image-updater.argoproj.io/backend.helm.image-tag: backend.image.tag
labels:
owner: sokube
scope: fruitz
namespace: openshift-gitops
spec:
project: fruitz-deployment
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
source:
path: helm
targetRevision: redhat-opentour-geneva
repoURL: 'git@gitlab.com:sokube-io/sample-apps/fruitz/fruitz-deploy.git'
helm:
valueFiles:
- values.yaml
destination:
server: https://kubernetes.default.svc
namespace: fruitz
Here is a detailed description of the annotations added:
argocd-image-updater.argoproj.io/write-back-method: git:secret:openshift-gitops/git-creds
: Using the git method with the kubernetes secret git-creds previously created in the openshift-gitops namespace .argocd-image-updater.argoproj.io/image-list: backend=registry.gitlab.com/sokube-io/sample-apps/fruitz/fruitz-quarkus/fruitz-quarkus
: Define the backend alias for the registry.gitlab.com/sokube-io/sample-apps/fruitz/fruitz-quarkus/fruitz-quarkus image and enable change detection related to it (monitoring the appearance of new tags).argocd-image-updater.argoproj.io/backend.update-strategy: latest
: Use of the latest strategy for the backend alias (defined in the previous annotation). This strategy consists in detecting the most recent tag of the image corresponding to the bakend alias present in the container registry to synchronize the deployment GitOps repository with it.argocd-image-updater.argoproj.io/backend.helm.image-tag: backend.image.tag
: Assign the backend alias (defined above) to the YAML path of the key corresponding to the fruitz-quarkus microservice image tag (Quarkus Java Microservice) in the Helm values.yaml
file. This depends on the structure of your Helm values.yaml
file and the structure of your Helm chart, but the structure of this model remains conventional. In our case, the image tag corresponding to the fruitz-quarkus microservice (Quarkus Java Microservice) is accessible in the backend → image → tag section : backend.image.tag
.Helm values.yaml
file with structure corresponding to the fruitz-quarkus microservice:
Now that the link between ArgoCD Image Updater and AgroCD is up and running, we’ll be able to test our GitOps Cloud-Native pipeline with this new tool.
To demonstrate the benefits of the two associated tools, we’re going to update the fruitz-quarkus microservice so that it can add fruits with a character count of 10 or less.
Updated the fruitz-quarkus repository by increasing the character limit from 9 to 10:
The update of the fruitz-quarkus repository triggered the execution of a new pipeline with only 3 tasks instead of 4 before the deployment of ArgoCD Image updater. Indeed, as explained in the introduction, the GitOps deployment repository update task has been removed.
We can see that the pipeline has been successfully executed.
In the container registry we can see that a new version of the registry.gitlab.com/sokube-io/sample-apps/fruitz/fruitz-quarkus/fruitz-quarkus image has been published by the Tekton pipeline container-image-build-push task, with the tag 1.0-SNAPSHOT-07a0170d
.
In the GitOps deployment repository, we can see that a new .argocd-source-fruitz-helm.yaml file has been created at the root of the directory. This new file was automatically created by ArgoCD Image Updater during a new commit, thanks to the parameters (annotations) specified in the ArgoCD fruitz-helm Application manifest.
In this file we can see that the helm.parameters.name key contains the following parameters:
image.name
: registry.gitlab.com/sokube-io/sample-apps/fruitz/fruitz-quarkus/fruitz-quarkusbackend.image.tag
: 1.0-SNAPSHOT-07a0170dIt is these parameters that will be used by ArgoCD to redeploy/update the application within the Kubernetes/OpenShift cluster, overriding the parameters initially present in the Helm values.yaml file.
ArgoCD has detected a new modification in the GitOps repository, so it will take care of redeploying the new version of the application with the new image registry.gitlab.com/sokube-io/sample-apps/fruitz/fruitz-quarkus/fruitz-quarkus:1.0-SNAPSHOT-07a0170d
We can now try adding the Watermelon fruit again and see that it works. The fruit is added to the list of fruits.
You can also check which version is deployed by querying a microservice-specific endpoint. We see that it is version 1.0-SNAPSHOT-07a0170d
In this new tutorial we take a look at how to set up an advanced GitOps Cloud Native pipeline on the OpenShift platform. This article introduces the ArgoCD Image Updater plugin and demonstrates how to use it in conjunction with the ArgoCD and Tekton pipelines tools. Finally, the ArgoCD Image Updater project allows us to further simplify the implementation of our CI/CD by eliminating the need to write the task/stage updating the GitOps repository, and to decouple the CI from the CD as much as possible, since both have their own lifecycle. It’s still in the experimental phase and therefore subject to further development, but there’s no doubt that it will soon be available to accompany our production CI/CDs.
Check the following links related to this blog post and see how SoKube can help you :