Deploy AWS Resources using Crossplane on Kubernetes

Deploy AWS Resources using Crossplane on Kubernetes

Deploy AWS resources on Kubernetes with Helm and Crossplane. Step-by-step guide to configure the AWS provider and create a S3 bucket.

Arthur Azrieli
Book Icon - Software Webflow Template
12
 min read

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

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:

  1. Install the AWS CLI & Authenticate it with your AWS Account
  2. Install the Kubectl CLI
  3. Install the Helm CLI
  4. 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

  1. creds file
    AWS credentials - should be filled with your own AWS credentials
  2. 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)
  3. crossplane-provider-bootstrap file
    Creates the Crossplane AWS Provider, which enables creating AWS resources using Crossplane (and its dependencies):
    ServiceAccount, DeploymentRuntimeConfig, Provider, ClusterRole & ClusterRoleBindings
  4. 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.
  5. 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