ArgoCD in Production

GitOps over ClickOps.

Most kubernetes clusters go a certain way the first time around. You see something cool, you write some manifest files, and you perform a kubectl apply -f deployment.yaml. This works, is great for debugging, or making sure you got manifests correct. However this means you don’t have a source of truth, it’s harder to work with others trying to modify the same manifests, and you don’t always know if the manifests have been applied.

One solution to this is GitOps. This allows a git repository to act as a source of truth; constantly checking and updating any running configuration. There are two real choices, FluxCD and ArgoCD. FluxCD is a very minimal choice - no UI, no RBAC, and less community support. FluxCD is also the choice on Big Bang a Department of Defense repository. On the other hand ArgoCD is the opposite — built-in UI and RBAC and great community support.

Defining ArgoCD applications is pretty easy. Take a look at the manifest below:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: adguard # the name of the application in the ArgoCD UI
  namespace: argocd
spec:
  destination:
    server: https://kubernetes.default.svc # what cluster to deploy to
  project: default # the default project
  source:
    path: manifests/adguard/ # the relative file path
    repoURL: https://github.com/ej-east/lisa-cluster # target repo
    targetRevision: HEAD # this is the tag to pull, HEAD is latest
  syncPolicy:
    automated:
      prune: true # removes old resources 
      selfHeal: true # automatically detects and corrects drift

As you can see in ~20 lines you can define an Argo Application. One really cool thing you can do with Argo is create an app-of-apps setup. Defining one app, the root app, to look at a directory of ArgoCD apps and create them.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: root-app
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  destination:
    namespace: argocd
    server: https://kubernetes.default.svc
  project: default
  source:
    path: argocd-applications/
    repoURL: https://github.com/ej-east/lisa-cluster
    targetRevision: HEAD
  syncPolicy:
    syncOptions:
      - CreateNamespace=true
    automated:
      prune: true
      selfHeal: true

One kubectl apply to bootstrap, git handles the rest.

This structure is what makes ArgoCD worth it for me. I can commit everything to git, not worry if what I have locally is running or in GitHub. I no longer have to manually run kubectl apply -f ., I no longer have to do ClickOps — I can do GitOps.