Skip to main content
When you scaffold a project with Kubebuilder, the generated code feels like a set of labeled drawers: some drawers hold the API shape, others contain the reconciliation/controller logic, and a few contain the Kubernetes YAML used for deployment and testing. This guide walks the project top-to-bottom so you know which file to open when you want to change a specific aspect of the operator.

Project blueprint — config/project-config.yaml

Open config/project-config.yaml. This file is the project blueprint that records domain, repo path, project name, layout, and the API resources Kubebuilder added. Typically you do not edit this file by hand because Kubebuilder updates it when you add APIs or webhooks.
Quick field reference:

API shape — api/v1/webapp_types.go

Open api/v1/webapp_types.go. This drawer defines the API surface for your custom resource.
  • WebAppSpec represents the user-requested (desired) state.
  • WebAppStatus represents the operator-reported (observed) state.
The scaffold includes a placeholder Foo field as an example. In the next implementation steps, replace it with fields such as image and replicas. The controller will then create child resources (Deployment, Service, ConfigMap, etc.) using either defaults or values from the spec. Markers beginning with +kubebuilder: are directives for controller-gen and other code generators. They generate CRD YAML, print columns, status subresource support, and validation rules. Generated files such as zz_generated.deepcopy.go live next to these types — do not edit generated files manually; use make generate instead.

Reconciliation logic — internal/controller/webapp_controller.go

Open internal/controller/webapp_controller.go. This is the controller/reconciler drawer — the place to implement operator behavior. The Reconcile function is the reconciliation loop that Kubernetes calls whenever a WebApp object (or an owned object) changes. In your implementation, the reconciler should:
  1. Read the WebApp instance from the API server.
  2. Compare the requested state (Spec) with the current cluster state.
  3. Create, update, or delete child resources (Deployment, Service, ConfigMap, etc.) to converge to the desired state.
  4. Update WebApp.Status with observed conditions and requeue as required.
The scaffolded Reconcile currently returns with no work done — implement the steps above and manage errors/requeue behavior as appropriate.
At the top of this file you will also find RBAC markers that generate Role and RoleBinding manifests. Keep them current as you add more owned resource kinds (e.g., Deployments, Services).

Manager and wiring — cmd/main.go

Open cmd/main.go. This file wires the manager process that runs the controller(s). The manager owns the shared client, cache, metrics endpoint, webhook server, health/readiness probes, leader election, and controller registration. You typically modify this file only when adding new controllers, changing leader election, or altering probe/metrics settings. Example: creating the manager instance.
Wiring the reconciler into the manager:

Deployment YAML — config/

The config/ directory holds Kubernetes manifests used for deploying and testing the operator:
  • config/crd/ — generated CRD YAML for your APIs.
  • config/rbac/ — generated RBAC manifests derived from +kubebuilder:rbac markers.
  • config/manager/ — the operator Deployment manifest and related files.
  • config/default/ — kustomize overlay tying deployment pieces together for make deploy.
  • config/samples/ — example WebApp CR instances for testing.
Example manifests (Namespace + controller Deployment):

Development tasks — Makefile

Open the Makefile. It contains standard targets for day-to-day work: generating code, building images, running locally, and deploying. Key variables and snippet:
Important targets to remember:
  • make generate — refreshes generated Go code (DeepCopy methods, etc.).
  • make manifests — regenerates CRDs and RBAC YAML via controller-gen.
  • make run — runs the operator locally against your kubeconfig.
  • make deploy — builds and applies manifests to the cluster (kustomize overlay sets the image).
Example targets:
Uninstall/undeploy helpers:
Keep generated and scaffolded files in mind: update +kubebuilder:rbac markers and your api types as you add real resources. Use make generate and make manifests to refresh generated code and YAML so the on-disk artifacts match your source.

Quick lookup — where to change what

Once you have this map, the generated project becomes a set of predictable drawers rather than a wall of files. Next, use this map to implement the reconciliation logic that ensures WebApp instances are translated into the proper cluster resources.

Watch Video