Skip to main content

Crossplane Ep 1: The Kubernetes Native Control Plane

Rachmat Hidayat
Author
Rachmat Hidayat
Learn & sharing insights on TypeScript, Go, Kubernetes, DevOps, DevSecOps, SRE, Platform Engineering, AI/ML Engineering, and MLOps.
crossplane - This article is part of a series.
Part 1: This Article
Kubernetes is famous for container orchestration, but at its core, it is simply a highly extensible API server backed by a database (etcd) and a reconciliation engine (Controllers). Crossplane hijacks this powerful architecture, allowing Kubernetes to orchestrate AWS RDS databases and S3 buckets just as easily as it orchestrates Pods. Let’s install the Control Plane.

1. The Control Loop Architecture
#

Before we install Crossplane, you must understand the “Reconciliation Loop”.

In Kubernetes, you declare a Desired State. For example, you write a Deployment YAML that asks for 3 Pods. The Kubernetes Controller constantly compares the Desired State against the Current State.

  1. Observe: Are there 3 Pods running? No, there are only 2.
  2. Diff: We need 1 more Pod.
  3. Act: Start a new Pod.

This loop runs infinitely, every few seconds. If a node crashes and a Pod dies, the loop detects the drift and immediately spins up a replacement.

Applying the Loop to Cloud Infrastructure
#

Terraform and Pulumi do not have an infinite loop. They run once when you type terraform apply, and then they shut down. If someone manually logs into the AWS Console and deletes a Security Group, Terraform will not fix it until the next time a human runs a pipeline.

Crossplane brings the infinite reconciliation loop to Cloud Infrastructure.

If you create an S3 bucket via Crossplane, Crossplane’s AWS Controller will constantly monitor that bucket in AWS. If a rogue administrator deletes the bucket via the AWS Console, the Crossplane controller will detect the drift within seconds, realize the bucket is missing, and instantly recreate it via the AWS API to match the Desired State stored in Kubernetes etcd.

This is called Configuration Drift Prevention, and it is the holy grail of infrastructure management.


2. Installing Crossplane
#

To use Crossplane, you need a Kubernetes cluster. Because Crossplane is a control plane tool, you can install it into a local kind (Kubernetes IN Docker) cluster on your laptop. You do not need an expensive EKS cluster to learn.

Prerequisites
#

  1. Install kubectl.
  2. Install kind or minikube.
  3. Install helm (The Kubernetes Package Manager).

Start your local cluster:

kind create cluster --name crossplane-demo

Helm Installation
#

Crossplane is installed via a standard Helm chart.

  1. Add the Crossplane Helm Repository:

    helm repo add crossplane-stable https://charts.crossplane.io/stable
    helm repo update
  2. Install the Chart: We will install Crossplane into a dedicated crossplane-system namespace.

    helm install crossplane crossplane-stable/crossplane \
      --namespace crossplane-system \
      --create-namespace
  3. Verify the Installation: Ensure the Crossplane Core and RBAC Manager pods are running.

    kubectl get pods -n crossplane-system

    Expected Terminal Output:

    NAME                                       READY   STATUS    RESTARTS   AGE
    crossplane-7f5b8c6d9-abcde                 1/1     Running   0          45s
    crossplane-rbac-manager-6d4f9b8c7-vwxyz    1/1     Running   0          45s

3. The Crossplane CLI (Optional but Recommended)#

While you interact with Crossplane primarily using standard kubectl commands, the Upbound team (the creators of Crossplane) provides a dedicated crossplane CLI tool that makes building and packaging Compositions much easier.

Install the Crossplane CLI:

# macOS / Linux
curl -sL "https://raw.githubusercontent.com/crossplane/crossplane/master/install.sh" | sh
sudo mv kubectl-crossplane /usr/local/bin

Verify it is installed correctly. Note that it integrates directly into kubectl as a plugin!

kubectl crossplane --version

4. Understanding Custom Resource Definitions (CRDs)
#

So, how does Crossplane actually teach Kubernetes about AWS S3 buckets?

Out of the box, Kubernetes only knows about things like Pods, Services, and ConfigMaps. If you try to run kubectl get buckets, the API server will return an error because “buckets” do not exist in the Kubernetes codebase.

Crossplane uses a native Kubernetes feature called Custom Resource Definitions (CRDs).

A CRD is a way to dynamically inject a brand new API schema into a running Kubernetes cluster. When we install the Crossplane AWS Provider (which we will do in Episode 2), the Provider will inject hundreds of new CRDs into the cluster. It will literally add Bucket, VPC, and RDSInstance to the Kubernetes API.

Once those CRDs are installed, you can use kubectl get buckets or kubectl get vpc just as easily as you use kubectl get pods.

Let’s check if Crossplane installed its core CRDs during the Helm installation:

kubectl get crds | grep crossplane

Expected Terminal Output:

compositions.apiextensions.crossplane.io               2026-08-09T17:15:22Z
compositeresourcedefinitions.apiextensions.crossplane.io 2026-08-09T17:15:22Z
configurationrevisions.pkg.crossplane.io               2026-08-09T17:15:22Z
configurations.pkg.crossplane.io                       2026-08-09T17:15:22Z
providerrevisions.pkg.crossplane.io                    2026-08-09T17:15:22Z
providers.pkg.crossplane.io                            2026-08-09T17:15:22Z

Notice the providers.pkg.crossplane.io CRD. This proves that our cluster now understands what a “Provider” is.


Troubleshooting & Common Errors
#

  1. Helm install fails with "cannot re-use a name that is still in use"

    • Root Cause: You previously tried to install Crossplane and the installation failed or was partially deleted.
    • Solution: Run helm uninstall crossplane -n crossplane-system to wipe the release, then delete the namespace, and try the installation again.
  2. kubectl crossplane command not found

    • Root Cause: You downloaded the binary but did not move it to a directory that is within your system’s $PATH.
    • Solution: Ensure you ran sudo mv kubectl-crossplane /usr/local/bin (or equivalent for your OS).

Conclusion & Next Steps
#

You have successfully installed the core Crossplane engine into your Kubernetes cluster. Your cluster is now a Control Plane capable of infinite reconciliation.

However, right now, Crossplane is an empty shell. It doesn’t know how to talk to AWS, GCP, or Azure, and it doesn’t have the credentials to do so.

In Episode 2: Providers and Credentials, we will install the official Upbound AWS Provider, configure IAM credentials securely using Kubernetes Secrets, and prepare our cluster to provision physical cloud hardware.

crossplane - This article is part of a series.
Part 1: This Article