Patching and Extending Helm Resources With Kustomize

Helm deployments are a great way to manage Kubernetes resources, but sometimes you need to customize or extend the resources that Helm generates. In this post, we’ll look at how you can use Kustomize to patch and extend Helm resources.

What is Kustomize?

Kustomize is a tool for customizing Kubernetes resources. It allows you to define a set of patches that can be applied to existing resources, and it provides a way to extend resources with additional configurations.

Example Scenario

When you deploy a Helm chart, it generates a set of Kubernetes resources based on the templates defined in the chart. If you need to make changes to these resources, you can use Kustomize to apply patches.

For example, let’s say you have a Helm chart that deploys a Deployment resource with the following configuration:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  replicas: 3
  # -- snip --

If you want to change the number of replicas to 5, you can create a patch file like this:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  replicas: 5

Generating Helm Manifests with Kustomize

How do you make sure that this patch is applied to the Deployment resource generated by the Helm chart? You can use Kustomize act as the generator for the Helm chart and apply the patch to the generated resources. That means that Kustomize will download the Helm chart into plain YAML files and patch them. Then, you can apply the patched resources to your cluster.

Start by creating a kustomization.yaml file. Here is an example of a Bitnami Airflow deployment:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: airflow
helmCharts:
  - name: airflow
    repo: https://charts.bitnami.com/bitnami
    releaseName: my-airflow
    namespace: airflow
    version: 17.2.4
    valuesFile: values.yml

Currently, this file only specifies the Helm chart to use and the values file to apply. No patches or additional resources are defined yet.

To generate the resources from the Helm chart, run the following command:

kustomize build --enable-helm

This tells Kustomize to download the Helm chart, generate the resources, and output them as plain YAML files. You can then apply these resources to your cluster.

Applying Patches with Kustomize

Now that we’ve established that Kustomize can generate resources from a Helm chart, let’s look at how you can apply patches to these resources.

Create a patch file (patch.yaml) that changes the number of replicas in the Deployment resource (note that I’m using my-airflow just as an example of a resource, you should replace it with the actual name of the resource you want to patch):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-airflow
spec:
  replicas: 5

Next, add the patch to the kustomization.yaml file, so it looks like this:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: airflow
helmCharts:
  - name: airflow
    repo: https://charts.bitnami.com/bitnami
    releaseName: my-airflow
    namespace: airflow
    version: 17.2.4
    valuesFile: values.yml
patches:
  - path: patch.yaml

Now, when you run kustomize build --enable-helm, the patch will be applied to the resources generated by the Helm chart.

Extending with Kustomize

In addition to patching resources, you can treat the kustomization.yaml as you would normally, where you can treat it as a base and apply additional overlays, add more resources on top of the generated ones, add annotations, etc.

Usage with Argo CD & GitOps

If you’re using Argo CD for GitOps, you can use kustomize with the --enable-helm flag to enable Kustomize to generate Helm manifests.

We are currently using Argo CD Vault Plugin to deploy resources, so I modified our ConfigManagementPlugin to look like this:

apiVersion: argoproj.io/v1alpha1
kind: ConfigManagementPlugin
metadata:
  name: argocd-vault-plugin-kustomize
spec:
  allowConcurrency: true

  # Note: this command is run _before_ anything is done, therefore the logic is to check
  # if this looks like a Kustomize bundle
  discover:
  find:
    command:
      - find
      - .
      - -name
      - kustomization.yaml
  generate:
  command:
    - sh
    - -c
    - 'kustomize build --enable-helm . | argocd-vault-plugin generate -s vault-configuration -'
  lockRepo: false

But depending on your setup, you might need to adjust this to fit your needs, or create a similar plugin yourself.

I’ve also read that patching the argocd-cm ConfigMap resource and adding kustomize.buildOptions: --enable-helm might work, but I haven’t tested it myself since we are using the above plugin for building the manifests.