You may wonder what the heck is helmfile? Well, I would say what is docker-compose to Docker, this is helmfile to Helm. Basically, it allows us to install the whole stack of applications to our Kubernetes cluster in a declarative way.

And you may also wonder why is cert-manager so special? I would say cert-manager itself is not that special Helm chart, but it contains CRD's which may be installed either by using value installCRDs=true or by installing them using kubectl apply before you install the chart.

Using the first option is straight forward, but this is not the recommended way by the documentation. I am not sure why, but I found out that helmfile sync becomes really unresponsive when resyncing, at least on kind cluster.

The second way is tricky to do via helmfile, but also reapplying the CRD's via kubectl apply makes kind unresponsive. Real cluster may behave differently for performance reasons, but can me make this universally functional? Thanks to helmfile events we can achieve this.

Here is a helmfile snippet which installs the chart:

releases:
- name: cert-manager
  chart: jetstack/cert-manager
  version: v0.16.0
  namespace: cert-manager
  wait: true
  hooks:
  - events: ["presync"]
    command: cert-manager-crds.sh

And here is the cert-manager-crds.sh script:

#!/usr/bin/env sh
set -u

kubectl get crd issuers.cert-manager.io > /dev/null 2>&1

if [ $? -ne 0 ]
then
  kubectl apply --validate=false -f cert-manager.crds.yaml
fi

This script first checks if CRD's are already installed and it continues execution just in case they are not. This way we avoid reapplying the manifest(s) that are already applied. The downside of this approach is that we have to update the CRD's manually once we bump the pinned version of the chart, actually cert-manager in this case.

The same approach may be applied to any chart having CRD's.