Config Management Plugins with Argo CD

Config Management Plugins with Argo CD blog cover image

Argo CD has the ability to work with Config Management tools like Helm and Kustomize natively. However there are other configuration management tools out there that are starting to become quite popular. CUE, YTT, and Tanka for example. If a user wants to use any other configuration management tool, they can do so by using Config Management Plugins (or CMPs). With CMPs, Argo CD users have the ability to integrate any configuration management tools for their GitOps deployments.

I went over a Config Management Plugin Crash Course in my last video where I outline how CMPs work and how it can be used. Be sure to check it out!

Also, be sure to check out our free course on GitOps and Continuous Delivery. Developed by the founders of the Argo Project, this course offers hands-on experience in implementing these practices with Argo CD.

In this blog, I’d like to expand on the video and go over a real world use case of using CMPs - Helmfile.

What is Helmfile?

Helmfile, is a declarative way for deploying Helm charts. Some of the advantages of using Helmfile is that it lets you keep and maintain changes of your Helm releases in version control, apply CI/CD to configuration changes, and the ability to sync to avoid drift in your environments. A basic example looks like this:

repositories:
 - name: prometheus-community
   url: https://prometheus-community.github.io/helm-charts

releases:
- name: prom-norbac-ubuntu
  namespace: prometheus
  chart: prometheus-community/prometheus
  set:
  - name: rbac.create
    value: false

You can set any number of repositories and any number of releases based on the repositories. An end user can then maintain the Helmfile in Git and sync it to the target cluster using: helmfile sync

This makes it perfect for GitOps! So let’s dive right into an example!

Using Helmfile in Argo CD

The first step is to create a ConfigMap of your CMP configuration. We will be focusing on the "sidecar" method as it will be the only supported method moving forward with Argo CD.

NOTE: While the ConfigManagementPlugin looks like a Kubernetes object, it is not actually a custom resource. It’s just something that Argo CD "understands".

apiVersion: v1
kind: ConfigMap
metadata:
  name: cmp-helmfile
  namespace: argocd
data:
  plugin.yaml: |
    apiVersion: argoproj.io/v1alpha1
    kind: ConfigManagementPlugin
    metadata:
      name: cmp-helmfile
    spec:
      version: v1.0
      init:
        command: [sh, -c, 'echo "Initializing..."']
      generate:
        command: [sh, -c]
        args: ["helmfile template --quiet --namespace $ARGOCD_APP_NAMESPACE"]
      discover:
        fileName: "helmfile.yaml"

There are a few sections under the spec that are needed for this example:

  • init - The init step always runs before the generate section. This could be used to do things like download the necessary binaries or any other dependency handling.
  • generate - The generate step is where the magic happens. This step runs in the Argo CD Application source directory. Here is where you can do, basically, whatever you need! The only requirement is that the output MUST be a valid Kubernetes object; and the output must go to stdout. In this example I’m running helmfile template and specifying the Argo CD Application target namespace. You can read more about what env vars are available to you in the official Argo CD Build Environment documentation page. You can find more examples of using the build environment in one of our past blog posts "Argo CD Build Environment Examples".
  • discover - The discover section is a flag to indicate if the sidecar for your CMP needs to run. In this case we’re looking for a file named helmfile.yaml.

Once you’ve created the ConfigMap, you can apply it to the cluster:

kubectl apply -n argocd -f cmp-configmap.yaml

Next step is to patch the Argo CD Repo Controller Deployment to include your sidecar. Create the patch file for this example:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: argocd-repo-server
  namespace: argocd
spec:
  template:
    spec:
      containers:
        - name: cmp
          securityContext:
            runAsNonRoot: true
            runAsUser: 999
          image: quay.io/christianh814/helmfile:v0.155.1
          imagePullPolicy: IfNotPresent
          command: [/var/run/argocd/argocd-cmp-server]
          volumeMounts:
            - mountPath: /var/run/argocd
              name: var-files
            - mountPath: /home/argocd/cmp-server/plugins
              name: plugins
            - mountPath: /home/argocd/cmp-server/config/plugin.yaml
              subPath: plugin.yaml
              name: cmp-helmfile
            - mountPath: /tmp
              name: cmp-tmp
      volumes:
        - name: cmp-helmfile
          configMap:
            name: cmp-helmfile
        - emptyDir: {}
          name: cmp-tmp

There are some important things to keep in mind here:

  • The sidecar container needs to run as user 999 in order to be able to read the files in the cloned repository.
  • Use an image that you’ve built that has the tools you need or use one that is known to have the tools. You can also "bake in" your plugin.yaml file as long as it can be found under: /home/argocd/cmp-server/config/
  • In my case, I’m just mounting the plugin.yaml in the container using the configmap I just created.
  • Other mounts from Argo CD are important like /var/run/argocd (that contains the argocd-cmp-server command that needs to run) and /home/argocd/cmp-server/plugins.

Once you have this patch file set, apply it to Argo CD by patching the argocd-repo-server Deployment.

kubectl -n argocd patch deployments/argocd-repo-server --patch-file manifests/argocd-repo-server-patch.yaml

This will trigger a restart of the Deployment. Make sure it’s done updating before you proceed.

kubectl rollout status -n argocd deployments/argocd-repo-server

Now, you can set up your Argo CD Application and point to a repo with a helmfile.yaml file.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: helmfile-demo
  namespace: argocd
spec:
  destination:
    name: in-cluster
    namespace: demo
  project: default
  source:
    path: helm/helmfile/demo/manifest
    repoURL: https://github.com/akuity/examples
    targetRevision: main
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

If you’re used to Argo CD, this should look familiar because it’s just a "standard" Argo CD Application! Just a couple of things to note:

  • My repo path points to a directory with a helmfile.yaml in it. You can view it on GitHub.
  • I’m setting the CreateNamespace option since I’m using helm and none of the helm charts I’m using provides the namespace.
  • Note the destination section, I’m deploying to in-cluster (which is the same cluster that Argo CD is running on). You might have to change it for your environment.
  • Note that the destination namespace is referenced in the plugin.yaml as $ARGOCD_APP_NAMESPACE

Success! The CMP recognized the helmfile.yaml in the repo (using the discover section) and ran the commands in the generate section to render out the YAML and Argo CD applied that YAML to the destination cluster.

Deployed HelmFile Application.
Deployed HelmFile Application.

You can see that Argo CD deployed the Application into the namespace we've set.

$ kubectl -n argocd get applications
NAME            SYNC STATUS   HEALTH STATUS
helmfile-demo   Synced        Healthy
$ kubectl get pods -n demo
NAME                                 READY   STATUS    RESTARTS   AGE
jupiter-simple-go-749cd6c7f8-5n4rk   1/1     Running   0          90s
jupiter-simple-go-749cd6c7f8-96rx4   1/1     Running   0          90s
saturn-gobg-9c4bdfff5-295b4          1/1     Running   0          90s

An Easier Way

The Akuity Platform, the premiere way of managing Argo CD, makes it easy to install and manage ConfigManagement Plugins with its CMP setup wizard. That’s not all - users can take advantage of pre-built CMPs which can be used to quickly get started.

Check out my video on Akuity’s CMP setup wizard, and be sure to try it out by signing up for a free trial by visiting https://akuity.io/signup

Share this blog:

Latest Blog Posts

What's New in Kargo v0.5.0

What's New in Kargo v0.5.0

We're back from Kubecon EU '24 in Paris, and there was a lot of buzz around Kargo! We had many conversations with folks talking about their struggles with how…...

Argo CD CDK8S Config Management Plugin

Argo CD CDK8S Config Management Plugin

If you haven't stored raw kubernetes YAML files in your GitOps repository, you most probably used some sort of tooling that generates YAML files, for example…...

Application Dependencies with Argo CD

Application Dependencies with Argo CD

With Argo CD and GitOps gaining wide adoption, many organizations are starting to deploy more and more applications using Argo CD and GitOps in their workflows…...

Leverage the industry-leading suite

Contact our team to learn more about Akuity Cloud