Crossplane — Explained
I was looking to understand what Crossplane in simple terms and everywhere, literally everywhere, the explanation for Crossplane is exactly copied information from the main Crossplane Documentation. I wanted to try from my side to explain what I understood in simple terms. If there are any mistakes, please let me know so I can correct the doc
Introduction
Since the start of Kubernetes Cluster, many things started to make its way into the IT landscape with Kubernetes as the heart of it. And out of the many, one is Infrastructure deployment.
In the past, we would need to rely on Cloud agnostic deployment tools like Terraform, Pulumi, etc. And this required to have knowledge on the tool and proficient when building large-scale infrastruture.
Someone might had an idea to build a tool, which will also deploy infra with simple way and it doesn’t matter which cloud is it. And that’s how, I believe, Crossplane was started.
We can think, why its so special and what’s the difference between other tools right now in the market? One answer, Immediate Reconciliation. So as you know any application running in a Kubernetes cluster is controlled by a Controller manager which takes care of constant reconciliation of resource created to match the state that is stored in the ETCD state. So for infrastructure deployment, the change is reflected immediately. No wasting time in deployment. This is the real bonus. Because if someone manage to change in Cloud through Portal or Console, Crossplane reverts it back in matter of seconds. Perfect for Gitops!!
So what’s Crossplane?
Crossplane, in simple terms, can be called an infrastructure deployment tool, which will deploy resources in any Cloud using just a yaml file. A simple yaml file.
Sounds cool? Then lets take a look at how does it look under the hood.
Inner Workings
So Crossplane is deployed as a Helm Chart or a kubernetes manifest file. This is basically an application, which when installed, will install all the CRDs or Custom Resource Definitions to make the Crossplane run. List of CRDS that are installed can be found here.
Then the next step will be to install a Provider. The Provider is kind of a plugin which when installed, will install Cloud Provider specific CRDs for the resources to be created. List of Providers can be found here
For example, provider-aws
is actually a mix of package
and CRDs
. Package
contains the functions to create the resource and CRDS
contain information on what are the parameters or input that is required for the resource to be created. A sample Provider
yaml config will look like this:
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
name: provider-aws
spec:
package: "crossplane/provider-aws:master"
And ProviderConfig
is to provide the credentials or config for the Provider
to run. In this case, it will be the AWS credentials and configuration. A sample ProviderConfig
looks like this:
apiVersion: aws.crossplane.io/v1beta1
kind: ProviderConfig
metadata:
name: aws-provider
spec:
credentials:
source: Secret
secretRef:
namespace: crossplane-system
name: aws-creds
key: key
ControllerConfig
is a configuration which can be used to override the default values provided when deploying Provider
. The changes that I think is important is package
version for the provider or resources
, nodeSelector
, etc. There are many other CRDs that are related to Crossplane. I am just touching only the important stuff.
For more information on what CRDs are installed as part of provider-aws
, check here
Crossplane Resources.
Now that the Crossplane is setup and connected, Its time to deploy resources. In Terraform, we have the possibility to deploy a resource
or a couple of resources bundled into a module
. Just like that we can create a ManagedResource
which is exactly the 1-to-1 resource on the cloud. For example RDSInstance
. Then there is CompositeResource
which is a combination of couple of ManagedResource
combined into one. For example, myDBInstance
which can be a mix of RDSInstance
, NetworkRules
, DB
etc.
With ManagedResource
, Its fairly simple deployment, because there is already the CRDs installed. A simple example:
apiVersion: database.aws.crossplane.io/v1beta1
kind: RDSInstance
metadata:
name: rdspostgresql
spec:
forProvider:
region: us-east-1
dbInstanceClass: db.t2.small
masterUsername: masteruser
allocatedStorage: 20
engine: postgres
engineVersion: "12"
skipFinalSnapshotBeforeDeletion: true
writeConnectionSecretToRef:
namespace: crossplane-system
name: aws-rdspostgresql-conn
So this RDSInstance
kind is created by the database.aws.crossplane.io/v1beta1
API.
With CompositeResource
, its a different story. This resource requires a CRD called CompositeResourceDefinition
or XRD
. This contains what are the input parameters that is required for the resource. Then there is a Composition
which is the main resource that is being created. The configuration here will take the input and can be managed to create a CompositeResource
which is a combination of multiple ManagedResource
. Infrastructure Teams, prefer Compositeresource
over ManagedResource
, because this gives them leverage to put static values for some parameters or lock some input parameter, so that the developers who creates the resource cannot override those parameter.
A Composite Resource is always a Cluster object. To create a Composite resource will deploy a Cluster Object and then a Claim is created out of it, which is what the endusers see in their namespace.
As you see in the picture, The end user will be creating a Claim, which is a request sent to Crossplane, who will read the Composition and XRD for the Composite resource requested, then make the API query to the Cloud via Provider and create the resource on the Cloud and then sends the confirmation info to the Claim, which will make the resource available in the namespace.
An example of a Composite Resource for Database looks like this:
apiVersion: database.example.org/v1alpha1
kind: XPostgreSQLInstance
metadata:
name: my-db
spec:
parameters:
storageGB: 20
compositionRef:
name: production
writeConnectionSecretToRef:
namespace: crossplane-system
name: my-db-connection-details
So all the other parameters can be defaulted in Composition or cannot be overridden. Composition and XRD configuration for a Composite resource can be found here
So is Crossplane Good?
So far, I have been working on AWS and Azure. It looks like Provider for AWS is really collaborative and engaging and the development is very fast, so for AWS, Crossplane will be a good choice for infra deployments. But of course, a K8s cluster needs to be in place.
For Azure and GCP, the development is slow, so the resources that can be deployed are really low. Alternative providers can also be used like provider-terraform
or provider-terrajet
, which basically uses Terraform to deploy resources under Crossplane. This is not an ideal solution IMHO, but if someone wants it so badly, then they can use it.
Conclusion
Crossplane is a really interesting tool and has the potential to be a very good one for infrastructure deployment. It helps to do a lot of automated infrastructure creation/deletion of resources for testing. On the other hand, its still in Beta phase, and gaining a large infrastructure crowd. If you think this is “beta” and not so good, remember, Terraform was once in beta stage, and we are still running huge, large-scale deployments. Choice is always yours!
Hope you enjoyed!
New Edit:
There are now stable providers available for crossplane, provided by Upbound.io. These are very good and stable from my tests, so I believe now its time to play around more without much issues and have a crossplane deployed infra.!!!
More info on providers can be found here