Local Development¶
This guide explains how to set up and run the CloudAPI Operator locally for development and debugging.
Prerequisites¶
- Go (version 1.24+)
- kubectl to access a Kubernetes cluster
- Helm for installing KCP
- A running Kubernetes cluster (e.g., kind or a remote cluster)
- Make to utilize provided makefile
Development Environment Setup¶
We recommend using Nix for a reproducible development environment:
This ensures all tools and dependencies are available in consistent versions.
Quick Start¶
Use Makefile to setup a development env with KCP:
This will:
- Create a Kind cluster (if not exists)
- Install cert-manager
- Install KCP via Helm
- Create KCP kubeconfig files (in-cluster and local)
- Install CRDs
After completion you can:
run the operator LOCALLY (from your machine): 1. Start port-forward: make kcp-port-forward 2. In another terminal: make run-local
deploy the operator IN THE CLUSTER: make deploy-dev
Manual Setup¶
Setting Up a Local Kubernetes Cluster¶
If you don't have a Kubernetes cluster available, you can spawn a local Kind cluster for development:
This creates a Kind cluster that can be used for local development and testing. The cluster will persist until you explicitly delete it.
To tear down the cluster when you're done:
Install cert-manager (required for KCP cert management)¶
Install KCP via Helm¶
Uninstall KCP:¶
Create KCP Kubeconfig¶
Generate the KCP admin kubeconfig files:
# For in-cluster use
make create-kcp-kubeconfig
# For local development (uses localhost)
make create-kcp-kubeconfig-local
Install CRDs¶
Before running the operator, install the Custom Resource Definitions in your cluster:
Verify the CRDs are installed like so:
Running the Operator¶
Option 1: Running Locally (Recommended for Development)¶
To run the operator from your local machine while connecting to KCP in the cluster:
-
Start the KCP port-forward (in one terminal):
-
Run the operator (in another terminal):
This approach is ideal for rapid development as it allows you to use your IDE debugger and see changes immediately without rebuilding container images.
Option 2: Running in the Cluster¶
To deploy the operator as a container inside the Kind cluster:
This will:
- Build the Docker image
- Load the image into the Kind cluster
- Deploy the operator
Check the deployment status:
Run the operator from the commandline like so:
or add a run configuration to your favorite IDE/Editor.
Testing Your Changes¶
Once the operator is running, create a sample WorkspaceClaim to trigger reconciliation:
Watch the operator logs to see the reconciliation loop in action.
Verify the resource status¶
Running Tests¶
Unit Tests¶
End-to-End Tests¶
Useful Commands¶
Run make help to see all available commands. Here's a summary:
General¶
| Command | Description |
|---|---|
make help |
Display help with all available targets |
Development¶
| Command | Description |
|---|---|
make manifests |
Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects |
make generate |
Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations |
make fmt |
Run go fmt against code |
make vet |
Run go vet against code |
make test |
Run tests |
make setup-test-e2e |
Set up a Kind cluster for e2e tests if it does not exist |
make test-e2e |
Run the e2e tests (expects an isolated environment using Kind) |
make cleanup-test-e2e |
Tear down the Kind cluster used for e2e tests |
make lint |
Run golangci-lint linter |
make lint-fix |
Run golangci-lint linter and perform fixes |
make lint-config |
Verify golangci-lint linter configuration |
Development Environment Setup¶
| Command | Description |
|---|---|
make setup-dev-env |
Set up complete dev environment with Kind, cert-manager, KCP, and CRDs |
make install-certmanager |
Install cert-manager into the current cluster |
make install-kcp |
Install KCP via Helm chart into the current cluster |
make uninstall-kcp |
Uninstall KCP from the current cluster |
make create-kcp-kubeconfig |
Create KCP admin kubeconfig file for in-cluster use |
make create-kcp-kubeconfig-local |
Create KCP kubeconfig for local development (uses localhost) |
make kcp-port-forward |
Port-forward KCP to localhost:8443 |
make run-local |
Run the operator locally (requires kcp-port-forward running) |
Build¶
| Command | Description |
|---|---|
make build |
Build manager binary |
make run |
Run a controller from your host |
make docker-build |
Build docker image with the manager |
make docker-push |
Push docker image with the manager |
make docker-buildx |
Build and push docker image for cross-platform support |
make build-installer |
Generate a consolidated YAML with CRDs and deployment |
make deploy-dev |
Build, load into Kind, and deploy the operator for development |
Deployment¶
| Command | Description |
|---|---|
make install |
Install CRDs into the K8s cluster specified in ~/.kube/config |
make uninstall |
Uninstall CRDs from the K8s cluster specified in ~/.kube/config |
make deploy |
Deploy controller to the K8s cluster specified in ~/.kube/config |
make undeploy |
Undeploy controller from the K8s cluster specified in ~/.kube/config |
Dependencies¶
| Command | Description |
|---|---|
make kustomize |
Download kustomize locally if necessary |
make controller-gen |
Download controller-gen locally if necessary |
make setup-envtest |
Download the binaries required for ENVTEST in the local bin directory |
make envtest |
Download setup-envtest locally if necessary |
make golangci-lint |
Download golangci-lint locally if necessary |
Configuration¶
The following environment variables can be customized:
| Variable | Default | Description |
|---|---|---|
KIND_CLUSTER |
cloudapi-operator-test-e2e |
Name of the Kind cluster |
KCP_HELM_CHART_VERSION |
0.12.7 |
KCP Helm chart version |
KCP_LOCAL_PORT |
8443 |
Local port for KCP port-forward |
CERTMANAGER_VERSION |
v1.18.2 |
cert-manager version |
OPERATOR_NAMESPACE |
cloudapi-operator-system |
Namespace for the operator deployment |
IMG |
example.com/cloudapi-operator:v0.0.1 |
Docker image name and tag |
Troubleshooting¶
CRDs not found¶
If you see errors about unknown resource types, ensure CRDs are installed:
Permission errors¶
Ensure your kubeconfig has sufficient permissions. For local clusters like kind or minikube, this is usually not an issue.
Operator not reconciling¶
The reconcile loop only triggers when:
- A
WorkspaceClaimresource exists in the cluster - The resource is created, updated, or deleted
If you don't see logs, create or modify a WorkspaceClaim resource.
Kind cluster issues¶
To completely reset your development environment:
Tear it down with
and set it up clean with