Getting started with Crossplane
Infrastructure as Code has been out there for quite some time now.
It came to solve an issue and kept evolving with new features.
We’ve seen days of
CFEngine. Went through Chef, Puppet, Ansible and are living in the Terraform and Pulumi era.
Crossplane is the next stage of this evolution. It is bringing something new to the table: the ability to detect and correct drifts.
Before we move forward to see the true abilities of crossplane, let’s see how you can get started with it.
Step 1: Setup an initial cluster
Crossplane runs on a Kubernetes cluster, so for the first step, you need to create a cluster. This can be as small as
minikube or kind since it will just be providing the interface for Crossplane.
For this step, install
kind on your system. And run:
kind create cluster — image kindest/node:v1.23.0 — wait 5m
Step 2: Install crossplane
As all Kubernetes hosted applications should be, start by creating a separate namespace:
kubectl create namespace crossplane-system
Next, install the
helm repo add crossplane-stable https://charts.crossplane.io/stable
helm repo update
helm install crossplane --namespace crossplane-system crossplane-stable/crossplane
helm list or
kubectl get command in the
crossplane-system namespace to check if the installation is successful.
Step 3: Install the crossplane cli
Crossplane is more or less a plugin/package for the
kubectl CLI. Simply install it using:
curl -sL https://raw.githubusercontent.com/crossplane/crossplane/master/install.sh | sh
Now you can use it like
kubectl crossplane ... to install any configuration package.
Step 4: Install the configuration package for your desired provider
In this example, we’ll install the AWS config package, using the command:
kubectl crossplane install configuration registry.upbound.io/xp/getting-started-with-aws:v1.8.1
This configuration uses the default VPC. If you wish to create a new VPC for the cluster, use
Crossplane is cloud-agnostic, so you can use
registry.upbound.io/xp/getting-started-with-azure:v1.8.1 for GCP and Azure respectively.
Further steps would be a little different if you opt for Azure or GCP, but you find them here.
Step 5: Configure credentials
We have the
crossplane ready on our local system, now we just need to pass the credentials for our provider of choice so that
crossplane can talk to it.
For AWS, this can be done like:
AWS_PROFILE=default && echo -e "[default]naws_access_key_id = $(aws configure get aws_access_key_id --profile $AWS_PROFILE)naws_secret_access_key = $(aws configure get aws_secret_access_key --profile $AWS_PROFILE)" > creds.conf
Note that this is the same kind of configuration that you get while performing AWS CLI login.
Next, we’ll create a secret from this file like:
kubectl create secret generic aws-creds -n crossplane-system --from-file=creds=./creds.conf
And pass it in our
Once you have the provisioners in place, just apply this manifest:
and check its status using the command::
kubectl get postgresqlinstance my-db
Et voila! You have a Postgres Instance ready, just like that!
There are mainly two ways to create resources from this point, using custom resources (CRs) or composite resources (XRs).
The custom resource method allows you to create resources from the resource definitions provided inside the AWS configuration package. This is the process that we just saw. You can see the definition and syntax for them here.
Composite Resources on the other hand are designed to let you build your own platform with your own opinionated concepts and APIs without needing to write a Kubernetes controller from scratch.
Instead, you define the schema of your XR and teach Crossplane which Managed Resources it should compose (ie create) when someone creates the XR you defined. You can read more on it here.
AWS provides the blueprints for these XRs right here. Let’s try an example from the same repo. Say you want to create your own VPC, you can use first apply the Composition by applying the contents shown here by running
kubectl apply -f compositions/aws-provider/vpc
And then applying the XR:
That’s all good, we created a VPC using infrastructure as code (IaC), just like any other IaC tool. What’s so special about crossplane? Also, why does it need a kubernetes cluster to run in the first place, why not just a CLI like Pulumi or Terraform (at least the open-source versions)?
crossplane isn’t just creating the infrastructure, it will also maintain it that way.
Let’s see how it does that by creating another resource. This time, an EKS cluster
Use the same crossplane-aws-blueprints repository and run these commands (you would want to update a few details like subnet-ids)
kubectl apply -f compositions/aws-provider/ekskubectl apply -f examples/aws-provider/composite-resources/eks/eks-claim.yaml
The configuration we are deploying here goes something like this
Here the managed node group is set to have a minimum of 2 nodes. Try and updating it to 3 from the AWS Console directly.
You’ll see that it creates a third node but soon enough the configuration goes back to 2 and the third node gets terminated.
Crossplane would not allow any manual changes on the resources. If any change is made, it will bring it back to original/desired configuration.
What if I said that you can install one more tool on the cluster managing crossplane which will make your life much more easier?
Crossplane goes hand in hand with another tool which I talked about in one of my previous blogs
Blending Crossplane (which keeps your infrastructure up to date with code) with a GitOps enabler like ArgoCD (which tracks your Git repo) would mean that any change you commit to your repository would reflect on your infrastructure.
There is a crossplane provider for installing argocd as well. Check it out here.
There are more tools that you can plug into this architecture. Take
KubeVela for example.
To summarize, KubeVela lets you declare your deployment plan as workflow, run it automatically with any CI/CD or GitOps system, and extend or re-program the workflow steps with CUE.
Though this is quite an understatement for KubeVela’s capability, but it should be a good start.
As an ops member, you can define the provisioners for infrastructure using Crossplane and setup the CI/CD process using KubeVela.
Finally, you create a Git repository and an ArgoCD application that tracks it.
Now your dev members are enabled with the ability to provision infrastructure and deploy their applications on it, just be doing a
git push with almost all the components abstracted.
They do not need to know how the IaC or Kubernetes works here, they just need to understand the syntax of one single
The reason I added ArgoCD and KubeVela in this blog is to simply help you understand that
crossplane does not just bring drift detection and auto-sync to the table.
If you architect it well and gel it up with other tools available in this landscape, you’ll understand the real value of Crossplane.
Crossplane is bringing a new evolution in IaC.
Ability to not just create, but holding on to the infrastructure configuration was only achieved through custom codes and in-house frameworks so far.
Now, it’s available for everyone and I hope will soon become the market standard that other IaC follow too.