DevOps · Crossplane

Crossplane for Kubernetes — A Field Guide

Crossplane for Kubernetes — A Field Guide is the work that turns a deploy into a system. The deployment is one moment; the system is the next 18 months of uptime, incidents, and.

John Kihiu12 min read

Crossplane extends the Kubernetes API to manage infrastructure outside the cluster — an RDS instance, an S3 bucket, a VPC — using the same declarative, reconciliation-loop model Kubernetes already uses for pods and deployments. Instead of a separate Terraform pipeline that runs on a schedule or on merge, infrastructure becomes a Kubernetes resource that a controller continuously reconciles toward the desired state, the same way a Deployment controller keeps pod replicas at the requested count.

Providers and managed resources

A Crossplane provider (provider-aws, provider-gcp, provider-azure, and many community providers for other services) installs CRDs and controllers for that cloud's resources. Once installed, you can create a Bucket or a RDSInstance as a Kubernetes object, and the provider's controller talks to the cloud API to make reality match the spec — including reconciling drift if someone changes the resource outside Crossplane, which is a meaningful difference from Terraform's plan-and-apply model that only checks drift when you explicitly run it.

YAML · MANAGED RESOURCE
apiVersion: s3.aws.upbound.io/v1beta1
kind: Bucket
metadata:
  name: app-uploads
spec:
  forProvider:
    region: eu-west-1
    tags:
      environment: production
  providerConfigRef:
    name: aws-provider-config

Compositions: the platform-team abstraction layer

Raw managed resources are still cloud-specific and detailed — not something you want application teams writing directly. A Composition lets a platform team define a higher-level abstraction (a PostgresDatabase claim, say) that expands into the actual set of managed resources — an RDS instance, a security group, a subnet group, a secret — behind a much simpler interface. Application teams request the abstraction; the platform team owns and evolves what it expands into, which is the core value proposition: self-service infrastructure requests that stay within guardrails the platform team controls.

Compositions are a real API contract, not just templating

Once application teams are creating claims against a Composition, changing the Composition's shape is a breaking-change decision, same as changing any API. Version Compositions deliberately and think about migration for existing claims before changing the fields a claim can set — this is easy to treat casually early on and expensive to fix once dozens of claims depend on the old shape.

Crossplane vs Terraform: not a strict replacement

Terraform's model is plan-review-apply, usually gated through CI/CD with a human approval step — good for changes where you want an explicit diff reviewed before anything happens. Crossplane's model is continuous reconciliation — good for infrastructure that should self-heal and for exposing infrastructure provisioning as a Kubernetes-native, GitOps-friendly API to teams already living in kubectl and Git. They're not mutually exclusive in a given organization; many teams use Terraform for foundational, rarely-changed infrastructure (the VPC, the cluster itself) and Crossplane for the higher-churn, per-application resources that benefit from self-service and continuous drift correction.

GitOps fits naturally

Because Crossplane resources are ordinary Kubernetes objects, they work with Argo CD or Flux the same way any other manifest does — commit a claim to Git, the GitOps controller applies it, Crossplane reconciles the underlying cloud resources. This is a genuine operational win over a separate Terraform pipeline: one review-and-audit trail (Git history) for both application deployments and the infrastructure they depend on, rather than two disconnected systems with their own approval flows.

Start with Compositions for your most-requested resource type

Don't try to model your entire cloud footprint in Crossplane on day one. Pick the resource type application teams request most often — a database, a queue, an object storage bucket — build one solid Composition for it, and prove the self-service workflow before expanding. A half-finished Crossplane rollout covering three resource types badly is worse than one resource type covered well.

ConcernTerraformCrossplane
Change reviewExplicit plan/apply, easy to gateContinuous reconciliation, gated via Git review of the claim
Drift handlingDetected on next plan runContinuously reconciled by the controller
Self-service for app teamsNeeds a separate wrapper/portalNative via Compositions and claims
Ecosystem maturityVery mature, broad provider coverageGrowing, strong on major clouds, thinner elsewhere

Wrapping up

Crossplane is worth adopting when the goal is genuine self-service infrastructure inside a Kubernetes-native, GitOps workflow — not as a wholesale Terraform replacement. Start narrow with one Composition for your highest-demand resource type, treat that Composition's shape as a versioned API, and expand once the workflow has proven itself with real application teams using it.

John Kihiu
Acumatica ERP Developer · Laravel Engineer

Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.