Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for Infrastructure as Code By James Joyner IV · · 8 min read

Crossplane Providers: Managing Multi-Cloud Resources From Kubernetes

Compositions get the spotlight, but providers are the engine. Here's how Crossplane providers reconcile real cloud resources and how to run them in production.

  • #iac
  • #crossplane
  • #kubernetes
  • #multi-cloud
  • #providers
  • #control-plane

Crossplane compositions get most of the attention — building internal cloud APIs, abstracting infrastructure into self-service claims. But compositions are useless without the layer underneath them: providers. A provider is what actually talks to AWS, Azure, or GCP and reconciles a Kubernetes resource into a real cloud resource. Get providers wrong and nothing above them works.

This is the under-documented layer, so let’s go deep on it: what providers are, how reconciliation works, and the operational details that separate a Crossplane install that survives contact with production from one that pages you every week.

A provider is a controller with a CRD bundle

When you install a Crossplane provider, you get two things: a set of Custom Resource Definitions (CRDs) that map cloud resources to Kubernetes objects, and a controller that reconciles them. Install the AWS S3 provider and you get a Bucket CRD plus a controller that watches Bucket objects and makes the real S3 bucket match.

apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
  name: provider-aws-s3
spec:
  package: xpkg.upbound.io/upbound/provider-aws-s3:v1.5.0

The modern Upbound providers are family providers — split by service (provider-aws-s3, provider-aws-ec2, provider-aws-rds) instead of one giant binary. Install only the services you use. This matters: the monolithic AWS provider registered thousands of CRDs and ate enormous memory. Family providers keep the footprint sane.

ProviderConfig: how it authenticates

A provider needs credentials, supplied by a ProviderConfig. Never use static keys in production — wire it to IRSA (EKS), Workload Identity (GKE), or a Pod Identity so credentials rotate automatically.

apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: default
spec:
  credentials:
    source: IRSA   # provider pod assumes an IAM role, no stored keys

Now any managed resource referencing this config provisions under that role’s permissions. Scope the role tightly — a provider with AdministratorAccess is a blast radius waiting to happen.

Managed resources and reconciliation

A managed resource (MR) is a Kubernetes object representing one cloud resource. You can apply one directly, without any composition:

apiVersion: s3.aws.upbound.io/v1beta1
kind: Bucket
metadata:
  name: app-data-prod
spec:
  forProvider:
    region: us-east-1
  providerConfigRef:
    name: default

The controller reconciles continuously: it observes the real bucket, diffs it against spec.forProvider, and corrects drift. This is the core value proposition — it’s not a one-shot apply, it’s a continuous control loop. Someone changes the bucket in the console? Crossplane reverts it on the next reconcile. That’s both a feature and a footgun, so understand it before you ship.

Deletion policy: the setting that prevents disasters

By default, deleting the MR deletes the cloud resource. For stateful resources that is terrifying. Set the policy explicitly:

spec:
  deletionPolicy: Orphan   # delete the K8s object, KEEP the cloud resource
  managementPolicies:
    - Observe
    - Create
    - Update
    # No "Delete" — Crossplane will never destroy this RDS instance

managementPolicies is the fine-grained control: you can have Crossplane observe and update a database but never create or delete it. For anything holding data, lock this down. I’ve seen a kubectl delete on the wrong namespace nearly take out a production database because nobody set deletionPolicy: Orphan.

Running providers in production

The operational details that actually matter:

  • Tune --max-reconcile-rate and --poll-interval via a DeploymentRuntimeConfig. The default poll (every 10 min) plus high reconcile rates against thousands of MRs can hammer cloud APIs into rate limits.
  • Watch provider memory. Each provider holds informer caches for its CRDs. Set resource limits and monitor — OOM-killed providers stop reconciling silently.
  • Pin provider versions. A provider upgrade can change CRD schemas. Test upgrades in a non-prod control plane first; pin the package digest in prod.
  • Use one control plane, many provider configs for multi-cloud. A single Crossplane install with AWS, Azure, and GCP providers gives you one place to manage resources across all three — that’s the multi-cloud payoff.

Where AI fits

Provider MR schemas are vast — the S3 Bucket alone has dozens of nested fields, and they don’t match the AWS console names. I use an assistant to translate “I want a versioned, encrypted bucket with a lifecycle rule” into the correct forProvider YAML, and to debug why a resource is stuck Unready by interpreting the controller’s condition messages. Keep a few Crossplane prompts for generating managed-resource manifests, then verify against the provider’s CRD reference.

The mental model

Compositions are the abstraction; providers are the engine. Before you build a single composition, get the provider layer solid: family providers for the services you use, IRSA/Workload Identity for auth, tightly-scoped IAM, deletionPolicy: Orphan on anything stateful, and tuned reconcile rates. Do that and Crossplane becomes a genuine multi-cloud control plane — a single Kubernetes API reconciling resources across every provider you run. Skip it and you’ve built a very elaborate way to delete your production database. For more, see our Infrastructure as Code category.

Provider manifests and generated managed-resource YAML are assistive. Always set deletion and management policies deliberately and test against a sandbox account first.

Free download · 368-page PDF

Download the Free 500-Prompt DevOps AI Toolkit

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.