kubebuilder-api-design

Use when authoring or modifying Kubebuilder Go API types and +kubebuilder markers so generation (`make generate`/`make manifests`) emits the intended CRD schema (validation/defaults, required/optional, list semantics, printer columns, subresources), or when asked which marker/type to use.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "kubebuilder-api-design" with this command: npx skills add configbutler/skills/configbutler-skills-kubebuilder-api-design

Kubebuilder API Design (Go)

Design Kubernetes APIs with Kubebuilder in Go (primarily for Kubernetes operators): CRD type definitions, schema markers, status/conditions, and the core scaffold/regenerate workflow.

Default scope: API design + CRD generation. Do not implement controller/webhook business logic unless explicitly requested.

Tooling assumptions (what needs to exist for generation)

This skill can help with pure API design (Go types + markers) without running anything, but to scaffold and to regenerate CRDs/manifests the user’s environment/project typically needs:

  • go toolchain (matching the project’s go.mod requirements)
  • kubebuilder CLI (or Operator SDK if they wrap Kubebuilder)
  • make (Kubebuilder projects drive generation via Makefile)

Notes:

  • controller-gen is usually installed automatically by the project’s Makefile target(s) (pinned version), so it’s not always a separate prerequisite.
  • Cluster tooling (kubectl, kind, etc.) is only needed if they want to run/test against a cluster; keep this out of scope unless explicitly requested.

Relationship to k8s-crd-design-review

Treat the generated CRD YAML as the compiled API contract. After shaping Go types + markers and running generation, run a design review on the generated CRD YAML (or diff) using ../k8s-crd-design-review/SKILL.md.

SSA / GitOps note: list semantics are part of the API contract.

Versioning / multi-version CRDs (pointer)

If the user is designing a multi-version API (e.g., v1alpha1v1beta1v1) or needs conversion webhooks:

Designing relations (object references) in Spec/Status

When a CRD needs to point at another Kubernetes object (or one of its fields/keys), treat “references” as API design, not a convenience import.

Prefer well-scoped, API-owned reference types (avoid generic core types)

Avoid embedding generic Kubernetes reference structs like corev1.LocalObjectReference or corev1.ObjectReference in new APIs.

Kubernetes upstream explicitly discourages new uses of corev1.LocalObjectReference and corev1.ObjectReference because it is underspecified and hard to validate/document per usage:

  • Key takeaway: “Instead of using these generic types, create a locally provided and used type that is well-focused on your reference.

This guidance applies equally to other overly-generic reference types you may find in older APIs (they tend to have unclear semantics, inconsistent validation, and awkward defaults).

Pattern: define a dedicated <Thing>Ref type per relationship

Define a small, purpose-built struct for each relationship, tailored to your CRD:

  • Make required fields actually required (don’t mirror upstream backward-compatibility tricks like omitempty + default empty string)
  • Encode the relationship’s real constraints in schema (name format, allowed kinds, namespace rules)
  • Add per-field documentation that matches the domain (so kubectl explain is useful)

Example (same-namespace reference by name):

// ConfigMapRef identifies a ConfigMap in the same namespace.
// The referenced ConfigMap must exist before this resource becomes Ready.
type ConfigMapRef struct {
    // Name is the name of the referenced ConfigMap.
    // +kubebuilder:validation:MinLength=1
    // Consider adding a stricter pattern if you want to enforce DNS-1123 label.
    Name string `json:"name"`
}

Example (namespace + name, if cross-namespace is allowed by design):

// SecretRef identifies a Secret.
// If Namespace is omitted, it defaults to the resource namespace.
type SecretRef struct {
    // +kubebuilder:validation:MinLength=1
    Name string `json:"name"`

    // +optional
    // +kubebuilder:validation:MinLength=1
    Namespace string `json:"namespace,omitempty"`
}

Decide (and document) the reference semantics up front

For each relation, explicitly choose and document:

  • Scope: same-namespace only vs cross-namespace (cross-namespace typically needs extra authorization/guardrails)
  • Identity: name only vs name+namespace vs (rarely) UID/resourceVersion (most APIs should stick to name/namespace)
  • Allowed targets: fixed Kind (recommended) vs “one-of” kinds (if so, model it explicitly)
  • Lifecycle behavior: what happens if the target is missing, renamed, deleted, or recreated
  • Status mirroring: if you surface resolved details (e.g., observed UID), put them in Status not Spec

If the user asks for “a reference to an arbitrary object”, push back and narrow it: require a specific Kind or a small, explicit set of Kinds, then reflect that in the API type.

Workflow

Step 0 — Gather inputs (ask only what’s needed)

  1. API identity: Group, Version, Kind, Plural, Scope (Namespaced vs Cluster)
  2. Desired Spec fields (including which are required) and any immutability expectations
  3. Status needs: conditions? observedGeneration? summary fields?
  4. Any constraints: enum values, ranges, patterns, max items, uniqueness, references to other objects

When the user mentions relations/references, capture:

  • target kind(s) and whether cross-namespace is allowed
  • whether the reference is required
  • whether they need to reference a whole object or a sub-field (e.g., secretKeyRef)
  • expected behavior when the target does not exist or changes

If the user already has YAML for the CRD, treat it as the contract and map it into Go types + markers.

Step 1 — Draft the Go API types

Create:

  • type <Kind>Spec struct { ... }
  • type <Kind>Status struct { ... }
  • type <Kind> struct { metav1.TypeMeta; metav1.ObjectMeta; Spec; Status }
  • type <Kind>List struct { metav1.TypeMeta; metav1.ListMeta; Items []<Kind> }

Rules of thumb:

  • Use pointers for optional scalars and optional structs to preserve “unset vs zero”.
  • Prefer Kubernetes-native types when relevant (metav1.Time, resource.Quantity, intstr.IntOrString).
  • Keep Status separate from Spec. Include ObservedGeneration and Conditions when useful.
  • For relations, prefer API-owned <Thing>Ref structs over embedding generic Kubernetes reference types (see “Designing relations”).

Read ./references/go-type-patterns.md for common Go/Kubernetes type choices.

Step 2 — Add Kubebuilder markers (validation, defaults, printing)

Add markers to match the desired API contract:

  • Root + subresources:
    • +kubebuilder:object:root=true
    • +kubebuilder:subresource:status
  • Validation + defaults on fields (min/max, pattern, enum, length, items, etc.)
  • List semantics for SSA and correctness (listType=set|map, listMapKey=...)
  • Printer columns that reflect the most important status/spec at a glance

Read ./references/kubebuilder-markers.md.

For a compact “what marker do I need?” cheat-sheet (root markers, field validation/defaults, list semantics, and printer columns), see ./references/api_reference.md.

Step 3 — Shape Status + Conditions

Prefer []metav1.Condition unless you have a strong reason to roll your own condition type. Include helper summary fields only if they serve UX.

Read ./references/status-and-conditions.md (Kubebuilder/Go implementation appendix). For canonical conceptual semantics and review heuristics, defer to k8s-crd-design-review/references/conditions-and-status.md.

Step 3.5 — Kubebuilder workflow essentials (scaffolding + generation)

When the user needs help with Kubebuilder scaffolding and regeneration steps (but not controller/webhook business logic), follow the short checklist in ./references/kubebuilder-workflow-essentials.md.

Step 4 — Provide a “generate + verify” checklist (don’t implement)

Give the user the standard Kubebuilder steps to regenerate CRDs and verify the schema, without writing controller logic:

  • Run make generate / make manifests
  • Inspect the generated CRD YAML and confirm:
    • required fields match expectations
    • defaults appear where intended
    • list semantics and map keys are correct
    • printer columns render

Then (recommended): run a contract review pass against the generated CRD YAML (or diff) using ../k8s-crd-design-review/SKILL.md, focusing on compatibility/migration impact, lifecycle/status semantics, and SSA/GitOps ergonomics.

When the user needs more API-shape guidance, point them to the offical long read of the Kubernetes API conventions.

Output format

When delivering code, output a single Go snippet per file:

  1. package + imports
  2. markers
  3. Spec, Status
  4. root object + list
  5. any type aliases and nested structs

Use concise comments. Put rationale (why a pointer, why listType map, etc.) in short bullet notes after the code.

Resources

Kubebuilder book (upstream docs mirror in this repo)

If you need canonical Kubebuilder explanations (beyond this skill’s cheat-sheets), prefer these pages:

references/

Load these only when needed (to keep context small):


This skill currently only bundles references/. Add scripts/ or assets/ later if you want automation helpers or boilerplate templates.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

k8s-crd-design-review

No summary provided by upstream source.

Repository SourceNeeds Review
General

Find Skills for ClawHub

Search for and discover OpenClaw skills from ClawHub (the official skill registry). Activate when user asks about finding skills, installing skills, or wants...

Registry SourceRecently Updated
2771Profile unavailable
General

Skill Listing Polisher

Improve a skill's public listing before publish. Use when tightening title, description, tags, changelog, and scan-friendly packaging so the listing looks cl...

Registry SourceRecently Updated
1130Profile unavailable
General

Skill Priority Setup

Scans installed skills, suggests L0-L3 priority tiers, and auto-configures skill injection policy. Use when: setting up skill priorities, optimizing token bu...

Registry SourceRecently Updated
2500Profile unavailable