YokeCD alpha

GitOps: Yoke & ArgoCD

The Yoke CLI is analogous to the Helm CLI. It is a client-side tool that communicates with your cluster and keeps track of packages deployed to it. However, for many, that is not how we deploy packages anymore. Where the words Platform Engineering are uttered, GitOps is sure to follow.

To that end, we want to be able to write our Flights (programs that encapsulate a set of kubernetes packages as code) and have a continuous deployment tool, such as ArgoCD, manage our resources for us. Out of the box, ArgoCD supports Helm, Jsonnet, and Kustomize. To support more use cases, it accepts extensions via config management plugins .

YokeCD is the official yoke config management plugin for ArgoCD. It allows you to write ArgoCD Applications but have their source evaluated by yoke's embedded wasm interpreter (wazero). The yokecd plugin supports a variety of setups:

Introducing YokeCD

To be compatible with ArgoCD, Yoke offers an ArgoCD CPM Sidecar Docker image hosted at DockerHub - davidmdm/yokecd .

Installing YokeCD Sidecar

Fresh ArgoCD Installation

The yoke project maintains a Flight that wraps the ArgoCD Chart v6.17.2 . Any input passed to the flight via stdin is directly passed to the ArgoCD Chart. Additionally the Flight installs the sidecar on the argocd-repo-server making the yokecd plugin available to argocd applications.

    yoke takeoff --namespace argocd yokecd https://github.com/davidmdm/yoke/releases/download/yokecd-installer%2Fv0.0.2/yokecd-installer.wasm.gz
  

Patch an Existing ArgoCD Installation

If you already have an existing ArgoCD installating you must patch the argocd-repo-server with the yokecd sidecar image. To do so create the following manifest substituting any names to match your deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: YOUR-ARGOCD-REPO-SERVER-NAME    # typically "argocd-repo-server", possibly with a prefix if installed via helm.
  namespace: YOUR-ARGOCD-NAMESPACE-NAME # typically "argocd"
spec:
  template:
    spec:
      containers:
        - name: yokecd
          image: davidmdm/yokecd:latest
          imagePullPolicy: IfNotPresent # use the imagePullPolicy that best fits your needs.
          command:
            - /var/run/argocd/argocd-cmp-server
          securityContext: # required by argocd cmp spec. Must be user 999.
            runAsNonRoot: true
            runAsUser: 999
          volumeMounts:
            - name: var-files
              mountPath: /var/run/argocd
            - name: plugins
              mountPath: /home/argocd/cmp-server/plugins
            - name: cmp-tmp
              mountPath: /tmp
      volumes:
        - name: cmp-tmp
          emptyDir: {}

Once your file is created, let's call it `patch.yaml`, we can now proceed to patch the existing argocd deployment. We will assumed in the following command that the argocd repo server deployment has name argocd-repo-server as per the standard installation. If this is not the case for your installation please substitute the name accordingly. We will also assume that ArgoCD is deployed in a namespace named argocd , if this is not the case please substitute accordingly once more.

kubectl patch deployments/argocd-repo-server --namespace=argocd --patch-file=patch.yaml

Creating YokeCD Applications

YokeCD applications are normal ArgoCD Applications that use the yokecd plugin.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: example
  namespace: argocd
spec:
  project: default
  source:
    plugin:
      name: yokecd
# ... and all other required fields

Parameters

In order to use and configure the plugin, we must pass parameters to it. The following parameters are supported:

Parameter
Type
Description
wasm
string
The url to download or the relative location in the source repository to the Flight's wasm asset. Cannot be used when parameter build is enabled.
build
string
A boolean string signalling that the wasm should be compiled on the fly by yokecd using the Go Toolchain in the context of the Application's source. Cannot be used with parameter wasm
input
string
The input that will be passed as stdin to the wasm executable upon execution
args
[]string
The args that will be passed to the Flight Executable upon execution

One of build or wasm must be specified.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: pg
  namespace: argocd
spec:
  project: default

  source:
    repoURL: https://github.com/davidmdm/yokecd-demo
    path: ./cmd/pg
    targetRevision: main

    plugin:
      name: yokecd
      parameters:
        # Will use the asset found at https://github.com/davidmdm/yokecd-demo/cmd/pg/main.wasm.gz
        # at revision main.
        #
        # This parameter cannot be used at the same time as "build"
        - name: wasm
          string: main.wasm.gz # Alternatively can be a url for example:
                               # https://github.com/org/repo/releases/downloads/v1.0.0/main.wasm
                               # If this is the case the application's source is not used.

        # Will build the wasm executable using the Go Toolchain with the source specified by the application.
        # The source must be a Go Module or inside a Go module.
        #
        # This parameter cannot be used at the same time as "wasm"
        - name: build
          string: 'true'

        - name: args
          array: ["--key=value", "positional-arg"]

        - name: input
          string: 'any-input-you-want'

  destination:
    name: in-cluster
    namespace: default

  syncPolicy:
    automated:
      prune: true
      selfHeal: true

YokeCD Service Catalog

When using ArgoCD, it is common to use the app of apps pattern, and have a root application watch a repository for more applications. Any repository that contains Flight programs can deploy them with ArgoCD via the yokecd plugin .

The following is an example structure of a service catalog with two releases: alpha and beta. Both releases are described as Go programs and contain an ArgoCD Application manifest that would use the yokecd plugin with build parameter .

services
├── alpha
│   ├── app.yaml
│   └── main.go
├── beta
│   ├── app.yaml
│   └── main.go
├── go.mod
└── go.sum

Other setups are possible, and any service repository can be mixed and matched with regular ArgoCD Applications.