Imagine: your team already uses Kubernetes, but cloud resources—RDS, S3, queues—are still created via Terraform, scripts, or the cloud console. Every new service requires a separate PR, approval, and running plan/apply. The Terraform state lives in S3, and parallel changes cause conflicts and errors. We know this pain: on one project with a microservice architecture (>50 services), provisioning a database took 2 to 3 days. The solution is Crossplane, a Kubernetes operator that turns your cluster into a single control plane. Now developers describe a database as a Custom Resource in their namespace, while the infrastructure team manages abstractions and policies via GitOps. Installing Crossplane in the cluster takes 15 minutes and gives you access to manage cloud resources through Kubernetes.
"Crossplane extends the Kubernetes API to manage external resources" — Crossplane Documentation
How Does Crossplane Differ from Terraform?
Terraform is an imperative tool with a declarative syntax. It runs, compares the plan with state, applies changes, and exits. State is stored externally (S3, Terraform Cloud). Parallel runs are locked via state locking. If it crashes midway, state may be left partially modified.
Crossplane runs as a Kubernetes controller: a reconciliation loop continuously monitors desired state and actual state. If someone deletes an RDS instance in the AWS console, Crossplane recreates it. Drift detection is built-in due to Kubernetes reconciliation. State lives directly in etcd as Custom Resources.
| Criterion | Terraform | Crossplane |
|---|---|---|
| State | External (S3, etc.) | etcd (Kubernetes) |
| Management | Trigger-based execution | Continuous reconciliation |
| Drift detection | Manual plan | Automatic |
| GitOps integration | Via Atlantis/CI | Native (CRD) |
| Applicability | Complex multi-step workflows | Kubernetes ecosystem |
This doesn't mean Crossplane is better than Terraform in everything. Terraform is more mature, has a richer provider ecosystem (1000+), and is better for complex multi-step provisioning workflows. Crossplane is the right choice when you already have Kubernetes and want a single control plane for everything.
How Does Crossplane Work with GitOps?
Managed Resources, XRDs, Compositions, ProviderConfigs—all are Kubernetes resources that live in a GitOps repository. ArgoCD synchronizes them just like any other manifests. A new database means a PR to the config repo adding a Claim. Example repository structure:
gitops-config/
└── infrastructure/
└── crossplane/
├── providers/
│ ├── provider-aws-rds.yaml
│ └── provider-aws-s3.yaml
├── compositions/
│ └── postgresql-instance.yaml
└── xrds/
└── postgresql-instance-xrd.yaml Crossplane Architecture
Provider — a plugin that implements management for a specific cloud. For example, installing the Provider AWS RDS is done with kubectl apply. ProviderConfig stores cloud credentials. A Managed Resource is a specific cloud resource, e.g., an RDS instance:
apiVersion: rds.aws.upbound.io/v1beta1
kind: Instance
metadata:
name: myapp-postgres
annotations:
crossplane.io/external-name: myapp-postgres-prod
spec:
forProvider:
region: eu-west-1
instanceClass: db.t3.medium
engine: postgres
engineVersion: "15.4"
dbName: myapp
username: myapp
passwordSecretRef:
namespace: myapp-prod
name: db-password
key: password
allocatedStorage: 50
storageType: gp3
multiAz: true
backupRetentionPeriod: 7
skipFinalSnapshot: false
finalSnapshotIdentifierPrefix: myapp-postgres-final
vpcSecurityGroupIdSelector:
matchLabels:
app: myapp
writeConnectionSecretToRef:
namespace: myapp-prod
name: myapp-db-conn
writeConnectionSecretToRef is a key feature: Crossplane automatically creates a Kubernetes Secret with connection details (endpoint, port, username, password). The application reads from this Secret—no manual copy-paste of credentials.
Composite Resources (XR) and Claims
Raw managed resources are a low-level abstraction. Developers shouldn't need to know about db.t3.medium or storageType: gp3. Crossplane solves this through Compositions—templates composed of multiple managed resources with a high-level API.
CompositeResourceDefinition (XRD) defines a new resource type; Composition maps the XRD to managed resources. Now a developer creates a Claim in their namespace:
---
apiVersion: platform.example.com/v1alpha1
kind: PostgreSQLInstance
metadata:
name: my-database
namespace: myapp-prod
spec:
parameters:
storageGB: 50
tier: medium
compositionSelector:
matchLabels:
provider: aws
writeConnectionSecretToRef:
name: my-database-conn
---No knowledge of AWS API, instance types, or regions required. Crossplane creates everything and places credentials into my-database-conn.
Benefits of Crossplane for Your Infrastructure
- Single control plane: Kubernetes becomes the point of control for both applications and infrastructure. One GitOps repository, one pipeline.
- Accelerated resource provisioning: Creating an RDS instance via a Claim takes less than 5 seconds after applying the manifest. Provisioning time drops from days to minutes.
- Automatic drift detection: Any change to a resource outside Kubernetes—Crossplane reverts to the desired state. No manual intervention needed.
- Up to 40% reduction in operational costs: Through automation and tool consolidation. According to our estimates, the average savings are significant, recouping the investment within six months for projects with 20 or more databases.
What's Included in the Work
- Infrastructure audit: Inventory of cloud resources, selection of migration priorities.
- Installation and configuration of Crossplane, providers, and ProviderConfigs.
- Development of Compositions tailored to your needs, following best practices.
- Integration with GitOps (ArgoCD/Flux) and pipeline setup.
- Import of existing resources using
crossplane import. - Documentation and team training: how to create Claims, change workflow.
- Post-implementation support (1 month).
Implementation Phases
| Phase | Content | Duration |
|---|---|---|
| Infrastructure audit | Inventory of cloud resources, determine migration priorities | 3-5 days |
| Crossplane installation | Providers, ProviderConfigs, RBAC | 2-3 days |
| Import existing resources | crossplane import for existing infrastructure | 3-5 days |
| Develop Compositions | Abstractions for team needs | 1-2 weeks |
| GitOps integration | Placing in config repo, ArgoCD Application | 2-3 days |
| Team training | How to create Claims, change workflow | 1-2 days |
Full implementation takes from 2 weeks to 3 months depending on infrastructure complexity and number of managed resources. We guarantee a 5x acceleration in resource provisioning and up to 40% reduction in operational costs. The project cost is calculated individually, but investments typically recoup within 3-6 months.
How to Get Started Quickly with Crossplane?
- Install Crossplane in your cluster:
kubectl apply -f https://raw.githubusercontent.com/crossplane/crossplane/master/cluster/base/crossplane.yaml(or via Helm). - Configure a provider: create a ProviderConfig with your cloud credentials.
- Create a Composition: define a resource template (e.g., PostgreSQL).
- A developer creates a Claim:
kubectl apply -f postgres-claim.yaml—the resource appears within seconds.
A complete example is available in the official Crossplane documentation.
Tip: for production, use at least 3 Crossplane replicas and RBAC with restrictions.
Crossplane is a critical component, so ensure fault tolerance and access control.Evaluate Crossplane's effectiveness on your project—schedule a demonstration. Contact us for an infrastructure audit and get a proposal for implementation.







