Skip to main content

Kargo, deploy from one environment to another with GitOps

·6 mins
gitops argocd container git kargo cd helm kustomize yaml
Romain Boulanger
Author
Romain Boulanger
Cloud Architect with DevSecOps mindset
Table of Contents

This article was written using Kargo version 0.3.1.

Introduction
#

Last month I presented Flamingo, which combines both Argo CD and Flux CD to take advantage of these two tools and adopt a GitOps approach.

However, GitOps or the above tools do not define a means of promoting changes that have been made from a development environment to a qualification or production environment.

In fact, Argo CD and Flux CD are responsible to deploy one or more target environments without any link or relationship between them.

However, it is possible to adopt a Branching Model to promote these changes. If you’re not familiar with the term, I recommend you take a look at this article.

Fortunately, a solution appeared a few months ago, even if it’s still in the development phase and therefore not ready to be used in production. In this article, I’d like to give you an overview of the potential of this tool.

Kargo, the answer
#

Who hasn’t dreamt of pressing a button to transfer changes from one environment to another? The most classic example is a new container image that is tested on a development environment before being deployed on a qualification environment.

This is exactly what Kargo can do, although it goes even further than image version management: it is capable of applying the different configurations of your Kubernetes objects.

Moreover, Kargo is part of the Argo Project (the same family as Argo CD) and is a 100% open source tool.

In a nutshell, Kargo is a continuous delivery platform which gives you the opportunity to orchestrate the lifecycle of applications on Kubernetes from one environment to another, using existing tools.

That’s right, Kargo works directly with Argo CD, which does what it does best: deploying Kubernetes objects.

Features
#

As mentioned above, Kargo is still a very young tool, but it has a number of features:

  • Promotion of configurations or containerised images from one environment to another;
  • Writing changes to Git: As soon as a change is approved, Kargo generates a Pull Request and commits the changes;
  • Ability to roll back changes in the event of an error;
  • Creation of tests to validate the correct operation of an environment, particularly with Argo Rollouts;
  • Canary and A/B testing can be used to deploy to a target environment.

This list maybe changed in future versions of Kargo. In fact, the team’s objective is to enhance the product in future versions until it reaches a first major version (1.0.0) in order to encourage the adoption of Kargo in production environments.

Kargo has a user interface that allows changes to be tracked at a glance:

Kargo UI

This interface also allows you to view the images or configurations associated with the defined environments. This makes it possible to have a history and to audit all the actions within Kargo.

Finally, the large black bar at the top is called the freight line (Freight), as in the case of goods transport. Now, you see the link between that and Kargo, right?

How does it work?
#

Let’s discuss about how Kargo works and how it manages environments, especially when a new image version is available.

Kargo workflow

Here is the sequence of operations in order:

  1. The CI, whatever the platform, creates a new container image;
  2. The image is pushed in a container registry;
  3. Depending on the configurations defined, Kargo analyses the Git repository containing the Kubernetes objects (1) and searches for any new associated images (2);
  4. Depending on the new images retrieved, the developer has the choice to promote these changes on the first environment configured, which in this case will be development;
  5. Once the developer has validated the changes, Kargo pushes them into Git;
  6. With the previous action, Argo CD is triggered and detects an update to the files in the development environment;
  7. Argo CD synchronises the changes on the Kubernetes cluster;
  8. Kargo retrieves the status of the deployed objects and enables tests to be carried out;
  9. If everything is OK, the developer can approve these changes for the next environment.

On the installation side, Kargo is best deployed with a Helm chart, and it is recommended that it is positioned as close as possible to the Argo CD, as it interacts directly with it.

As you can see, Kargo allows you to chain one or more environments according to your deployment cycle. These environments are embodied in a Kubernetes object called a Stage:

apiVersion: v1
kind: Namespace
metadata:
  name: kargo-demo
  labels:
    kargo.akuity.io/project: "true"
---
apiVersion: kargo.akuity.io/v1alpha1
kind: Warehouse
metadata:
  name: docker-registry
  namespace: kargo-demo
spec:
  subscriptions:
  - image:
      repoURL: nginx
      semverConstraint: ^1.24.0
---
apiVersion: kargo.akuity.io/v1alpha1
kind: Stage
metadata:
  name: dev
  namespace: kargo-demo
spec:
  subscriptions:
    warehouse: docker-registry
  promotionMechanisms:
    gitRepoUpdates:
    - repoURL: ${GITOPS_REPO_URL}
      writeBranch: main
      kustomize:
        images:
        - image: nginx
          path: overlays/dev
    argoCDAppUpdates:
    - appName: nginx-dev
      appNamespace: argocd

Here’s an example of how to generate a dev environment within Kargo. This is made up of several Kustomize base, overlays/dev, overlays/uat and overlays/prod folders to reference the specific configurations of each environment. Note that this code repository deploys a simple deployment containing an nginx image.

If you want to reproduce this at home, I advise you to use this example which provides the steps to follow to test Kargo.

I’ve made a few small changes to the basic version. Instead of creating a branch for each environment, I use the main branch with the writeBranch: main parameter.

As you can see, the dev environment listens on a docker-regitry Warehouse object which retrieves new nginx images by following the associated semver constraint (^1.24.0). In addition, the argoCDAppUpdates block links up with Argo CD, which orchestrates deployment once the changes have been approved.

Note that creating a Namespace with the label kargo.akuity.io/project: "true" is essential for referencing the kargo-demo project within the tool.

Here are the steps between an image registry and a development environment. Of course, it’s possible to go further and add environments in succession in this way, always in the form of stages.

apiVersion: kargo.akuity.io/v1alpha1
kind: Stage
metadata:
  name: uat
  namespace: kargo-demo
spec:
  subscriptions:
    upstreamStages:
    - name: dev
  promotionMechanisms:
    gitRepoUpdates:
    - repoURL: ${GITOPS_REPO_URL}
      writeBranch: main
      kustomize:
        images:
        - image: nginx
          path: overlays/uat
    argoCDAppUpdates:
    - appName: nginx-uat
      appNamespace: argocd
---
apiVersion: kargo.akuity.io/v1alpha1
kind: Stage
metadata:
  name: prod
  namespace: kargo-demo
spec:
  subscriptions:
    upstreamStages:
    - name: uat
  promotionMechanisms:
    gitRepoUpdates:
    - repoURL: ${GITOPS_REPO_URL}
      writeBranch: main
      kustomize:
        images:
        - image: nginx
          path: overlays/prod
    argoCDAppUpdates:
    - appName: nginx-prod
      appNamespace: argocd

Your Kargo pipeline should look like this:

Kargo pipeline

The promotion mechanism can be used directly from the interface or on the command line:

Kargo promotion

As mentioned above, the promotion will commit directly to your code repository, triggering deployment within Argo CD :

GitHub diff

Kargo with Argo CD

It is entirely possible to continue and update subsequent environments by carrying out the same steps for uat and prod.

Finally, Kargo makes it possible to work with several types of source within the warehouse object, including image registries, Git code repositories and Helm chart registries.

A few final words…
#

Rather than fiddling with a CI/CD chain based on diff and sed to promote your changes, Kargo brings with it a lack often expressed when talking about GitOps tools: orchestration between environments.

Once again, Kargo is still very young, but I personally think it has great potential. In the future, it may even become essential with any Argo CD installation.

Don’t hesitate to follow Kargo releases and updates on GitHub.

Related

GitOps approach with Flamingo, the best of both worlds
·7 mins
gitops flamingo flux argocd cd kubernetes