Argo CD

We are switching more and more to Kubernetes to run our applications. This (re)introduces a new issue with the application lifecycle. We have the ability to change resources in a Kubernetes cluster and forget about it. Months later, when we redeploy the original manifest, the application will break. Or when we promote something from Test to Acceptance and we forget that we changed a resource after we deployed it and again we lose time researching why the application breaks.

Problems

The scenario above describes a few problems we can have with manual deployments to Kubernetes clusters.

  • Mutability: We can change the Kubernetes cluster state without changing the source. This means that we have an issue when someone re-deploys the source files.
  • Versioning: We don’t have any versioning of the changes. Something can break and we can’t go back. Manual changes are error prone when promoting through DTAP environments. Also, the traceability part isn’t guaranteed.
  • Process: The process to manage a cluster becomes more complex

GitOps

Many of the issues can be solved by switching to GitOps. According to Weaveworks, GitOps contains of four principles:

  1. The entire system described declaratively
  2. The canonical desired system state versioned in Git
  3. Approved changes that can be automatically applied to the system
  4. Software agents to ensure correctness and alert on divergence

Kubernetes is configured declaratively by defining the desired state in manifests and deploying them to a cluster. This can be saved into Git and we have our GitOps repository.

Automatically deployments and monitoring on divergence is harder to reach. We can build our own scripts to do this but there are  existing tools which can handle this for us. One of these tools is Argo CD.

Argo CD

Argo CD describes itself as follows:

Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes.
Argo CD documentation

Argo CD offers the ability to compare and synchronize Kubernetes with GitOps and Helm repositories. It does this based on configuration which is called an Application. An Application in the Argo CD context is the configuration between a GitOps repository and a Kubernetes cluster.

The image below shows an Argo CD Application:

Web UI

We can create this application using the web UI.
The advantage of the web UI is that there is almost no learning curve.

If the GitOps repository requires authentication you need to configure this first.

This can be done by following the steps below:

  1. Open the web UI
  2. Go to the gear icon in the menu bar
  3. Open the repositories configuration
  4. Click on the “Connect repo using SSH/HTTPS” button
  5. Fill in the form with your git configuration and press the connect button.

After this we can create the Application:

  1. Open the UI
  2. Press the New App button
  3. Fill in the form
  4. Synchronize your first Application

Argo CD now starts monitoring the state of the cluster and detects differences. Syncing the Application will deploy these differences. We also have the ability to enable auto syncing. This is a great option for development environments,  and even production environments if the of the GitOps process allows it.

Argo CLI

We can do the same steps with the Argo CD CLI.

The installation manual can be found in the Argo CD documentation.

argocd login argocd.example.com #1 Login to Argo CD with username/password 
argocd repo add https://git.example.com/repos/repo --username git --password secret #2 Add GitOps repository 
argocd app create example --repo https://git.example.com/repos/repo --path . --dest-namespace default --dest-server https://kubernetes.default.svc --directory-recurse #3 Add the application

Declarative API

The declarative API lets us deploy an manifest in the Kubernetes cluster to configure an Application.
The example we used above consists of changes in three  manifests:

  1. A Secret to define the username and password of the GitOps repository
  2. A ConfigMap to define the GitOps repository and reference the secret
  3. A Custom Resource defining the Application

The secret should contain the username and password for the GitOps repository. See the example below.

apiVersion: v1
kind: Secret
metadata:
        name: git-secret
        namespace: argocd
type: opaque
stringData:
  username: git
  password: secret

We can just apply this secret in the same namespace as Argo CD.
The second step is a patch of the Argo CD ConfigMap.

apiVersion: v1 
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
data:
  repositories: |
    – url: https://git.example.com/repos/repo
      passwordSecret:
        name: git-secret
        key: password
      usernameSecret:
        name: git-secret
        key: username

We should patch this, there is already data in this ConfigMap which should be retained. So overwriting the ConfigMap isn’t an option.
The last step is to apply a new Application.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: example-application
  namespace: argocd
spec:
  project: default
  source:
    repoURL: ‘https://git.example.com/repos/repo’
    targetRevision: HEAD
    path: .
  destination:
    server: ‘https://kubernetes.default.svc’
    namespace: ‘default’

What’s next 

We have seen three ways to setup a first application in Argo CD. We can now add Kubernetes manifests into the GitOps repository and start deploying to a cluster.

We can now deploy our complete landscape with Argo CD on Kubernetes. Manual actions on the cluster shouldn’t be necessary anymore and we have a nice audit trail in our GitOps repository.

It works also with other GitOps tools like Sealed Secrets which allows us to store secrets securely within our GitOps repository.