Introduction
During Christmas, I had some extra time on my hands - a perfect opportunity to catch up on tech I’d been meaning to explore. A few colleagues had been discussing about Crossplane recently, and it got me curious. What is it really about? How does it fit into the Kubernetes ecosystem? And most importantly, could it simplify the way we manage cloud infrastructure?
So, I decided to dive in and set up a small lab environment to get a better understanding of Crossplane, especially its integration with AWS. In this article, I’ll walk you through my experience, breaking down the setup process and sharing insights along the way. If you’ve been wondering about Crossplane too, this might be the perfect starting point!
For a deeper dive into Crossplane’s capabilities, you can also check out the official Crossplane documentation:
Setting Up Minikube on macOS
Before diving into Crossplane, we need a local Kubernetes cluster to get things up and running. Minikube is an excellent choice for this purpose, especially for testing and small-scale setups. Here's how you can install and configure Minikube on your MacBook with macOS.
Why Minikube?
Minikube is a lightweight Kubernetes distribution designed for local environments. It’s perfect for experimenting with Kubernetes features and tools like Crossplane without requiring a full-blown cloud setup. It also integrates seamlessly with Docker, making it an easy and efficient way to spin up a cluster on your local machine.
Installation Steps
Here’s a step-by-step guide to setting up Minikube on macOS:
- Install Minikube
Use Homebrew to install Minikube:brew install minikube
- Install kubectl
Kubernetes' command-line tool,kubectl
, is essential for interacting with your cluster. Install it via Homebrew:brew install kubectl
- Install Helm (Kubernetes Package Manager)
Helm, the Kubernetes package manager, will be needed later for deploying applications. Install it with:brew install helm
- Start Minikube
Once Minikube is installed, start your cluster withminikube start
alexanderhose ~ % minikube start
😄 minikube v1.34.0 on Darwin 15.0 (arm64)
✨ Automatically selected the docker driver
📌 Using Docker Desktop driver with root privileges
👍 Starting "minikube" primary control-plane node in "minikube" cluster
🚜 Pulling base image v0.0.45 ...
💾 Downloading Kubernetes v1.31.0 preload ...
> gcr.io/k8s-minikube/kicbase...: 441.45 MiB / 441.45 MiB 100.00% 10.57 M
> preloaded-images-k8s-v18-v1...: 307.61 MiB / 307.61 MiB 100.00% 5.40 Mi
🔥 Creating docker container (CPUs=2, Memory=2200MB) ...
🐳 Preparing Kubernetes v1.31.0 on Docker 27.2.0 ...
▪ Generating certificates and keys ...
▪ Booting up control plane ...
▪ Configuring RBAC rules ...
🔗 Configuring bridge CNI (Container Networking Interface) ...
🔎 Verifying Kubernetes components...
▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
🌟 Enabled addons: storage-provisioner, default-storageclass
🏄 Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
Here's what you can expect during startup:
- Minikube will automatically detect and select Docker as the driver.
- It will pull the necessary base images and configure the cluster.
Verifying the Kubernetes Cluster Installation
Once you’ve installed Minikube, kubectl
, and Helm, it’s important to verify that your Kubernetes cluster is running properly. Use the following command to check the status of the cluster:
alexanderhose ~ % kubectl cluster-info
Kubernetes control plane is running at https://127.0.0.1:57085
CoreDNS is running at https://127.0.0.1:57085/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
Adding the Crossplane Helm Repository
With the Kubernetes cluster verified, the next step is to prepare for Crossplane installation. Helm will help us install Crossplane and manage its lifecycle.
- Add the Crossplane Helm Repository
Add the official Crossplane Helm chart repository - Update the Helm Repository
After adding the Crossplane repository, ensure it’s up to date - List the Helm Repositories
Confirm that the Crossplane repository has been successfully added
alexanderhose ~ % helm repo add crossplane-stable https://charts.crossplane.io/stable
"crossplane-stable" has been added to your repositories
alexanderhose ~ % helm repo update
Hang tight while we grab the latest from your chart repositories...
alexanderhose ~ % helm repo list
NAME URL
crossplane-stable https://charts.crossplane.io/stable
Installing Crossplane
Now that we’ve added the Crossplane Helm repository, the next step is to install Crossplane itself. Crossplane is a Kubernetes add-on that simplifies cloud infrastructure management. It allows you to define infrastructure resources declaratively using Kubernetes manifests. In this section, we’ll install Crossplane into our Minikube cluster and verify that it’s running correctly.
Step 1: Install Crossplane Using Helm
Run the following command to install Crossplane:
alexanderhose ~ % helm install crossplane \
--namespace crossplane-system \
--create-namespace crossplane-stable/crossplane
NAME: crossplane
LAST DEPLOYED: Fri Jan 3 23:00:05 2025
NAMESPACE: crossplane-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Release: crossplane
Chart Name: crossplane
Chart Description: Crossplane is an open source Kubernetes add-on that enables platform teams to assemble infrastructure from multiple vendors, and expose higher level self-service APIs for application teams to consume.
Chart Version: 1.18.2
Chart Application Version: 1.18.2
Kube Version: v1.31.0
Here’s what this command does:
crossplane
: The release name for the Helm installation.--namespace crossplane-system
: Installs Crossplane in a dedicated namespace calledcrossplane-system
.--create-namespace
: Creates the namespace if it doesn’t already exist.crossplane-stable/crossplane
: Specifies the Crossplane chart from the previously added repository
Step 2: Verify the Deployment
Next, verify that the Crossplane pods are running:
alexanderhose ~ % kubectl get pods -n crossplane-system
NAME READY STATUS RESTARTS AGE
crossplane-76596b6bcd-724mq 1/1 Running 0 51s
crossplane-rbac-manager-787f89744d-xckhj 1/1 Running 0 51s
This confirms that:
- The
crossplane
pod is running, which serves as the core Crossplane component. - The
crossplane-rbac-manager
pod is running, managing the necessary Role-Based Access Control (RBAC) permissions.
Interacting with the Crossplane Cluster
With Crossplane installed and running, it’s time to configure it to interact with AWS. This involves changing the Kubernetes context for easier management, creating an AWS credentials secret, and verifying the configuration.
Step 1: Set the Kubernetes Context
To streamline our interaction with the Crossplane cluster, we can set the default namespace for kubectl
to crossplane-system
. This saves us from repeatedly specifying the namespace in our commands:
alexanderhose ~ % kubectl config set-context --current --namespace=crossplane-system
Context "minikube" modified.
From this point forward, all kubectl
commands will target the crossplane-system
namespace by default.
Step 2: Generate AWS Service Account Keys
For Crossplane to manage AWS resources, it requires access credentials. Ensure you have an AWS user with CLI access and the necessary permissions for managing resources (e.g., AdministratorAccess
or fine-tuned IAM policies). Generate the access keys and store them in a file named aws-credentials.txt
with the following format:
Replace EXAMPLEACCESSKEY
and EXAMPLESECRET
with your actual AWS access and secret keys
Step 3: Create a Kubernetes Secret
Add the AWS credentials as a Kubernetes secret to the crossplane-system
namespace. This command creates a secret named aws-secret
and stores the credentials securely.
alexanderhose ~ % kubectl create secret generic aws-secret --from-file=creds=./aws-credentials.txt
secret/aws-secret created
alexanderhose ~ % kubectl describe secret aws-secret
Name: aws-secret
Namespace: crossplane-system
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
creds: 115 bytes
Step 4: Decode and Verify the Secret
You can decode the secret to verify its contents (for debugging purposes or validation). Decoding confirms that the secret was created correctly and contains the expected AWS credentials.
alexanderhose ~ % kubectl get secrets/aws-secret --template={{.data.creds}} | base64 -d
[default]
aws_access_key_id = EXAMPLEACCESSKEY
aws_secret_access_key = EXAMPLESECRET
Installing Providers for AWS S3 and SSM
With Crossplane installed and AWS credentials configured, the next step is to install the necessary providers. Providers act as the bridge between Crossplane and cloud services, enabling you to manage resources like S3 buckets and SSM directly from Kubernetes.
Step 1: Install the AWS Providers
Crossplane requires a provider to interact with each specific AWS service. For this example, we’ll install providers for S3 and SSM (Systems Manager).
Save the following YAML files for the AWS providers:
Run the following commands to install the providers. These commands install the S3 and SSM providers into the crossplane-system
namespace.
alexanderhose ~ % kubectl apply -f ./aws-s3-provider.yaml
provider.pkg.crossplane.io/provider-aws-s3 created
alexanderhose ~ % kubectl apply -f ./aws-ssm-provider.yaml
provider.pkg.crossplane.io/aws-provider-ssm created
Step 2: Configure the AWS Provider
After installing the providers, you need to configure them with the credentials stored in the secret we created earlier.
Save the following YAML files for the AWS configuration:
Run the following command. This step configures Crossplane to use the aws-secret
for interacting with AWS resources.
alexanderhose ~ % kubectl apply -f ./aws-provider-config.yaml
providerconfig.aws.upbound.io/provider-aws created
This configuration does the following:
- Specifies
default
as the provider configuration name, which will be referenced in all AWS resource manifests. - Points to the
aws-secret
containing your AWS credentials in thecrossplane-system
namespace.
Before moving forward, it’s always a good idea to confirm that everything was deployed as expected. You can check the deployments in the crossplane-system
namespace with:
alexanderhose ~ % kubectl get deployments -n crossplane-system
NAME READY UP-TO-DATE AVAILABLE AGE
aws-provider-ssm 1/1 1 1 95s
crossplane 1/1 1 1 20h
crossplane-rbac-manager 1/1 1 1 20h
provider-aws-s3 1/1 1 1 88s
upbound-provider-family-aws 1/1 1 1 103s
Deploying Your First Resource
Now that Crossplane is up and running with the necessary providers, it’s time to deploy our first AWS resource: an S3 bucket. This step will demonstrate how you can define cloud resources using Kubernetes manifests and let Crossplane handle the provisioning.
Create the S3 Bucket Manifest
First, create a file named s3-bucket.yaml
with the following content:
Here’s a quick breakdown of the manifest:
apiVersion
andkind
: These specify the type of resource, in this case, an S3 bucket.metadata
: Includes a name (crossplane-bucket
) and a label for tracking purposes.spec.forProvider
: Defines specific configuration details for the bucket, like the region (us-west-1
).
Deploy the S3 Bucket
Apply the manifest to your Kubernetes cluster:
alexanderhose ~ % kubectl apply -f s3-bucket.yaml
bucket.s3.aws.upbound.io/crossplane-bucket created
Now that you’ve successfully deployed your first S3 bucket with Crossplane, consider exploring how to automate additional AWS resources like SSM documents, RDS or Lambda.
Troubleshooting Deployment Issues
Sometimes, things might not go as planned. To check the details of your deployment and identify potential issues, you can use the kubectl describe
command. For example:
alexanderhose ~ % kubectl describe bucket.s3.aws.upbound.io/crossplane-bucket
Status:
At Provider:
Conditions:
Last Transition Time: 2025-01-04T20:32:35Z
Message: connect failed: cannot initialize the Terraform plugin SDK async external client: cannot get terraform setup: cannot get referenced ProviderConfig: "default": ProviderConfig.aws.upbound.io "default" not found
Reason: ReconcileError
Status: False
Type: Synced
In this case, the Message
field clearly indicates that the provider configuration is missing or incorrect. The key point here is to check if the metadata name of the ProviderConfig
is default
.
Frequently Asked Questions (FAQs)
1. What is Crossplane?
Crossplane is an open-source Kubernetes add-on that enables you to manage cloud infrastructure using Kubernetes manifests. It lets you declaratively provision and manage resources across multiple cloud providers, such as AWS, GCP, and Azure, directly from your Kubernetes cluster.
2. How do I integrate Crossplane with other AWS services?
To integrate Crossplane with AWS, you need to:
- Deploy specific providers, such as for EC2 or Lambda, to your Kubernetes cluster. Check https://marketplace.upbound.io for additional providers.
- Apply Kubernetes manifests for AWS resources like EC2 or Lambda, referencing the appropriate provider.
In short, you create providers and apply them in your Kubernetes cluster to establish a connection with additional AWS services.
3. Can I use Minikube for Crossplane in production?
No, you should not use Minikube for production environments. Minikube is designed for local development and testing purposes. For production use cases, you should deploy Crossplane in a robust Kubernetes environment, such as Amazon EKS, Google GKE, or Azure AKS, that supports high availability and scalability.
Member discussion