Skip to main content
/ Cloud

Crossplane in 2026: Why Kubernetes Teams Are Ditching Terraform

Sacha Roussakis-NotterSacha Roussakis-Notter
18 min read
Kubernetes
Terraform
Share

A deep dive into Crossplane, the CNCF-graduated Kubernetes-native infrastructure tool. Compare Crossplane vs Terraform vs Pulumi, learn when to use each, and see production patterns for platform engineering.

The Infrastructure Control Plane Revolution

In October 2025, Crossplane achieved CNCF Graduation — joining the ranks of Kubernetes, Prometheus, and Helm as a production-ready, battle-tested project. With the release of Crossplane v2.0 in August 2025, the project has fundamentally changed how platform teams think about infrastructure management.

The core premise is simple but transformative: What if your Kubernetes cluster could manage not just pods, but your entire cloud infrastructure?

flowchart

Separate tools, separate state

Unified control plane

Crossplane Approach

Kubernetes + Crossplane

Cloud Resources

Containers

Databases

Networking

Traditional Approach

Terraform

State File

Cloud Resources

Kubernetes

Containers

Gap between App and Infra

Single Source of Truth

Ctrl+scroll to zoom • Drag to pan40%

What is Crossplane?

Crossplane is a control plane framework that extends Kubernetes to manage any infrastructure resource. Instead of treating infrastructure as code that runs separately, Crossplane treats infrastructure as Kubernetes resources — subject to the same reconciliation, RBAC, and GitOps patterns you use for applications.

The Kubernetes Control Loop for Infrastructure

The magic lies in the reconciliation loop. When you apply a Crossplane resource, Kubernetes continuously ensures the actual cloud state matches your desired state:

yaml
1# This is a Kubernetes manifest, not a Terraform file
2apiVersion: s3.aws.upbound.io/v1beta1
3kind: Bucket
4metadata:
5 name: my-application-data
6 namespace: team-backend
7spec:
8 forProvider:
9 region: ap-southeast-2
10 versioning:
11 enabled: true
12 serverSideEncryptionConfiguration:
13 - rule:
14 applyServerSideEncryptionByDefault:
15 sseAlgorithm: AES256

Apply this with kubectl apply, and Crossplane:

  1. Creates the S3 bucket in AWS
  2. Continuously monitors for drift
  3. Automatically corrects any manual changes
  4. Reports status back to Kubernetes

No state files. No locking. No separate CLI.

Crossplane v2.0: The 2026 Game Changer

The August 2025 release introduced transformative capabilities:

1. Compose ANY Kubernetes Resource

Previously, compositions could only include Crossplane-managed resources. Now you can combine infrastructure AND native Kubernetes resources:

yaml
1# One composite resource provisions everything
2apiVersion: platform.buun.io/v1alpha1
3kind: Application
4metadata:
5 name: customer-api
6 namespace: production
7spec:
8 database:
9 engine: postgresql
10 size: large
11 replicas: 3
12 monitoring: enabled

This single resource creates:

  • RDS PostgreSQL database
  • Kubernetes Deployment
  • Service and Ingress
  • ConfigMap with connection strings
  • Grafana dashboard
  • PagerDuty alert rules

2. Namespaced Resources by Default

All managed resources are now namespaced, enabling:

  • True multi-tenancy
  • Team-scoped infrastructure
  • Simplified RBAC
yaml
1# Team-scoped database - only team-backend can see/modify
2apiVersion: rds.aws.upbound.io/v1beta1
3kind: Instance
4metadata:
5 name: orders-db
6 namespace: team-backend # Scoped to team
7spec:
8 forProvider:
9 instanceClass: db.t3.medium
10 engine: postgres

3. Composition Functions (Pipeline Mode)

Move beyond static YAML with real programming:

yaml
1apiVersion: apiextensions.crossplane.io/v1
2kind: Composition
3metadata:
4 name: application-with-logic
5spec:
6 compositeTypeRef:
7 apiVersion: platform.buun.io/v1alpha1
8 kind: Application
9 mode: Pipeline
10 pipeline:
11 - step: compute-resources
12 functionRef:
13 name: function-go-templating
14 input:
15 apiVersion: gotemplating.fn.crossplane.io/v1beta1
16 kind: GoTemplate
17 source: Inline
18 inline:
19 template: |
20 {{- $replicas := .observed.composite.resource.spec.replicas }}
21 {{- $size := .observed.composite.resource.spec.database.size }}
22 {{- $cpu := "500m" }}
23 {{- $memory := "1Gi" }}
24 {{- if eq $size "large" }}
25 {{- $cpu = "2000m" }}
26 {{- $memory = "4Gi" }}
27 {{- end }}
28 # Dynamic resource computation based on inputs

Crossplane vs Terraform vs Pulumi: The Real Comparison

This is the question every platform team asks. Here's an honest breakdown:

flowchart

Yes

No

Yes

No

Developers

Ops or DevOps

Yes

No

New Infrastructure Project

Already using Kubernetes?

Want GitOps for infra?

Team background?

Crossplane

Need complex logic?

Pulumi

Terraform

Kubernetes-native, continuous reconciliation, built-in GitOps

Real programming languages, full IDE support, native testing

Largest ecosystem, industry standard, proven at scale

Ctrl+scroll to zoom • Drag to pan22%

Quick Comparison Table

FeatureCrossplaneTerraformPulumi
ParadigmKubernetes control planePlan/Apply workflowPlan/Apply workflow
LanguageYAML (K8s manifests)HCLTypeScript, Python, Go
StateKubernetes etcd (no file)External state filePulumi Cloud or backends
Drift DetectionContinuous, automaticManual on plan/applyManual on preview/up
GitOpsNative (Argo CD, Flux)Requires wrappersRequires CI/CD
DependenciesRequires KubernetesStandaloneStandalone
LicenseApache 2.0BSL (source-available)Apache 2.0
CNCF StatusGraduatedN/AN/A

State Management: The Fundamental Difference

This is where Crossplane fundamentally differs:

Terraform State:

hcl
1# You must configure and manage state
2terraform {
3 backend "s3" {
4 bucket = "my-terraform-state"
5 key = "prod/terraform.tfstate"
6 region = "ap-southeast-2"
7 encrypt = true
8 dynamodb_table = "terraform-locks" # Locking required!
9 }
10}

Crossplane State:

yaml
1# State is just Kubernetes resources - no configuration needed
2# Kubernetes etcd handles everything:
3# - Storage
4# - Locking (via resource versions)
5# - Backup (your cluster backup strategy)
6# - High availability
flowchart

Crossplane State

Terraform State

terraform.tfstate

S3 Backend

DynamoDB Locking

Manual Drift Check

Kubernetes etcd

Built-in HA

Built-in Locking

Continuous Reconciliation

State corruption, lock conflicts

Self-healing, auto drift fix

Ctrl+scroll to zoom • Drag to pan36%

GitOps: Where Crossplane Shines

Crossplane is a first-class GitOps citizen. Your infrastructure is just Kubernetes manifests:

yaml
1# argocd-application.yaml
2apiVersion: argoproj.io/v1alpha1
3kind: Application
4metadata:
5 name: aws-infrastructure
6 namespace: argocd
7spec:
8 project: default
9 source:
10 repoURL: https://github.com/buun-group/infrastructure
11 path: crossplane/production
12 targetRevision: main
13 destination:
14 server: https://kubernetes.default.svc
15 syncPolicy:
16 automated:
17 prune: true
18 selfHeal: true

Argo CD syncs your infrastructure the same way it syncs your applications. No special plugins. No wrapper tools.

When to Use Each Tool

Choose Crossplane When:

  • Already running Kubernetes in production
  • Building an internal developer platform
  • Want GitOps for applications AND infrastructure
  • Need continuous drift detection and remediation
  • Multi-tenant infrastructure requirements
  • Fine-grained RBAC inherited from Kubernetes

Choose Terraform When:

  • No existing Kubernetes infrastructure
  • Team has deep HCL expertise
  • Need the widest provider ecosystem
  • Simple infrastructure without platform needs
  • Organization mandates Terraform

Choose Pulumi When:

  • Developers want TypeScript/Python/Go for infra
  • Need complex conditional logic
  • Want to test infrastructure like application code
  • Building reusable infrastructure libraries

Production Patterns: Platform Engineering with Crossplane

Pattern 1: Self-Service Developer Platform

Developers request infrastructure through simple APIs:

yaml
1# Developer applies this - no cloud console access needed
2apiVersion: database.platform.io/v1alpha1
3kind: PostgreSQL
4metadata:
5 name: orders-db
6 namespace: team-payments
7spec:
8 size: medium # Abstracts away instance types
9 version: "15"
10 backup: daily
11 # Platform team's composition handles:
12 # - Actual RDS configuration
13 # - Security groups
14 # - Parameter groups
15 # - Monitoring
16 # - Backup schedules

Pattern 2: Compliance-by-Default

Compositions enforce organizational standards:

yaml
1# XRD defines what developers can configure
2apiVersion: apiextensions.crossplane.io/v1
3kind: CompositeResourceDefinition
4metadata:
5 name: xdatabases.platform.buun.io
6spec:
7 group: platform.buun.io
8 names:
9 kind: XDatabase
10 plural: xdatabases
11 versions:
12 - name: v1alpha1
13 schema:
14 openAPIV3Schema:
15 type: object
16 properties:
17 spec:
18 type: object
19 required: ["size", "engine"]
20 properties:
21 size:
22 type: string
23 enum: ["small", "medium", "large"] # Limited options
24 engine:
25 type: string
26 enum: ["postgresql", "mysql"] # Approved engines only
27 # Note: No direct instance type selection
28 # No VPC configuration
29 # No security group access
30 # Platform team controls these in Composition

Pattern 3: Multi-Cloud Abstraction

Same API, different cloud implementations:

yaml
1# Developer API is cloud-agnostic
2apiVersion: storage.platform.io/v1alpha1
3kind: ObjectStorage
4metadata:
5 name: app-assets
6spec:
7 region: australia
8 versioning: true
9
10# Platform team maintains multiple compositions:
11# - composition-objectstorage-aws.yaml → S3
12# - composition-objectstorage-azure.yaml → Blob Storage
13# - composition-objectstorage-gcp.yaml → Cloud Storage
flowchart

AWS Account

Azure Sub

GCP Project

Developer API

XRD: ObjectStorage

Cloud Selector

Composition: AWS

Composition: Azure

Composition: GCP

S3 Bucket

Blob Container

Cloud Storage Bucket

Ctrl+scroll to zoom • Drag to pan43%

Real-World Adoption

Crossplane is running in production at:

  • Nike - Internal developer platform
  • Autodesk - Multi-cloud infrastructure
  • Grafana - Self-service cloud resources
  • NASA Science Cloud - Research infrastructure
  • SAP - Enterprise platform engineering
  • IBM - Hybrid cloud management
  • BMW - Connected vehicle infrastructure

Why Enterprises Choose Crossplane

ChallengeTerraform SolutionCrossplane Solution
State corruptionHope + backupsNo state files
Drift accumulationScheduled plansContinuous reconciliation
Developer self-serviceAtlantis + approval gatesNative Kubernetes RBAC
Multi-tenancyWorkspaces (limited)Namespaces (native)
GitOpsWrapper toolsFirst-class support

The Ecosystem in 2026

Providers

Official Upbound Family Providers:

  • provider-family-aws - 200+ AWS services
  • provider-family-azure - 180+ Azure services
  • provider-family-gcp - 150+ GCP services

Popular Community Providers:

  • Kubernetes (manage other clusters)
  • Helm (deploy Helm charts)
  • GitHub/GitLab (repos, teams, permissions)
  • Datadog/Dynatrace (observability)
  • Vault (secrets management)

Installation

bash
1# Install Crossplane
2helm repo add crossplane-stable https://charts.crossplane.io/stable
3helm install crossplane crossplane-stable/crossplane \
4 --namespace crossplane-system \
5 --create-namespace
6
7# Install AWS Provider
8cat <<EOF | kubectl apply -f -
9apiVersion: pkg.crossplane.io/v1
10kind: Provider
11metadata:
12 name: provider-aws-s3
13spec:
14 package: xpkg.upbound.io/upbound/provider-aws-s3:v1.0.0
15EOF

Getting Started: Your First Crossplane Resource

Step 1: Configure Provider Credentials

yaml
1# Use IRSA (IAM Roles for Service Accounts) - no long-lived creds
2apiVersion: aws.upbound.io/v1beta1
3kind: ProviderConfig
4metadata:
5 name: default
6spec:
7 credentials:
8 source: IRSA

Step 2: Create Infrastructure

yaml
1# Create an S3 bucket
2apiVersion: s3.aws.upbound.io/v1beta1
3kind: Bucket
4metadata:
5 name: my-crossplane-bucket
6spec:
7 forProvider:
8 region: ap-southeast-2
9 tags:
10 ManagedBy: Crossplane
11 Environment: development

Step 3: Verify

bash
1# Check resource status
2kubectl get bucket my-crossplane-bucket
3
4# NAME READY SYNCED AGE
5# my-crossplane-bucket True True 2m
6
7# Describe for details
8kubectl describe bucket my-crossplane-bucket

Migration Path from Terraform

Crossplane can import existing resources:

bash
1# Import existing AWS resources
2crossplane beta import \
3 --provider provider-aws-s3 \
4 --resource Bucket \
5 --name existing-bucket-name
6
7# Generates Crossplane manifests for existing infrastructure

For gradual migration:

  1. Start with new resources in Crossplane
  2. Import existing resources incrementally
  3. Maintain both temporarily
  4. Sunset Terraform after migration complete

Should You Switch?

flowchart

Yes

No

No

Yes

No

Yes

Want GitOps

Simple infra

Are you happy with Terraform?

Stay with Terraform

Running Kubernetes?

Consider Pulumi or adopt Kubernetes first

Building a platform?

Evaluate based on GitOps needs

Crossplane is ideal

Ctrl+scroll to zoom • Drag to pan42%

Migrate if:

  • Terraform state management is painful
  • You want true GitOps for infrastructure
  • Building an internal developer platform
  • Need continuous drift correction

Stay with Terraform if:

  • Current workflow works well
  • No Kubernetes in your stack
  • Team deeply invested in HCL

Brisbane Platform Engineering

At Buun Group, we help Queensland businesses build modern infrastructure platforms:

  • Platform Design — architect self-service developer platforms with Crossplane
  • Migration Support — transition from Terraform to Crossplane safely
  • Composition Development — build compliant, reusable infrastructure abstractions
  • GitOps Integration — implement Argo CD/Flux with infrastructure management
  • Training — upskill your team on Kubernetes-native infrastructure

We've deployed Crossplane in production for Australian enterprises. We know the patterns that work and the pitfalls to avoid.

Ready to modernize your infrastructure?

Topics

Crossplane 2026Crossplane vs TerraformCrossplane vs PulumiKubernetes infrastructure managementplatform engineering CrossplaneGitOps infrastructureCNCF CrossplaneCrossplane compositions

Share this post

Share

Comments

Sign in to join the conversation

Login

No comments yet. Be the first to share your thoughts!

Found an issue with this article?

/ Let's Talk

Want to work with us?

Whether you need help with architecture, development, or technical consulting, our team is here to help bring your vision to life.