Skip to content

Add Helm hook to automatically upgrade CRDs during chart upgrades #2311

@JAORMX

Description

@JAORMX

Problem

When upgrading the toolhive-operator-crds Helm chart, CRDs are not automatically updated due to Helm's default behavior. This means users must manually apply CRD updates using kubectl, which is:

  1. Not intuitive for users expecting helm upgrade to work
  2. Easy to miss, leading to confusion when new CRD fields are available in the chart but not in the cluster
  3. Inconsistent with the upgrade experience

Current Workaround

Users must manually update CRDs after upgrading:

kubectl apply -f <path-to-crds>

Note: Do NOT use kubectl replace --force as it will delete and recreate the CRD, destroying all existing custom resources in the process.

Proposed Solution

Add a Helm pre-upgrade hook to the toolhive-operator-crds chart that automatically applies CRD updates during chart upgrades. This can be implemented using a Job that runs kubectl apply on the CRDs.

Example implementation:

apiVersion: batch/v1
kind: Job
metadata:
  name: {{ include "toolhive-operator-crds.fullname" . }}-upgrade-crds
  annotations:
    "helm.sh/hook": pre-upgrade
    "helm.sh/hook-weight": "-5"
    "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
spec:
  template:
    spec:
      serviceAccountName: {{ include "toolhive-operator-crds.fullname" . }}-upgrade
      restartPolicy: Never
      containers:
      - name: upgrade-crds
        image: bitnami/kubectl:latest
        command:
        - /bin/sh
        - -c
        - |
          kubectl apply -f /crds/
        volumeMounts:
        - name: crds
          mountPath: /crds
      volumes:
      - name: crds
        configMap:
          name: {{ include "toolhive-operator-crds.fullname" . }}-files

Important: The hook must use kubectl apply (not kubectl replace --force) to safely merge CRD updates without deleting existing resources.

Benefits

  1. Better UX: helm upgrade will "just work" as users expect
  2. Prevents issues: Ensures CRDs are always in sync with the chart version
  3. Prevents data loss: Using kubectl apply safely updates CRDs without deleting custom resources
  4. Consistency: Aligns with how many other operator charts handle CRD upgrades (e.g., cert-manager, prometheus-operator)

References

Alternative Considered

Document the manual upgrade process clearly in the chart README - but this is a poor UX compared to automatic upgrades.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions