Installation
I will use k3s for this demo and follow the official installation guide.
I will install Crossplane in newly Kubernetes cluster:
# Add the Crossplane Helm repository
helm repo add crossplane-stable https://charts.crossplane.io/stable
helm repo update
# Install Crossplane
helm upgrade -i crossplane \
--namespace crossplane-system \
--create-namespace \
crossplane-stable/crossplane
# Set the context to crossplane-system namespace
kubectl config set-context --namespace default --current
Verify the installation:
kubectl get pods -n crossplane-system
I should see pods like crossplane-* and crossplane-rbac-manager-* running.
Installing AWS Family Providers
AWS family providers are specialized providers for different AWS services, providing better resource coverage and more focused functionality. I will install them:
First, I’ll clone the demo repository to get the required YAML files:
git clone https://github.com/mariobris/crossplane-demo
cd crossplane-demo
Then apply the AWS family providers:
kubectl apply -f provider-aws.yaml
The provider-aws.yaml file defines the AWS family providers needed for this demo. It includes separate providers for S3 and EC2. Each provider manages only its specific AWS service, which helps keep things simple and focused.
Check installed API resources:
kubectl api-resources --categories=crossplane
Investigate the VPC resrource specification:
kubectl explain vpc.spec.forProvider
Provider Configuration
To allow the AWS family providers to communicate with AWS services, I must configure authentication. This is done using a ProviderConfig resource, which tells the providers how to authenticate with AWS.
AWS Authentication Setup
Note: I need valid AWS credentials with sufficient permissions to work with AWS resources. For this demo, I’m using an IAM User with with full access to AWS services.
- Create AWS credentials file:
cat > aws-credentials.txt << EOF
[default]
aws_access_key_id = <your-access-key>
aws_secret_access_key = <your-secret-key>
EOF
- Create a Kubernetes secret:
kubectl create secret generic aws-creds \
--namespace crossplane-system \
--from-file=secret-key=./aws-credentials.txt
- Apply the provider configuration:
kubectl apply -f providerConfig.yaml
Working with Managed Resources
Managed resources represent external cloud services as Kubernetes objects. Let’s explore how to work with different AWS resources using Crossplane.
Your First Managed Resource
I will create a simple S3 bucket to test the setup using the AWS S3 family provider. I can find the example manifest here.
Important: S3 bucket names must be globally unique in AWS. Before applying the manifest, I’ll open s3.yaml and change the Name field of the resource to a unique value that is not already used by anyone else.
Apply the manifest:
kubectl apply -f manifests/simple/s3.yaml
Check the status:
kubectl get bucket
I can see that the bucket is SYNCED and READY. If it’s not, then follow the troubleshooting section.
Note: This example uses the provider-aws-s3 family provider, which provides specialized S3 functionality.
Creating Multiple Resources
I will create common AWS resources and observe their state:
kubectl apply -f manifests/simple/
Observe resources:
kubectl get managed
I will list the secrets containing connection details for the S3 bucket:
kubectl get bucket
kubectl get secrets -n crossplane-system --field-selector type=connection.crossplane.io/v1alpha1
Delete resources:
kubectl delete -f manifests/simple/
Helm Templating
Simple manifests can be deployed with Kustomize or Helm. I will deploy the same resources with Helm now:
helm upgrade -i -n default simple manifests/helm/
Observe the created resources and review the values.yaml file:
kubectl get managed
Delete resources:
helm uninstall -n default simple
Resource Dependencies
Crossplane handles resource dependencies through selectors. For example, when creating an EC2 instance, you might need:
- VPC
- Subnet (with VPC selector)
- Instance (with subnet selectors)
- InstanceState (with instance selectors)
Crossplane uses selectors like vpcIdSelector and subnetIdSelector to reference other resources to pass values between resources. The creation order is determined by these explicit references, not automatic dependency detection.
Example: Using Selectors
First, create a VPC with the required label:
apiVersion: ec2.aws.upbound.io/v1beta1
kind: VPC
metadata:
name: demo-vpc
labels:
app: demo-vpc
spec:
forProvider:
region: us-east-1
cidrBlock: 192.168.0.0/16
providerConfigRef:
name: user-keys
Then create a Subnet that references the VPC using a selector:
apiVersion: ec2.aws.upbound.io/v1beta1
kind: Subnet
metadata:
name: demo-subnet
spec:
forProvider:
vpcIdSelector:
matchLabels:
app: demo-vpc
cidrBlock: 192.168.0.0/24
region: us-east-1
providerConfigRef:
name: user-keys
Note: The vpcIdSelector tells Crossplane to find the VPC resource with the label app: demo-vpc and use its ID for the subnet’s VPC reference.
Best Practices
Resource Naming
Use consistent Kubernetes naming conventions:
metadata:
name: ${environment}-${service}-${resource-type}-${identifier}
Tagging Strategy
Implement consistent AWS tagging:
tags:
Name: ${resource-name}
Environment: ${environment}
Project: ${project}
Owner: ${team}
Resource Organization
Organize resources by environment or project using namespaces or labels.
Troubleshooting
When working with Crossplane, you may encounter various issues. Here’s a systematic approach to diagnose and resolve common problems:
1. Komoplane
See the Komoplane section
2. Check Provider Status
First, verify that your providers are properly installed and healthy:
kubectl get -n crossplane-system provider
kubectl describe -n crossplane-system provider <provider-name>
3. View Provider Logs
Check provider logs for detailed error messages:
kubectl get -n crossplane-system pods
kubectl logs -n crossplane-system <pod-name>
4. Monitor Resource Status
Check the status of your managed resources:
# Check resource status
kubectl get managed
# Check specific resource status
kubectl describe <managed-resource-name>
# Check resource events
kubectl get events --sort-by='.lastTimestamp' -A
Resources
- Crossplane Demo Repository - Contains all the YAML files used in this tutorial