> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Demo Scaffold The Same Operator With Operator SDK

> Guide to scaffolding a Go WebApp Kubernetes operator with Operator SDK, covering installation, project initialization, API and controller creation, generated code inspection, manifests, and layout comparison with Kubebuilder

You previously built a web app operator using Kubebuilder. In this lesson you'll scaffold the same Go operator with the Operator SDK and compare the resulting project layout. The objective is to observe the initial scaffold and reconcile model—this is not a walkthrough to re-implement the web app logic.

This guide covers:

* Prerequisites
* Installing the operator-sdk CLI (Linux / macOS)
* Initializing a new Go operator project
* Creating the WebApp API and controller
* Inspecting generated code and manifests
* Comparing the generated PROJECT layout and plugins

## Prerequisites

* Go toolchain installed and configured (Go 1.19+ recommended)
* Git and curl available
* Optional: a disposable workspace (example: an ephemeral container or temporary directory)

## Install operator-sdk

### Linux installation (recommended steps)

Download the release binary for your architecture, verify the signed checksums, and place the binary on your PATH as `operator-sdk`.

```bash theme={null}
export OPERATOR_SDK_VERSION=v1.42.2
export OPERATOR_SDK_DL_URL="https://github.com/operator-framework/operator-sdk/releases/download/${OPERATOR_SDK_VERSION}"
curl -LO "${OPERATOR_SDK_DL_URL}/operator-sdk_linux_amd64"
curl -LO "${OPERATOR_SDK_DL_URL}/checksums.txt"
curl -LO "${OPERATOR_SDK_DL_URL}/checksums.txt.asc"
```

Import and verify the release signing key, then verify the checksums:

```bash theme={null}
gpg --keyserver keyserver.ubuntu.com --recv-keys 052996E2A20B5C7E
gpg --verify checksums.txt.asc checksums.txt
sha256sum --check --ignore-missing checksums.txt
# expected output:
# operator-sdk_linux_amd64: OK
```

Make the binary executable and move it into a location on your PATH:

```bash theme={null}
chmod +x operator-sdk_linux_amd64
sudo mv operator-sdk_linux_amd64 /usr/local/bin/operator-sdk
```

### macOS (Homebrew)

You can also install via Homebrew on macOS:

```bash theme={null}
brew install operator-sdk
```

Verify the CLI is available and inspect the binary metadata:

```bash theme={null}
operator-sdk version
# sample output:
# operator-sdk version: "v1.42.2", commit: "6001c29067051e1a04e829ea033988b904d1845e", kubernetes version: "1.33.1", go version: "go1.25.7", GOOS: "linux", GOARCH: "amd64"
```

Note: the reported "kubernetes version" refers to the Kubernetes client libraries bundled with the SDK binary, not your cluster version.

<Callout icon="lightbulb" color="#1CB2FE">
  If you are already familiar with the [Kubebuilder](https://learn.kodekloud.com/user/courses/kubernetes-operators) scaffold, the operator-sdk Go scaffold will feel familiar: you still write API types and a reconciler, and you still run a controller manager. operator-sdk layers additional tooling and plugins (manifests, scorecard, OLM) around that shared foundation.
</Callout>

## Initialize a clean Go operator-sdk project

Start from an empty directory (for disposable workspaces you may run `rm -rf *`).

```bash theme={null}
rm -rf *
operator-sdk init --domain=kodekloud.com --repo=github.com/kodekloud/webapp-sdk --plugins=go/v4
```

What to watch for as the project initializes:

* controller-runtime and Go module setup (the same controller-runtime library Kubebuilder uses).
* Code generation steps (e.g., `make generate`, `go generate`) and `go mod tidy`.

This confirms the operator runtime foundation (manager, client, event watching, reconcile loop) is shared between Kubebuilder and operator-sdk.

## Create the WebApp API and controller

Scaffold the API group `webapp`, version `v1`, and kind `WebApp`. Use `--resource` to scaffold the CRD types and `--controller` to add a reconciler skeleton.

```bash theme={null}
operator-sdk create api --group webapp --version v1 --kind WebApp --resource --controller
```

Typical generated artifacts:

* `api/v1/webapp_types.go`
* `internal/controller/webapp_controller.go`
* `internal/controller/webapp_controller_test.go`

The SDK also runs `go mod tidy` and the codegen tasks to produce boilerplate.

## Inspect the generated code

API types are located under `api/v1`. The reconciler skeleton is under `internal/controller` (in some layouts it may appear under `controllers`). This separation mirrors the conceptual boundaries used by Kubebuilder.

A corrected sample of the generated list type (ensure your generated `WebAppList` resembles this):

```go theme={null}
package v1

import (
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// WebAppList contains a list of WebApp
type WebAppList struct {
    metav1.TypeMeta `json:",inline"`
    metav1.ListMeta `json:"metadata,omitempty"`
    Items           []WebApp `json:"items"`
}

func init() {
    SchemeBuilder.Register(&WebApp{}, &WebAppList{})
}
```

## Generate manifests

After you implement API fields and reconciliation logic, generate the manifests (CRDs, RBAC, webhook manifests if applicable):

```bash theme={null}
make manifests
```

This produces the CRD YAML, RBAC roles, and other required manifests for deploying your operator.

## Comparing the PROJECT layout

The `PROJECT` file is the most useful artifact when comparing scaffolds. It records the project layout and plugins the scaffold used. operator-sdk, when configured with the Kubebuilder Go layout, will include entries reflecting the Go layout plus operator-sdk plugins (manifests, scorecard, OLM).

Representative `PROJECT` fragment:

```yaml theme={null}
domain: kodekloud.com
layout:
  - go.kubebuilder.io/v4
plugins:
  manifests.sdk.operatorframework.io/v2: {}
  scorecard.sdk.operatorframework.io/v2: {}
projectName: webapp-sdk
repo: github.com/kodekloud/webapp-sdk
resources:
  - api:
      crdVersion: v1
      namespaced: true
      controller: true
      domain: kodekloud.com
      group: webapp
      kind: WebApp
      path: github.com/kodekloud/webapp-sdk/api/v1
      version: v1
version: "3"
```

Quick comparison table: Kubebuilder vs operator-sdk scaffolds

| Area                   | Kubebuilder               | Operator SDK (Go plugin)                              |
| ---------------------- | ------------------------- | ----------------------------------------------------- |
| Controller runtime     | controller-runtime (same) | controller-runtime (same)                             |
| Project layout         | Kubebuilder Go layout     | Kubebuilder Go layout (via plugin)                    |
| Extra tooling          | Minimal by default        | Plugins for manifests, scorecard, OLM, packaging      |
| Common files           | `api/`, `controllers/`    | `api/`, `internal/controller/` (layout may vary)      |
| Packaging & validation | Manual or external        | Built-in plugin support for OLM, scorecard, manifests |

Files you typically see after scaffold:

| Path                                       | Purpose                                           |
| ------------------------------------------ | ------------------------------------------------- |
| `api/v1/webapp_types.go`                   | API type definitions and CRD annotations          |
| `api/v1/webapp_webhook.go`                 | (Optional) Webhook scaffolding                    |
| `internal/controller/webapp_controller.go` | Reconciler skeleton and business logic entrypoint |
| `PROJECT`                                  | Records layout, plugins, and resources            |
| `config/` or `make` targets                | Generated manifests and deployment resources      |

## Key takeaway

The operator-sdk Go plugin uses the same controller-runtime and Kubebuilder-style project layout. The primary differences are the tooling additions and plugins operator-sdk provides for packaging, validation, and distribution (OLM/scorecard). If you understand the Kubebuilder workflow, the operator-sdk Go scaffold will be immediately recognizable and comfortable to work with.

## Links and references

* [Operator SDK Releases](https://github.com/operator-framework/operator-sdk/releases)
* [Kubebuilder / Kubernetes Operators course](https://learn.kodekloud.com/user/courses/kubernetes-operators)
* [controller-runtime documentation](https://pkg.go.dev/sigs.k8s.io/controller-runtime)

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/kubernetes-operators/module/d2537d70-4008-4d53-ad04-b7731ca0f7c0/lesson/0a8c350b-f62f-4772-8899-ee7f3c567bf6" />
</CardGroup>
