Using kustomize to patch helm charts

Helm is a popular package manager for Kubernetes applications.It bundles Kubernetes manifests for a given application to a set used for deployments. Furthermore, helm providesdependency management as well as a templating engine (go templates with sprig-functions).

Kustomize is a configuration management tool that is used to merge and patch Kubernetes manifests.

Using kustomize to render Helm charts

Using Kustomize to patch Helm charts is only useful if you only use Helm for its dependency management and template capabilities, but notfor its management of the installed Kubernetes manifests itself. A common use case that is covered by this prerequisites would be the usage of Argo-CD.

Kustomize has a built-in plugin that renders helm charts, the usage is rather intuitive:

# kustomization.yaml
helmCharts:
  - releaseName: helm-release-name
    namespace: default
    name: chart-name
    version: chart-version
    repo: repo-url
    valuesInline: {}

Patch helm charts after creation

An exemplary use case for this is that a Helm chart produces some Secrets from input values, but it is preferred to have thesesecrets in a Secret Manager and just reference them using External Secrets.

So we have to remove the secrets produced by the helm chart (their actual values are just useless dummy values at this point) and replace themwith ExternalSecrets. The kustomization.yaml looks like this:

# kustomization.yaml
patchesStrategicMerge:
  - secret-rm.yaml

resources:
  - secret.yaml

helmCharts: [...]

The secret-rm.yaml removes the secret from the Helm output using the delete-directive:

# secret-rm.yaml
$patch: delete
apiVersion: v1
kind: Secret
metadata:
  name: db-password
  namespace: default

The secret.yaml part then just creates an ExternalSecret as replacement that fetches the Secret from the Secret Manager:

# secret.yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: db-password
  namespace: default
spec:
  refreshInterval: 1h
  secretStoreRef:
    kind: ClusterSecretStore
    name: gcpsm # has to be defined separately
  target:
    name: db-password
    creationPolicy: Owner
  data:
    - secretKey: password
      remoteRef:
        key: db_password