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.
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!
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:
plugin.yaml
file as long as it can be found under: /home/argocd/cmp-server/config/
plugin.yaml
in the container using the configmap I just created./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:
helmfile.yaml
in it. You can view it on GitHub.CreateNamespace
option since I’m using helm and none of the helm charts I’m using provides the namespace.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.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.
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
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
GitOps is rapidly becoming the standard for managing cloud-native ecosystems with Kubernetes. Traditional IaC tools fell short with the rise of Kubernetes…...
October 19, 2023Kargo is a next-generation continuous delivery and application lifecycle orchestration platform for Kubernetes. It builds upon GitOps principles and integrates...
October 10, 2023GitOps principles exist to address the genuine problems of visibility and collaboration when working with a complex system like Kubernetes. They stress the…...