Home >> Blog – EN >> Optimize the GitOps Cloud Native pipeline with ArgoCD Image Updater

Optimize the GitOps Cloud Native pipeline with ArgoCD Image Updater

09 November 2023

By Sami AMOURA.

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.

The ArgoCD Image updater project

Presentation

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.

How it works

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.

Workflow

Genral workflow

Advanced Cloud-Native GitOps pipeline

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:

  • The backend developed with Java Quarkus: fruitz-quarkus
  • A frontend based on Angular technology

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.

Background

At the time of the previous blogpost, the Fruitz application had been deployed and we had added 2 more fruits:

  • Pear
  • Pineapple

Initial user interface

Let’s go back to the application and try adding the Watermelon fruit.

Adding watermelon

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:

ArgoCD logs

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.

Tekton Pipeline

As a reminder, before the integration of the ArgoCD Image Updater tool, the Tekton pipeline consisted of 4 tasks:

  • maven-package: Java application packaging,
  • container-image-build-push: containerize the Java application and push it into the container registry,
  • scan-trivy: container image vulnerability scanner (SAST),
  • update-helm-deployment-repository: update GitOps deployment repository.

Tekton intial four 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:

  • maven-package
  • container-image-build-push
  • scan-trivy

Tekton intial four tasks

Installing and configuring ArgoCD Image Updater

Installation

There are two ways to install the ArgoCD Image Updater tool:

  • In the same Kubernetes cluster (and namespace) where the ArgoCD instance is deployed, using native Kubernetes manifests and/or Kustomize,
  • In a different Kubernetes cluster from where the ArgoCD instance is deployed.

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

Configuration

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:

  • A docker-registry secret that we’ll call gitlab-registry-credentials so we can connect to and monitor our GitLab container registry,
  • Another Kubernetes secret with the SSH private key named git-creds for writing to the GitOps repository.

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.

GitLab oken creation

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:

  • Container registry name: GitLab Container Registry
  • Container registry API URL: https://registry.gitlab.com
  • Registry prefix: registry.gitlab.com

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:
    • git: declarative approach (GitOps), which allows you to create a commit in the GitOps repository with the tags of the new images
    • argocd: imperative approach, enabling direct modification of the ArgoCD application within the Kubernetes cluster or using the ArgoCD API
  • 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 it
  • argocd-image-updater.argoproj.io/<image_alias>.update-strategy: allows you to define the type of update strategy
  • argocd-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:

Helm values structure

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.

Pipeline execution

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.

Update of the fruitz-quarkus microservice

Updated the fruitz-quarkus repository by increasing the character limit from 9 to 10:

Update fruitz limit

Running the new GitOps Cloud-Native pipeline

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.

Tekton tasks success

Tekton pipeline success

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.

Tketon pipeline success

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.

ArgoCD Image Updater Helm file

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-quarkus
  • backend.image.tag: 1.0-SNAPSHOT-07a0170d

It 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 Image Updater automatic update

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

New updated pod

New updated podwith commit ID

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

New updated podwith commit ID

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.

SoKube can help you !

Check the following links related to this blog post and see how SoKube can help you :

Leave a Reply

  Edit this page