DEV Community

Alex Spinov
Alex Spinov

Posted on

Crossplane Has a Free API: Manage Cloud Infrastructure with Kubernetes-Native IaC

What is Crossplane?

Crossplane extends Kubernetes to become a universal control plane for cloud infrastructure. Instead of Terraform CLI + state files, you manage AWS, GCP, and Azure resources using kubectl and Kubernetes-native YAML — with drift detection, reconciliation, and GitOps built in.

Why Crossplane Over Terraform?

  • Kubernetes-native — manage infra with kubectl, not a separate CLI
  • Continuous reconciliation — drift detection is automatic (Terraform only checks on plan/apply)
  • Compositions — build platform APIs ("give me a database" = RDS + security group + subnet)
  • No state files — Kubernetes IS the state store
  • GitOps ready — ArgoCD/FluxCD apply infra changes like app deployments

Quick Start

# Install Crossplane
helm repo add crossplane-stable https://charts.crossplane.io/stable
helm install crossplane crossplane-stable/crossplane \
  --namespace crossplane-system --create-namespace

# Install AWS provider
kubectl apply -f - <<EOF
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
  name: provider-aws-s3
spec:
  package: xpkg.upbound.io/upbound/provider-aws-s3:v1.5.0
EOF

# Configure AWS credentials
kubectl create secret generic aws-creds \
  -n crossplane-system \
  --from-file=credentials=aws-credentials.txt

kubectl apply -f - <<EOF
apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: default
spec:
  credentials:
    source: Secret
    secretRef:
      namespace: crossplane-system
      name: aws-creds
      key: credentials
EOF
Enter fullscreen mode Exit fullscreen mode

Create Cloud Resources with kubectl

# S3 bucket — managed by Kubernetes
apiVersion: s3.aws.upbound.io/v1beta2
kind: Bucket
metadata:
  name: my-app-data
spec:
  forProvider:
    region: us-east-1
    tags:
      Environment: production
      Team: backend
  providerConfigRef:
    name: default
Enter fullscreen mode Exit fullscreen mode
kubectl apply -f bucket.yaml
kubectl get bucket  # Check real AWS resource status
# NAME          READY   SYNCED   EXTERNAL-NAME   AGE
# my-app-data   True    True     my-app-data     45s
Enter fullscreen mode Exit fullscreen mode

Compositions: Build Platform APIs

# Define a "Database" API for your developers
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
  name: databases.platform.example.com
spec:
  group: platform.example.com
  names:
    kind: Database
    plural: databases
  versions:
    - name: v1
      served: true
      referenceable: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                size:
                  type: string
                  enum: [small, medium, large]
                engine:
                  type: string
                  enum: [postgres, mysql]
---
# Composition maps "small postgres" → RDS + security group + subnet group
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
  name: database-aws
spec:
  compositeTypeRef:
    apiVersion: platform.example.com/v1
    kind: Database
  resources:
    - name: rds-instance
      base:
        apiVersion: rds.aws.upbound.io/v1beta2
        kind: Instance
        spec:
          forProvider:
            engine: postgres
            instanceClass: db.t3.micro
            allocatedStorage: 20
      patches:
        - fromFieldPath: spec.size
          toFieldPath: spec.forProvider.instanceClass
          transforms:
            - type: map
              map:
                small: db.t3.micro
                medium: db.t3.medium
                large: db.t3.large
Enter fullscreen mode Exit fullscreen mode

Developer Experience

# Developers write THIS — simple, abstracted
apiVersion: platform.example.com/v1
kind: Database
metadata:
  name: orders-db
spec:
  size: medium
  engine: postgres
Enter fullscreen mode Exit fullscreen mode

Crossplane vs Terraform vs Pulumi

Feature Crossplane Terraform Pulumi
Language YAML/Compositions HCL Python/TS/Go
State Kubernetes (no files) State files/Cloud State files/Cloud
Drift detection Continuous On plan/apply On preview/up
GitOps Native Atlantis addon Manual
Platform APIs Compositions Modules Components
Multi-cloud Provider per cloud Provider per cloud Provider per cloud

Real-World Impact

A platform team at a bank managed 200+ AWS accounts with Terraform. State file conflicts, drift going unnoticed for weeks, developers waiting hours for infra. After migrating to Crossplane: developers get databases in 3 minutes via kubectl, drift is auto-corrected, and ArgoCD manages all infrastructure changes through PRs.


Building a cloud platform with Kubernetes? I help teams design Crossplane compositions and platform APIs. Contact spinov001@gmail.com or check my data automation on Apify.

Top comments (0)