In this article we will be talking about Crossplane as an Infrastructure as Code (IaC) tool that is running on Kubernetes, why should we use it and how you configure AWS provider to start creating resources, we will be going through a full step by step example for you to be able to create your first resource with Crossplane
Who is this article for?
- DevOps engineers interested in learning another IaC tool
- Developers that want to take more Ops responsibility and provision their own infrastructure
- Engineering managers that are looking to implement an IaC tool in their company/startup
Why am I writing this?
I had some discussions with engineers that had some trouble to get started with Crossplane, it may be a little less straightforward than a well established tool like Terraform, some documentation isn’t precise for different use cases and providers and even ChatGPT’s code doesn’t seem to work at times. And here I am saving the day to make your life easier by giving you a step by step guide where you install and configure everything and deploy your first AWS resource using Crossplane.
Why should you even use Crossplane then?
There are certain use cases where Crossplane provides very powerful capabilities being able to create both applications and cloud resources, those can be used for ephemeral environments for example or for having a SaaS company provide full environments that could be self created by a tenant. Those environments could be created by just applying a Kubernetes manifest which is much simpler than starting to run traditional IaC plan and apply commands.
How this article works
- We prepared a repository with resources to deploy everything needed.
- We explain on each resource what it does.
- We walk you through how to deploy Crossplane.
- We deploy a S3 Bucket to make sure everything works.
Prerequisites
1. Clone the repository and step into it
git clone https://github.com/MeteorOps/crossplane-aws-provider-bootstrap.git cd crossplane-aws-provider-bootstrap
2. Make sure you have the required CLIs:
- Install the AWS CLI & Authenticate it with your AWS Account
- Install the Kubectl CLI
- Install the Helm CLI
- An existing Kubernetes cluster (we’ll be using kind)
Optional: Start a local kind cluster
brew install kind
kind create cluster
open /Applications/Docker.app
kubectl cluster-info --context kind-kind
Repository Overview
Link to the Github Repository: https://github.com/MeteorOps/crossplane-aws-provider-bootstrap.git
-
creds
file AWS credentials - should be filled with your own AWS credentials -
crossplane-provider-conf
file Uses the creds file to create a Crossplane ProviderConfig (separated into a different file because it takes time for this resource to be ready) -
crossplane-provider-bootstrap
file Creates the Crossplane AWS Provider, which enables creating AWS resources using Crossplane (and its dependencies):ServiceAccount, DeploymentRuntimeConfig, Provider, ClusterRole & ClusterRoleBindings -
bucket-definitions
&bucket-crd
files The Kubernetes Crossplane manifests that create a CompositeResourceDefinition and a Composition resource, which together define how to create a S3 Bucket (like a Terraform Module would). Note: The ‘Composition’ resource relies on the ‘CompositeResourceDefinition’. -
bucket-example
file The Kubernetes Crossplane manifest we’ll apply at the end to create a S3 bucket using Crossplane
Deploy Crossplane
1. Fill the creds file with your AWS access keys
Get your AWS IAM User (not an SSO user as it requires a token to work) access keys and fill them in the credentials file
- NOTE: for production usage, please create a Crossplane IAM user and use its access keys, or preferably use something like IRSA
2. Deploy the Crossplane Helm Chart
Add the Helm repository from which the Crossplane Helm Charts will be fetched
helm repo add crossplane-stable https://charts.crossplane.io/stable
Deploy Crossplane on your Kubernetes cluster in a new namespace named crossplane-system
helm install crossplane crossplane-stable/crossplane --namespace crossplane-system --create-namespace
3. Examine your Crossplane Deployment
-
Run the following command to get Crossplane's pods:
kubectl get pods -n crossplane-system
Then, you should see 2 pods: crossplane & crossplane-rbac-manager
4. Provide Crossplane AWS access by creating a Kubernetes Secret
Insert your AWS credentials to the creds file and run the following from the same folder:
kubectl create secret generic aws-credentials -n crossplane-system --from-file=creds=./creds
Make sure the secret was created as expected:
-
Run the following command:
kubectl get secret aws-credentials -n crossplane-system
You should see the aws-credentials secret:
5. Deploy the Crossplane AWS Provider
Creating a Crossplane AWS Provider requires creating a bunch of resources: ServiceAccount, DeploymentRuntimeConfig, Provider, ClusterRole & ClusterRoleBindings, and ProviderConfig
We divided the resources creation into 2 phases:
1 - crossplane-provider-bootstrap.yaml
:
ServiceAccount, DeploymentRuntimeConfig, Provider, ClusterRole & ClusterRoleBindings
2- crossplane-provider-conf.yaml
:
ProviderConfig
The reason for dividing it into 2 phases is that the creation of the ProviderConfig fails if we attempt to create it before the first set of Provider resources and dependencies is ready
Create the Provider Kubernetes resources using the bootstrap YAML file:
-
Run the following command:
kubectl apply -f crossplane-provider-bootstrap.yaml
Validate the creation readiness of the Provider & wait for it to be ready:
-
Run the following command to see the AWS Provider resource:
kubectl get provider
You should see something like this:
It might take 1-2 minutes to become Healthy.
Create the ProviderConfig resource & Validate its creation:
-
Run the following command:
kubectl apply -f crossplane-provider-conf.yaml && kubectl get providerconfig
Create a S3 Bucket using Crossplane
Create the CompositeResourceDefinition to define a S3 Bucket:
-
Run the following command:
kubectl apply -f bucket-definitions.yaml
Create the Composition to define a S3 Bucket:
-
Run the following command:
kubectl apply -f bucket-crd.yaml
Create the S3 Bucket Crossplane resource in Kubernetes:
kubectl apply -f bucket-example.yaml
When we installed the AWS Provider, it was installed with some Crossplane CRDs of the AWS Provider.
One of those CRDs is ‘bucket’.
Now we can check if the bucket was created by running kubectl get bucket
against our Kubernetes cluster
Check if the S3 Bucket was created in AWS:
-
List you AWS S3 buckets and search for the newly created one:
aws s3 ls
Teardown & Cleanup
We’ll start by deleting the S3 Bucket Crossplane resource in Kubernetes, which will end up deleting the resource in AWS.
Eventually, if we used kind
to spin up a local Kubernetes cluster, we’ll terminate the cluster to keep our workstation nice and clean.
Delete the S3 Bucket resource:
kubectl delete -f bucket-example.yaml
If used kind delete the cluster:
kind delete cluster
Useful Debugging Commands
kubectl get provider
kubectl logs -n crossplane-system deploy/crossplane -c crossplane
kubectl logs -n crossplane-system -l pkg.crossplane.io/provider=provider-aws
Top comments (2)
Thank you for writing this article. I work with Kubernetes and Terraform daily to manage AWS resources, but they remain fairly separate in my workflow. Crossplane caught my interest as a way to bridge this gap, allowing more direct interaction between Kubernetes and AWS, rather than having to update Terraform whenever Kubernetes resources change. I really appreciate the repository and the clear instructions for getting everything up and running in your article.
One thing that stood out to me as a potential concern was the use of Kubernetes secrets to store an IAM user's access keys. A more secure approach would be to create a service account tied to an IAM role. However, I understand the challenges involved in setting up such a solution, particularly when dealing with a "chicken and egg" scenario. I assume this method was used for the sake of simplicity in the article. It might be helpful to note that this isn’t the ideal long-term solution and to reference more secure alternatives for handling authentication even if they're not fully detailed.
While I felt like I was beginning to grasp Crossplane, this article made me realize how much I still have to learn and clarified some misconceptions I had. I guess it’s time to dive deeper and fully immerse myself in it!
awesome article @arthurazr_46 !