
Crossplane on AWS | Building a Multi-Cloud Kubernetes Control Plane
Infrastructure as Code · Kubernetes · Crossplane · Multi-Cloud · Platform Engineering
Modern platform teams are increasingly looking for ways to give developers a simple interface for consuming infrastructure without exposing the complexity of the underlying cloud platforms.
A developer shouldn't necessarily need to understand every detail of an AWS VPC, IAM configuration, S3 bucket, database, load balancer, or Kubernetes cluster just to deploy an application.
This is where Crossplane becomes particularly interesting.
Crossplane is a control plane framework for platform engineering. It extends the Kubernetes API and reconciliation model so that Kubernetes can manage resources outside the cluster. Crossplane Providers connect the control plane to external services such as AWS, Azure, and Google Cloud.
In this article, I’ll walk through an architecture where AWS hosts the Crossplane control plane, while Crossplane manages infrastructure across AWS and can extend the same platform model to other clouds.
The goal is not simply to provision cloud resources.
The goal is to build an internal developer platform where infrastructure is consumed through Kubernetes-native APIs.
Architecture Overview
The architecture starts with developers working with GitHub.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Developers
│
▼
GitHub
│
▼
GitOps
│
▼
┌─────────────────────────────────────┐
│ AWS │
│ │
│ EKS Cluster │
│ │ │
│ ▼ │
│ Crossplane │
│ │ │
│ ┌───────┼────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ AWS GCP Azure │
│ Resources Resources Resources │
└─────────────────────────────────────┘The EKS cluster acts as the Kubernetes-based control plane.
Crossplane watches Kubernetes resources and continuously reconciles them against external infrastructure.
For example, a Kubernetes resource can represent an S3 bucket, database, network, or other cloud resource.
This creates a consistent workflow:
Git → Kubernetes API → Crossplane → Cloud Provider
Why Crossplane?
Traditional infrastructure workflows often separate application deployment and infrastructure provisioning.
A common architecture looks like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Application Git
│
▼
GitOps
│
▼
Kubernetes
Infrastructure Git
│
▼
Terraform
│
▼
AWSThis works well, but platform teams may eventually end up maintaining multiple systems, workflows, state models, and abstractions.
Crossplane takes a different approach.
Infrastructure becomes part of the Kubernetes control plane.
1
2
3
4
5
6
7
8
9
10
11
12
Kubernetes API
│
┌──────────┴──────────┐
│ │
Applications Infrastructure
│ │
▼ ▼
Kubernetes Crossplane
│
┌─────────────┼─────────────┐
▼ ▼ ▼
AWS GCP AzureCrossplane Providers expose external infrastructure APIs through Kubernetes resources and controllers. Providers continuously reconcile the desired state with the external service.
This creates a powerful platform engineering model:
Kubernetes becomes the interface through which developers consume infrastructure.
1. EKS as the Control Plane
The first component is an EKS cluster running Crossplane.
1
2
3
4
5
6
7
8
AWS Account
│
└── EKS Cluster
│
├── Crossplane
├── Providers
├── Composition Functions
└── Platform APIsThe EKS cluster doesn't necessarily run the application workloads.
Instead, it can serve as a dedicated management cluster.
This separation is useful because the lifecycle of the platform control plane can be managed independently from the workloads it provisions.
The control plane becomes responsible for:
- Infrastructure APIs
- Provider controllers
- Platform abstractions
- Composition logic
- Credentials and permissions
- Resource reconciliation
- Environment provisioning
Crossplane's current documentation describes this model as a control plane framework for platform engineering.
2. Crossplane Providers
Crossplane itself does not directly know how to create every cloud resource.
Providers extend Crossplane.
A Provider connects Crossplane to an external API and exposes resources through Kubernetes APIs.
Examples include:
- AWS
- Azure
- Google Cloud
- Kubernetes
- Other APIs and infrastructure platforms
Conceptually:
1
2
3
4
5
6
7
8
9
Crossplane
│
┌────────────┼────────────┐
│ │ │
▼ ▼ ▼
AWS Provider GCP Provider Azure Provider
│ │ │
▼ ▼ ▼
AWS GCP AzureThis is what allows the same Kubernetes-based control-plane model to manage infrastructure across multiple platforms.
3. Managed Resources
Once a Provider is installed, Crossplane exposes APIs representing external resources.
These are called Managed Resources.
For example:
1
2
3
4
5
6
7
Kubernetes API
│
▼
AWS S3 Bucket
│
▼
Amazon S3The Kubernetes object describes the desired state.
Crossplane's provider controller observes that state and reconciles the corresponding resource in AWS.
This is one of the fundamental differences between Crossplane and a simple provisioning script.
The controller continues watching the resource rather than treating provisioning as a one-time operation.
4. Declarative Infrastructure
Consider an application that requires object storage.
Instead of developers manually creating an S3 bucket, the platform can expose a Kubernetes API.
A simplified resource might look like:
1
2
3
4
5
6
7
apiVersion: s3.aws.m.upbound.io/v1beta1
kind: Bucket
metadata:
name: application-storage
spec:
forProvider:
region: eu-west-2The exact API version and Provider package depend on the Crossplane AWS provider implementation being used.
The important concept is the workflow:
1
2
3
4
5
6
7
8
9
10
11
12
13
YAML
│
▼
Kubernetes API
│
▼
Crossplane
│
▼
AWS Provider
│
▼
Amazon S3The developer interacts with Kubernetes.
Crossplane handles the external infrastructure lifecycle.
5. From Infrastructure APIs to Platform APIs
Directly exposing every AWS resource to developers is not necessarily the best platform design.
Developers usually don't need to know how many AWS resources are required to create an application environment.
For example, an application environment might require:
1
2
3
4
5
6
7
Network
Database
Object Storage
IAM
Secrets
Load Balancer
DNSInstead of exposing all of these independently, a platform team can create a higher-level API.
For example:
1
2
3
4
5
6
7
8
apiVersion: platform.example.com/v1alpha1
kind: ApplicationEnvironment
metadata:
name: payments-dev
spec:
region: eu-west-2
database: postgres
storage: s3The developer requests an ApplicationEnvironment.
The platform decides what infrastructure that environment requires.
This is where Crossplane Compositions become important.
6. XRDs, XRs, and Compositions
Crossplane provides several concepts for building higher-level platform APIs.
Composite Resource Definition — XRD
An XRD defines a custom API.
For example:
1
ApplicationEnvironmentThe XRD defines what fields users are allowed to provide.
Composite Resource — XR
The XR represents an instance of that custom API.
For example:
1
payments-devComposition
The Composition defines how the requested platform resource maps to underlying resources.
Crossplane's documentation describes a Composition as a template for creating multiple Kubernetes resources as a single composite resource.
Conceptually:
1
2
3
4
5
6
7
8
ApplicationEnvironment
│
▼
Composition
│
┌────┼────┬────┐
▼ ▼ ▼ ▼
VPC DB S3 IAMThe developer sees one API.
The platform team manages the implementation.
7. Composition Functions
Current Crossplane versions use Composition Functions as part of the composition pipeline.
Functions can generate and transform the resources that make up a composite resource.
Crossplane provides functions and SDKs for building custom functions, including implementations using technologies such as Go and Python.
This gives platform engineers another abstraction layer:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Developer Request
│
▼
Custom Platform API
│
▼
Composition Pipeline
│
▼
Composition Functions
│
▼
Managed Resources
│
▼
Cloud InfrastructureThe platform API therefore becomes independent from the underlying implementation details.
8. Example: Application Environment
Imagine a developer requests:
1
2
3
4
5
6
7
8
9
10
apiVersion: platform.example.com/v1alpha1
kind: ApplicationEnvironment
metadata:
name: payments-dev
spec:
region: eu-west-2
database:
type: postgres
storage:
type: objectThe platform could translate this into:
1
2
3
4
5
6
7
8
9
10
ApplicationEnvironment
│
▼
Crossplane
│
├── VPC
├── PostgreSQL
├── S3
├── IAM
└── Network configurationThe developer doesn't need to understand the implementation.
The platform team owns the platform contract.
This is the core idea behind Infrastructure as a Product.
9. Multi-Cloud Architecture
Crossplane can also be used to build a multi-cloud control plane.
The architecture from the diagram can be extended as:
1
2
3
4
5
6
7
8
9
10
Crossplane
│
┌─────────────┼─────────────┐
│ │ │
▼ ▼ ▼
AWS GCP Azure
│ │ │
┌────┼────┐ │ ┌────┼────┐
▼ ▼ ▼ ▼ ▼ ▼ ▼
S3 DB VPC GKE Storage NetworkA platform team can create higher-level APIs that abstract away the cloud-specific implementation.
For example:
1
2
3
4
5
kind: ApplicationEnvironment
spec:
cloud: aws
region: eu-west-2or:
1
2
3
4
5
kind: ApplicationEnvironment
spec:
cloud: gcp
region: europe-west2The API remains conceptually similar while the Composition determines which provider resources are created.
This does not mean that every cloud becomes identical. Cloud services have different capabilities, APIs, pricing models, and operational characteristics.
The goal is to standardize the platform experience, not hide every cloud-specific difference.
10. GitOps
GitHub can act as the source of truth for the platform configuration.
A typical workflow is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Developer
│
▼
GitHub
│
▼
Argo CD
│
▼
Kubernetes API
│
▼
Crossplane
│
▼
Cloud InfrastructureA developer submits a pull request.
After the change is approved and merged, GitOps applies the Kubernetes resources.
Crossplane then reconciles those resources against the cloud APIs.
This creates two complementary reconciliation loops:
1
2
3
4
5
6
7
8
9
10
11
12
13
Git
│
▼
Argo CD
│
▼
Kubernetes
│
▼
Crossplane
│
▼
CloudArgo CD reconciles Git with Kubernetes.
Crossplane reconciles Kubernetes desired state with external infrastructure.
11. Continuous Reconciliation
One of the most important concepts in Crossplane is reconciliation.
The desired state is represented by Kubernetes resources.
Crossplane continuously observes the external resource and attempts to make reality match the desired state.
Conceptually:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Desired State
│
▼
Kubernetes
│
▼
Crossplane
│
▼
External Resource
│
│
└─────── observe
│
▼
ReconcileIf the external resource differs from the desired state, Crossplane can detect that difference and reconcile it according to the Provider and resource configuration.
This controller-based model is central to Crossplane's architecture.
12. Credentials and Cloud Access
A production platform must carefully design how Crossplane authenticates to cloud providers.
The architecture should avoid distributing long-lived cloud credentials to developers.
Instead:
1
2
3
4
5
6
7
8
9
Developer
│
│ Kubernetes API
▼
Crossplane
│
│ Cloud identity
▼
AWSAccess should follow least-privilege principles.
The Crossplane documentation supports provider configuration for connecting providers to external services and documents provider-specific authentication mechanisms.
For AWS deployments, the identity model should be designed around the security capabilities of the AWS environment rather than embedding credentials into application repositories.
13. Connection Details
Some infrastructure resources produce information that applications need.
For example:
1
2
3
4
5
Database
│
├── Endpoint
├── Username
└── PasswordCrossplane supports connection details for composite resources, allowing information such as database connection strings, credentials, certificates, and endpoints to be exposed through Kubernetes Secrets.
The resulting workflow can look like:
1
2
3
4
5
6
7
8
9
10
11
12
13
Crossplane
│
▼
Database
│
▼
Connection Details
│
▼
Kubernetes Secret
│
▼
ApplicationThis creates a standardized mechanism for passing infrastructure outputs to workloads.
Secrets should still be handled according to the organization's security requirements, including appropriate encryption, access controls, rotation, and secret-management practices.
14. Crossplane and Terraform
Crossplane does not necessarily mean Terraform must disappear.
Both tools can have a role in a platform architecture.
For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Terraform
│
▼
Platform Foundation
│
├── VPC
├── EKS
├── IAM
└── Bootstrap
│
▼
Crossplane
│
├── Databases
├── Storage
├── Application infrastructure
└── Platform environmentsOne possible model is:
Terraform provisions the foundational platform.
Crossplane manages infrastructure consumed through the platform API.
This is not a requirement; organizations can choose different boundaries.
The important architectural question is:
Which system owns which resources?
Clear ownership prevents two controllers or provisioning systems from attempting to manage the same resource.
15. Platform Engineering Model
The real value of Crossplane appears when it is combined with platform engineering practices.
Instead of giving developers direct access to dozens of infrastructure APIs, the platform team creates a small number of well-designed APIs.
For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
Platform API
│
┌────────────────┼────────────────┐
│ │ │
▼ ▼ ▼
Application Database Kubernetes
Environment Service Cluster
│ │ │
▼ ▼ ▼
Crossplane Crossplane Crossplane
│ │ │
▼ ▼ ▼
AWS AWS AWSThe platform becomes an abstraction layer between developers and infrastructure.
This is particularly useful for organizations that want standardized environments while still allowing the underlying infrastructure to evolve.
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article