k8s-crd-from-typed-schema
Installation
SKILL.md
k8s CRDs from a typed schema
Generating CRDs from typed schemas (zod / TypeBox / Valibot / hand-written JSON Schema) looks straightforward — convert to OpenAPI v3, embed as openAPIV3Schema, done. It isn't. CRDs use a subset of OpenAPI v3 plus k8s-specific extensions ("Structural Schema"), and several common JSON-Schema features are silently incompatible. Plus there are two non-schema gotchas (status subresource, metadata prohibition) that don't show up until you try to use the CRD.
This skill is the punch list of what to fix before kubectl apply -f crd.yaml succeeds and the operator actually works.
When to use
- Building an operator / controller and writing your own CRDs.
- Generating CRDs from a typed source rather than hand-authoring YAML.
- Hitting
kubectlerrors likeunknown field "$schema"/must not have "oneOf"/must not specify anything other than name and generateName/cannot have both "additionalProperties" and "properties". - Operator works once but then reconciles forever in a loop after the first status write.
Workflow
1. Convert typed schema → JSON Schema (OpenAPI v3 dialect)
For zod: