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.
- Observe: Are there 3 Pods running? No, there are only 2.
- Diff: We need 1 more Pod.
- 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#
- Install
kubectl. - Install
kindorminikube. - Install
helm(The Kubernetes Package Manager).
Start your local cluster:
kind create cluster --name crossplane-demoHelm Installation#
Crossplane is installed via a standard Helm chart.
Add the Crossplane Helm Repository:
helm repo add crossplane-stable https://charts.crossplane.io/stable helm repo updateInstall the Chart: We will install Crossplane into a dedicated
crossplane-systemnamespace.helm install crossplane crossplane-stable/crossplane \ --namespace crossplane-system \ --create-namespaceVerify the Installation: Ensure the Crossplane Core and RBAC Manager pods are running.
kubectl get pods -n crossplane-systemExpected 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/binVerify it is installed correctly. Note that it integrates directly into kubectl as a plugin!
kubectl crossplane --version4. 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 crossplaneExpected 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:22ZNotice the providers.pkg.crossplane.io CRD. This proves that our cluster now understands what a “Provider” is.
Troubleshooting & Common Errors#
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-systemto wipe the release, then delete the namespace, and try the installation again.
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).
- Root Cause: You downloaded the binary but did not move it to a directory that is within your system’s
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.

