Crossplane is a cloud-native tool that allows users to manage infrastructure directly through the Kubernetes API (kube-api). The kube-api server enables communication with the cluster and Kubernetes related resources. At the time of writing, Crossplane is a Sandbox project at the CNCF. By managing our infrastructure through the kube-api, we have the possibility to create and interact with all of our resources through Kubernetes. This allows us to keep our resources cohesive and manage all of them in Kubernetes.
In this guide, we will provide
- an overview of Crossplane and additional benefits
- a guide on using the Crossplane Civo Provider to create a ‘civokubernetes’ resource
To use Crossplane, you either need access to the hosted version, which is provided by Upbound, or you have to install the self-hosted version. In our guide, we are going to be using the self-hosted version. The self-hosted Crossplane instance can be installed like other Kubernetes resources on your Kubernetes cluster through a Helm Chart.
Once Crossplane is installed, we will have to install the Provider Configuration for the given Provider that we want to use. The Provider Configuration references a cloud provider and their resources. There are Provider Configurations for all major cloud providers, which allow you to use Crossplane on the cloud of your choice.
Once our Kubernetes cluster has Crossplane and our Provider Configuration installed, we can create a Provider Resource. The Provider Resource will tell Crossplane how to connect to our Provider Account e.g. our Civo account.
At this point, the resources installed on our Kubernetes cluster will know about the infrastructure resources that can be created through the Civo Provider and we can apply our resources to the Crossplane Cluster. Crossplane will communicate through the Provider Configuration with Civo to create a Civo Kubernetes cluster for us.
The following image provides a high level overview of the resources installed in our KinD cluster and how those communicate with our Civo Account.
Benefits of using Crossplane
Using Crossplane, we are able to implement GitOps best practices not only on the resources running within our Kubernetes cluster but also on our infrastructure resources. GitOps is the practice of using Git as our single point of truth. Thus, all of our resources are kept in Git. An agent running within our cluster will be provided with access to our Git repository to pull any changes within Git into our Cluster.
This allows us to set up advanced deployment mechanisms. Whenever any changes occur, whether on our resources or our infrastructure, the agent will recognize those changes and pull them automatically into our cluster; should they pass our checks.
If you are new to GitOps, have a look at the following overview.
Ultimately, Crossplane ensures that we can declaratively manage our infrastructure. Meaning, we will specify within our code the properties of our infrastructure resources and Crossplane will ensure those are created like specified. The code, which details our infrastructure, is referred to as our desired state and the resources that Crossplane will create become the actual state of our infrastructure. The actual state of our infrastructure always refers to the implemented and running infrastructure.
Once the resources have been created, Crossplane will continuously monitor the state of our infrastructure resources. Should the actual state of our infrastructure not match the desired state specified, Crossplane will then try to modify the actual state to match the desired state. This is the same process as the declarative model that underpins Kubernetes.
For example, should you change the number of nodes running on your Kubernetes cluster through the UI and not through the infrastructure resources stored in Git and managed by Crossplane, Crossplane will detect those changes. Subsequently, Crossplane is responsible for reverting the changes back so that the actual state of your cluster matches the desired state defined in Git. This way, all changes done to your infrastructure are trackable in Git.
Like mentioned before, Crossplane allows us to define our infrastructure resources in Git. Detailing our infrastructure in code makes it possible to easily share configuration files. Instead of describing which buttons to press in a UI, we can provide other team members the code configuration to create a new Kubernetes Cluster or similar. As a result, our infrastructure can become more consistent across teams.
Shifting Left is the process of empowering developers by ensuring they are equipped to participate in infrastructure management and deployments. Instead of a dedicated DevOps team being responsible for creating and managing infrastructure in response to requests by the engineering teams, the engineering teams are provided with the necessary tools to address most common use cases themselves.
Using Crossplane, the DevOps team can define what type of infrastructure resources can be created and then provide the engineering team with examples of those resources. In contrast, if engineers have to have access to a cloud provider account to create resources, they may have less direction on which resources to create, how to create them, and how to manage the system most efficiently.
Thus, Crossplane makes it easier to empower engineering teams across the organization.
Using the Civo Crossplane Provider
This section details how to use the Civo Crossplane Provider.
Before using Crossplane and the Civo Crossplane Provider, please ensure that you have the following resources installed:
- KinD (optionally another Kubernetes Cluster)
- A civo account -- If you sign up now, you can get $250 worth of credit
Preparing our KinD cluster
To use Crossplane, we first need to have a Kubernetes cluster on which we can install Crossplane. You can use any Kubernetes cluster you have access to, and we are going to use a KinD cluster running locally. Since we want to create a Civo cluster with Crossplane, we are going to start out with a KinD cluster. The following command will create a basic, one node KinD cluster for us:
kind create cluster --name crossplane
Note that you could use any other Kubernetes Cluster for the same purpose. The important thing is that we need a cluster on which we can install Crossplane.
Next, we are going to install the Crossplane Helm Chart. Run the following commands:
kubectl create namespace crossplane-system helm repo add crossplane-stable https://charts.crossplane.io/stable helm repo update helm install crossplane --namespace crossplane-system crossplane-stable/crossplane --version 1.6.0
You can ensure all resources are running properly through the following commands:
helm list -n crossplane-system kubectl get all -n crossplane-system
Installing the Civo Provider Configuration
Next, Crossplane has to learn about Civo and the resources that can be created on Civo. This is what the Provider Configuration is used for. The Provider Configuration lives in the following repository.
There are two options for installing the Provider Configuration by adding the OCI image for the provider configuration. OCI refers to Open Container Initiative with the purpose to define a common standard for containers. In either case, make sure to be connected to the KinD cluster, which is running Crossplane.
Before installing the Provider, we need to have access to the Crossplane CLI. The Crossplane CLI can be installed through the following commands:
curl -sL https://raw.githubusercontent.com/crossplane/crossplane/release-0.14/install.sh | sh sudo mv kubectl-crossplane /usr/local/bin
To add the OCI Civo Provider Configuration Package, run:
kubectl crossplane install provider crossplane/provider-civo:main
Once you run the command, the kube-API will let you know that the resources has been created:
Connecting the Civo Crossplane Provider to your Civo Account
To connect the Civo Crossplane Provider to your Civo Account, you will need your Civo API key. The Civo API key can be found on your Civo Account under Account > Settings > Security like detailed in the screenshot below.
Before creating a Provider resource, edit the API key in provider.yaml or by creating a new YAML file like detailed in the next step.
Encode the secret with the following command:
echo “your API key” | base64
Next, replace the value of the credentials section within the Secret YAML file with the output:
apiVersion: v1 kind: Secret metadata: namespace: crossplane-system name: civo-provider-secret type: Opaque data: credentials: <replace with base64 encoded Civo API KEY> --- apiVersion: civo.crossplane.io/v1alpha1 kind: ProviderConfig metadata: name: civo-provider spec: region: lon1 credentials: source: Secret secretRef: namespace: crossplane-system name: civo-provider-secret key: credentials
Next, we can apply the Provider:
kubectl apply -f provider.yaml
Once the resource has been created, we can apply the cluster resource. The example specifies a small cluster instance with three nodes in the LON1 Civo Region:
kind: CivoKubernetes apiVersion: cluster.civo.crossplane.io/v1alpha1 metadata: name: test-crossplane spec: name: test-crossplane pools: - id: "8382e422-dcdd-461f-afb4-2ab67f171c3e" count: 4 size: g3.k3s.small - id: "8482f422-dcdd-461g-afb4-2ab67f171c3e" count: 3 size: g3.k3s.small applications: - "argo-cd" - "prometheus-operator" connectionDetails: connectionSecretNamePrefix: "cluster-details" connectionSecretNamespace: "default" providerConfigRef: name: civo-provider
Note that the applications are provided as a YAML array. If you do not add any applications, the default applications which are Traefik and Kubernetes Metrics will be installed on your cluster. You can find a comprehensive list of all applications on the Civo by running the following command with the Civo CLI:
civo kubernetes application ls
Lastly, we can apply the cluster resource to our KinD cluster:
kubectl apply -f cluster.yaml
This will create a new Kubernetes cluster in your Civo account, according to the specifications provided in the cluster.yaml file.
Note that you will not be able to delete the cluster created by Crossplane through the Civo UI or the Civo CLI directly since the resource is managed by Crossplane. Crossplane will continuously reconcile the cluster within Civo. If Crossplane detects that the cluster is missing or has changed, it will ensure that the cluster is re-created and matches the cluster specification.
You can check the status of our newly created cluster through the following command:
kubectl get civokubernetes
Lastly, we want to be able to connect to our newly created Civo Kubernetes Cluster. Upon creating the cluster, we are storing its kubeconfig in a Kubernetes secret.
With the use of
kubectl it is possible to retrieve the
CivoKubernetes kubeconfig directly:
kubectl get secrets cluster-details-<name of your cluster> -o yaml | yq eval '.data.kubeconfig' - | base64 -d > kubeconfig
Make sure to add the name of your cluster to the above command.
This will create the kubeconfig file in your current directory.
Next, validate that you can connect to the cluster, by using the kubeconfig file we just saved:
kubectl get nodes --kubeconfig kubeconfig NAME STATUS ROLES AGE VERSION k3s-test-cluster-ec4e8ef1-node-pool-41cf Ready <none> 4m21s v1.20.2+k3s1 k3s-test-cluster-ec4e8ef1-node-pool-23e0 Ready <none> 4m13s v1.20.2+k3s1
In this guide, we gained a general understanding of Crossplane, how it works and its benefits. Next, we created a KinD cluster with Crossplane installed, added the Civo Crossplane provider and applied our Provider and Cluster Resources. If you have followed the guide, you should now be able to use Crossplane to create Civo Kubernetes Clusters and manage those through custom Kubernetes resources.
At the beginning of the guide, we highlighted the value of using GitOps best practices in combination with Crossplane. To get started with GitOps have a look at the following guides:
If you have any questions make sure to join the Civo Slack community. You will have received an invite upon creating your Civo account. Additionally, we highly encourage you to create your own Guides that you can submit through the “Content” section in your Civo Account.