GitOps with ArgoCD

by Ross Fairbanks on Oct 29, 2021

GitOps with ArgoCD image thumbnail

Following on from our introductory article on the subject of GitOps, the aim of this next article is to delve into the first of the GitOps tools we’re putting under the microscope; ArgoCD. Before we dive into the features of ArgoCD, let’s provide some background, and see where it came from.

ArgoCD is one tool in a family of open-source tools whose aim is 'to get things done with Kubernetes'. The first of the family of tools, Argo Workflows, originated in 2017 from a company called Applatix, which was subsequently acquired by Intuit. Following the acquisition, ArgoCD made its first appearance in August 2018, and since that initial pre-release, it’s progressed to  v2.1.5 (as I write), with a sizeable number of organizations using it for continuous application delivery. 

In addition to this successful growth, the Argo family of projects are collectively an incubating project under the auspices of the Cloud Native Computing Foundation (CNCF). And to further emphasize the prominence of ArgoCD, Red Hat recently chose to build their OpenShift GitOps offering on top of ArgoCD (and actively collaborate on the project). So, that’s a lot of popularity and credibility — but what is it that ArgoCD can do for us?

GitOps workflow

A basic GitOps workflow with ArgoCD might look like something like this:

 

A developer makes changes to an application, and pushes a new version to a Git repo, along with a revised configuration for the Kubernetes resource definitions. A continuous integration pipeline is triggered, which results in a new container image being pushed to a registry. Once the pull request has been reviewed and the changes merged to the main branch, a webhook is triggered which notifies ArgoCD of new changes. ArgoCD clones the repo, compares the desired state of the application with the actual state running in the cluster, and applies the changes. At this point, Kubernetes takes over to reconcile the workload. The tracked repo might hold the config for an application that runs in the same cluster as ArgoCD, but ArgoCD can also manage applications running in remote clusters. The workflow effectively installs or upgrades an application without a human interacting directly with the cluster.

This is a rudimentary description of a GitOps workflow, and there are multiple factors that need to be taken into consideration when architecting a workflow. These factors are concerned with how an organization’s teams work together along the continuous pipeline, and how changes are promoted to different environments (i.e. dev, staging, production). It can result in many or a few Git repositories, multiple namespaces, and multiple clusters. Whatever falls out of these architectural considerations, ArgoCD provides the automation to provide the final delivery step in the workflow.

Custom Resource Definitions

So, how does ArgoCD know what to track, from where, and to which cluster and namespace to apply changes to? Well, first of all, ArgoCD is a collection of software components that run in a dedicated namespace on a Kubernetes cluster. Just like any domain-specific application or controller that runs atop Kubernetes, ArgoCD works from custom resource definitions (CRDs). Specifically, ArgoCD extends the Kubernetes API with application and project CRDs. Instances of the former provide ArgoCD with the source of the configuration for an application (a Git repo or a Helm repo), as well as the location of the target cluster and namespace to apply the configuration to. The latter provides a means for grouping applications together so that different teams can restrict access to their specific application resources.

User interface

It’s possible to craft instances of the application CRDs by hand in YAML files before applying them to a Kubernetes cluster. But, not everyone likes creating and maintaining YAML resource definitions, and additional configuration on top of that required to describe an application, just adds to the burden. For that reason, ArgoCD provides a couple of ways of creating the CRDs it introduces and consumes.

The first method is to use ArgoCD’s CLI, which is fully-featured. There’s an awful lot you can achieve with the CLI, but creating application CRDs is one of the more relevant features:

argocd app create guestbook \
    --repo https://github.com/argoproj/argocd-example-apps.git \
    --path guestbook \
    --dest-namespace default \
    --dest-server https://kubernetes.default.svc \
    --directory-recurse

Executing this command results in the creation of an application resource that describes its GitOps-related characteristics to ArgoCD, and the subsequent deployment of the application to the cluster by ArgoCD.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: guestbook
  namespace: argocd
spec:
  destination:
    namespace: default
    server: https://kubernetes.default.svc
  project: default
  source:
    directory:
      recurse: true
    path: guestbook
    repoURL: https://github.com/argoproj/argocd-example-apps.git

Perhaps a more seductive approach to creating an application CRD is to use ArgoCD’s graphical user interface. ArgoCD’s application server (which runs in-cluster) serves a Node.js-based user interface, that can be used for managing the lifecycle of applications under the control of ArgoCD. As well as providing an abstraction over the underlying resources and command line, the user interface also provides a graphical representation of the Kubernetes configuration that describes the app:

It might be argued that the management of applications through a GUI is not strictly GitOps-style. After all, isn’t everything supposed to be managed through a Git repository, including the configuration that governs the GitOps workflow? Despite this, everyone who first encounters ArgoCD usually cites its user interface as one of its standout features, which makes it more approachable for new users. Perhaps one that significantly distinguishes it from its competition.

Multi-tenancy

When an organization adopts GitOps wholesale, it will inevitably mean that multiple teams will be interacting with a single instance of ArgoCD to manage their individual application stacks. This means there is significant scope for stepping on each other’s toes, with the obvious chaos that could ensue. In recognition of this, ArgoCD supports multi-tenancy as a first-class feature.

We already mentioned the projects CRD earlier, which enables the association of different applications with projects. The project CRD can be defined in such a way as to restrict the source repositories that ArgoCD reads from for applications that belong to that project. Similarly, the project CRD can also limit the cluster/namespace combination that applications for that project can be deployed to. Fine-grained control can be achieved through the creation of roles and role-based access control, which are defined as part of a project CRD instance. A complimentary CRD (called an ApplicationSet), along with its associated controller, can also be used to manage multi-tenancy scenarios in an ArgoCD GitOps setting.

Configuration management tools

There are a lot of tools and techniques for generating and managing the resource definitions that describe the configuration of applications in Kubernetes; pure YAML, Helm charts, Kustomize overlays, and many more. If you want to adopt a GitOps approach to application deployment, then you don’t necessarily want to sacrifice the investment that’s been made in this tooling in order to accommodate your preferred GitOps agent. ArgoCD is great in this respect, having the ability to render pure YAML, Helm charts, Kustomize overlays, and configuration written in Ksonnet (deprecated), and Jsonnet.

There are other tools beyond this list, however, but ArgoCD provides a mechanism for their inclusion through a plugin system. Plugins can be created by anyone with a need, and at Giant Swarm, we’ve done just that, as our requirements are quite complex due to our need to manage fleets of clusters and apps. The plugin system works, but is not as optimal as might be, and there is work underway to overhaul the plugin system to improve the experience when working with other configuration management tools.

Conclusion

When it comes to GitOps, ArgoCD is one of the major players in the Kubernetes domain. And, whilst we’ve covered some of the salient features in this article, there is much, much more available to endear us to its utility. For example, it provides a hook mechanism for running scripts to augment the syncing of the desired state in the cluster, and sync phases and waves to further improve the flexibility available for the syncing process.

What gives ArgoCD a further boost is its inclusion in the wider ecosystem of tools under the Argo umbrella. Combining ArgoCD with Argo Rollouts, for example, enables progressive application deployments (e.g. canary releases), directly under the control of a GitOps workflow.

We’d love to hear about your experiences with ArgoCD, and how it helps you to implement a GitOps workflow for your cloud-native infrastructure and applications. Get in touch and tell us about it.