Working with Custom Resource Definitions
1. Understanding CRD Handling
Method Behavior
crds/ directoryInstalled once before templates; not templated, not upgraded, not deleted
templates/ with hooksUse pre-install/pre-upgrade + helm.sh/resource-policy: keep for upgrade support
2. Installing CRDs with Charts
Flag Effect
Default CRDs in crds/ installed automatically
--skip-crdsSkip CRD installation (assumes pre-installed)
3. Creating CRD Templates
Example: crds/myresource.yaml (NOT templated)
apiVersion : apiextensions.k8s.io/v1
kind : CustomResourceDefinition
metadata :
name : myresources.example.com
spec :
group : example.com
scope : Namespaced
names :
plural : myresources
singular : myresource
kind : MyResource
versions :
- name : v1
served : true
storage : true
schema :
openAPIV3Schema :
type : object
properties :
spec :
type : object
4. Managing CRD Versions
Strategy Detail
Separate chart Manage CRDs in a chart consumed by app charts
Multiple versions storage: true on exactly one version; others served: true for compatibility
Conversion webhooks Required when promoting storage version
5. Handling CRD Upgrades
Warning: CRDs in crds/ are NEVER upgraded by Helm. For evolving CRDs, place them in templates/ with helm.sh/resource-policy: keep and pre-upgrade hooks.
Method Workflow
Templated CRDs Allow updates; risk of breaking running CRs
Hook-managed pre-install,pre-upgrade hook applies CRDs first
Manual Apply CRDs via kubectl outside chart, install with --skip-crds
6. Avoiding CRD Deletion on Uninstall
Annotation Effect
helm.sh/resource-policy: keepRetains resource on helm uninstall
CRDs in crds/ Always retained (Helm never deletes)
7. Validating CRD Schemas
Tool Use
kubeconform --strictValidate CRs against CRD schemas
kubectl apply --dry-run=serverLive admission validation
CEL validation rules Inline schema with x-kubernetes-validations
8. Using CRDs with Operators
Example: Operator chart layout
operator-chart/
├── Chart.yaml
├── crds/ # CRDs installed first
│ └── myresource.yaml
├── templates/
│ ├── deployment.yaml # Operator pod
│ ├── rbac.yaml
│ └── examples/ # Sample CRs (optional)
└── values.yaml
9. Testing CRD Installation
Example: Verify CRD post-install
helm install op ./chart
kubectl get crd myresources.example.com
kubectl explain MyResource.spec
10. Troubleshooting CRD Issues
Issue Fix
CRD missing during template install CRDs install before templates — check timing if using webhooks
CRD not upgraded Helm crds/ never updates; use kubectl apply -f crds/ manually
Stuck on uninstall CRs reference CRD; delete CRs first or set finalizer policy
Schema validation fails Run kubectl get crd ... -o yaml + check openAPIV3Schema