Scaffold

The +kubebuilder:scaffold marker is a key part of the Kubebuilder scaffolding system. It marks locations in generated files where additional code will be injected as new resources (such as controllers, webhooks, or APIs) are scaffolded. This enables Kubebuilder to seamlessly integrate newly generated components into the project without affecting user-defined code.

How It Works

When you scaffold a new resource using the Kubebuilder CLI (e.g., kubebuilder create api), the CLI identifies +kubebuilder:scaffold markers in key locations and uses them as placeholders to insert the required imports and registration code.

Example Usage in main.go

Here is how the +kubebuilder:scaffold marker is used in a typical main.go file. To illustrate how it works, consider the following command to create a new API:

kubebuilder create api --group crew --version v1 --kind Admiral --controller=true --resource=true

To Add New Imports

The +kubebuilder:scaffold:imports marker allows the Kubebuilder CLI to inject additional imports, such as for new controllers or webhooks. When we create a new API, the CLI automatically adds the required import paths in this section.

For example, after creating the Admiral API in a single-group layout, the CLI will add crewv1 "<repo-path>/api/v1" to the imports:

import (
    "crypto/tls"
    "flag"
    "os"

    // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
    // to ensure that exec-entrypoint and run can make use of them.
    _ "k8s.io/client-go/plugin/pkg/client/auth"
    ...
    crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4/api/v1"
    // +kubebuilder:scaffold:imports
)

To Register a New Scheme

The +kubebuilder:scaffold:scheme marker is used to register newly created API versions with the runtime scheme, ensuring the API types are recognized by the manager.

For example, after creating the Admiral API, the CLI will inject the following code into the init() function to register the scheme:

func init() {
    ...
    utilruntime.Must(crewv1.AddToScheme(scheme))
    // +kubebuilder:scaffold:scheme
}

To Set Up a Controller

When we create a new controller (e.g., for Admiral), the Kubebuilder CLI injects the controller setup code into the manager using the +kubebuilder:scaffold:builder marker. This marker indicates where the setup code for new controllers should be added.

For example, after creating the AdmiralReconciler, the CLI will add the following code to register the controller with the manager:

if err = (&crewv1.AdmiralReconciler{
    Client: mgr.GetClient(),
    Scheme: mgr.GetScheme(),
}).SetupWithManager(mgr); err != nil {
    setupLog.Error(err, "unable to create controller", "controller", "Admiral")
    os.Exit(1)
}
// +kubebuilder:scaffold:builder

The +kubebuilder:scaffold:builder marker ensures that newly scaffolded controllers are properly registered with the manager, so that the controller can reconcile the resource.

List of +kubebuilder:scaffold Markers

MarkerUsual LocationFunction
+kubebuilder:scaffold:importsmain.goMarks where imports for new controllers, webhooks, or APIs should be injected.
+kubebuilder:scaffold:schemeinit() in main.goUsed to add API versions to the scheme for runtime.
+kubebuilder:scaffold:buildermain.goMarks where new controllers should be registered with the manager.
+kubebuilder:scaffold:webhookwebhooks suite tests filesMarks where webhook setup functions are added.
+kubebuilder:scaffold:crdkustomizeresourceconfig/crdMarks where CRD custom resource patches are added.
+kubebuilder:scaffold:crdkustomizewebhookpatchconfig/crdMarks where CRD webhook patches are added.
+kubebuilder:scaffold:crdkustomizecainjectionpatchconfig/crdMarks where CA injection patches are added for the webhook.
+kubebuilder:scaffold:manifestskustomizesamplesconfig/samplesMarks where Kustomize sample manifests are injected.
+kubebuilder:scaffold:e2e-webhooks-checkstest/e2eAdds e2e checks for webhooks depending on the types of webhooks scaffolded.