Crossplane
Kubernetes-native infrastructure as code control plane for composing cloud resources.
Installation
Section titled “Installation”Crossplane Core
Section titled “Crossplane Core”| Command | Description |
|---|---|
helm repo add crossplane-stable https://charts.crossplane.io/stable | Add Crossplane Helm repo |
helm repo update | Update Helm repositories |
helm install crossplane crossplane-stable/crossplane -n crossplane-system --create-namespace | Install Crossplane on Kubernetes |
helm install crossplane crossplane-stable/crossplane -n crossplane-system --set args='{"--debug"}' | Install with debug logging |
helm upgrade crossplane crossplane-stable/crossplane -n crossplane-system | Upgrade Crossplane |
helm uninstall crossplane -n crossplane-system | Uninstall Crossplane |
kubectl get pods -n crossplane-system | Verify Crossplane is running |
kubectl get deployments -n crossplane-system | Check deployment status |
CLI Installation
Section titled “CLI Installation”| Command | Description |
|---|---|
curl -sL https://raw.githubusercontent.com/crossplane/crossplane/master/install.sh | sh | Install Crossplane CLI |
brew install crossplane/tap/crossplane | Install CLI via Homebrew |
crossplane --version | Show CLI version |
CLI Commands
Section titled “CLI Commands”Package Management
Section titled “Package Management”| Command | Description |
|---|---|
crossplane xpkg init my-config configuration | Initialize new configuration package |
crossplane xpkg init my-provider provider | Initialize new provider package |
crossplane xpkg build | Build a Crossplane package |
crossplane xpkg build --package-root=./package --examples-root=./examples | Build with specific directories |
crossplane xpkg push index.docker.io/org/config:v1 | Push package to registry |
crossplane xpkg install provider index.docker.io/org/provider:v1 | Install a provider package |
crossplane xpkg install configuration index.docker.io/org/config:v1 | Install a configuration package |
Debugging and Validation
Section titled “Debugging and Validation”| Command | Description |
|---|---|
crossplane beta validate schema.yaml resources/ | Validate resources against schema |
crossplane beta trace kind/name | Trace resource dependencies |
crossplane beta trace kind/name -o wide | Trace with extended output |
crossplane beta convert composition comp.yaml | Convert Composition to pipeline mode |
crossplane beta render xr.yaml composition.yaml functions.yaml | Locally render composed resources |
Providers
Section titled “Providers”Provider Setup
Section titled “Provider Setup”| Command | Description |
|---|---|
kubectl apply -f provider-aws.yaml | Install AWS provider |
kubectl apply -f provider-gcp.yaml | Install GCP provider |
kubectl apply -f provider-azure.yaml | Install Azure provider |
kubectl apply -f provider-kubernetes.yaml | Install Kubernetes provider |
kubectl apply -f provider-helm.yaml | Install Helm provider |
kubectl get providers | List installed providers |
kubectl get provider.pkg provider-aws -o yaml | Show provider details |
kubectl describe providerrevision | Show provider revision status |
kubectl get managed | List all managed cloud resources |
kubectl get managed -o wide | List managed resources with status |
AWS ProviderConfig
Section titled “AWS ProviderConfig”apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
metadata:
name: default
spec:
credentials:
source: Secret
secretRef:
namespace: crossplane-system
name: aws-creds
key: credentials
Create the credentials secret:
kubectl create secret generic aws-creds \
-n crossplane-system \
--from-file=credentials=./aws-credentials.txt
GCP ProviderConfig
Section titled “GCP ProviderConfig”apiVersion: gcp.upbound.io/v1beta1
kind: ProviderConfig
metadata:
name: default
spec:
projectID: my-gcp-project
credentials:
source: Secret
secretRef:
namespace: crossplane-system
name: gcp-creds
key: credentials
Azure ProviderConfig
Section titled “Azure ProviderConfig”apiVersion: azure.upbound.io/v1beta1
kind: ProviderConfig
metadata:
name: default
spec:
credentials:
source: Secret
secretRef:
namespace: crossplane-system
name: azure-creds
key: credentials
Composite Resources (XRDs)
Section titled “Composite Resources (XRDs)”XRD Operations
Section titled “XRD Operations”| Command | Description |
|---|---|
kubectl apply -f xrd.yaml | Create CompositeResourceDefinition |
kubectl get xrd | List all XRDs |
kubectl describe xrd xdatabases.custom.example.com | Show XRD details |
kubectl get composite | List all composite resources |
kubectl describe composite | Show composite resource status |
kubectl delete xrd xdatabases.custom.example.com | Delete XRD |
Set spec.claimNames in XRD | Enable namespace-scoped claims |
Set spec.versions[].schema | Define OpenAPI schema for XRD |
Set spec.connectionSecretKeys | Define which connection keys to expose |
XRD Definition Example
Section titled “XRD Definition Example”apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
name: xdatabases.platform.example.com
spec:
group: platform.example.com
names:
kind: XDatabase
plural: xdatabases
claimNames:
kind: Database
plural: databases
connectionSecretKeys:
- endpoint
- port
- username
- password
versions:
- name: v1alpha1
served: true
referenceable: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
parameters:
type: object
properties:
engine:
type: string
enum: ["postgres", "mysql", "mariadb"]
description: "Database engine type"
engineVersion:
type: string
description: "Engine version"
storageGB:
type: integer
default: 20
description: "Storage size in GB"
instanceSize:
type: string
enum: ["small", "medium", "large"]
default: "small"
required:
- engine
required:
- parameters
Compositions
Section titled “Compositions”Composition Operations
Section titled “Composition Operations”| Command | Description |
|---|---|
kubectl apply -f composition.yaml | Create a Composition |
kubectl get compositions | List all Compositions |
kubectl describe composition | Show Composition details |
Set spec.compositeTypeRef in Composition | Link to XRD |
Set spec.resources[] in Composition | Define composed resources |
Use patches in Composition | Map fields between composite and resources |
patch: { type: FromCompositeFieldPath } | Patch from composite to resource |
patch: { type: ToCompositeFieldPath } | Patch from resource to composite |
patch: { type: CombineFromComposite } | Combine multiple fields into one |
Set spec.mode: Pipeline in Composition | Use function pipeline mode |
Composition Example (Resources Mode)
Section titled “Composition Example (Resources Mode)”apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: xdatabase-aws
labels:
provider: aws
engine: postgres
spec:
compositeTypeRef:
apiVersion: platform.example.com/v1alpha1
kind: XDatabase
resources:
- name: rds-instance
base:
apiVersion: rds.aws.upbound.io/v1beta1
kind: Instance
spec:
forProvider:
engine: postgres
instanceClass: db.t3.micro
allocatedStorage: 20
publiclyAccessible: false
skipFinalSnapshot: true
region: us-east-1
patches:
- type: FromCompositeFieldPath
fromFieldPath: spec.parameters.engineVersion
toFieldPath: spec.forProvider.engineVersion
- type: FromCompositeFieldPath
fromFieldPath: spec.parameters.storageGB
toFieldPath: spec.forProvider.allocatedStorage
- type: FromCompositeFieldPath
fromFieldPath: spec.parameters.instanceSize
toFieldPath: spec.forProvider.instanceClass
transforms:
- type: map
map:
small: db.t3.micro
medium: db.t3.medium
large: db.t3.large
connectionDetails:
- type: FromFieldPath
name: endpoint
fromFieldPath: status.atProvider.endpoint
- type: FromFieldPath
name: port
fromFieldPath: status.atProvider.port
- name: subnet-group
base:
apiVersion: rds.aws.upbound.io/v1beta1
kind: SubnetGroup
spec:
forProvider:
region: us-east-1
description: "Managed by Crossplane"
writeConnectionSecretsToNamespace: crossplane-system
Composition Example (Pipeline Mode)
Section titled “Composition Example (Pipeline Mode)”apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: xdatabase-pipeline
spec:
compositeTypeRef:
apiVersion: platform.example.com/v1alpha1
kind: XDatabase
mode: Pipeline
pipeline:
- step: patch-and-transform
functionRef:
name: function-patch-and-transform
input:
apiVersion: pt.fn.crossplane.io/v1beta1
kind: Resources
resources:
- name: rds-instance
base:
apiVersion: rds.aws.upbound.io/v1beta1
kind: Instance
spec:
forProvider:
engine: postgres
instanceClass: db.t3.micro
region: us-east-1
patches:
- type: FromCompositeFieldPath
fromFieldPath: spec.parameters.storageGB
toFieldPath: spec.forProvider.allocatedStorage
- step: auto-ready
functionRef:
name: function-auto-detect-ready
Claims
Section titled “Claims”Claim Operations
Section titled “Claim Operations”| Command | Description |
|---|---|
kubectl apply -f claim.yaml | Create a resource claim |
kubectl get claim | List all claims in namespace |
kubectl get database | List claims of type Database |
kubectl describe claim my-database | Show claim status and events |
kubectl delete claim my-database | Delete claim and managed resources |
Set spec.compositionRef.name in claim | Select specific Composition |
Set spec.compositionSelector.matchLabels in claim | Select Composition by labels |
kubectl get events --field-selector involvedObject.name=my-db | View claim events |
kubectl get secret my-db-conn -o jsonpath='{.data.endpoint}' | Read connection details |
Claim Example
Section titled “Claim Example”apiVersion: platform.example.com/v1alpha1
kind: Database
metadata:
name: my-app-db
namespace: default
spec:
parameters:
engine: postgres
engineVersion: "15"
storageGB: 50
instanceSize: medium
compositionSelector:
matchLabels:
provider: aws
engine: postgres
writeConnectionSecretToRef:
name: my-app-db-conn
Functions
Section titled “Functions”Function Pipeline
Section titled “Function Pipeline”| Command | Description |
|---|---|
kubectl apply -f function.yaml | Install a Composition function |
kubectl get functions | List installed functions |
kubectl describe function function-patch-and-transform | Show function details |
crossplane beta render xr.yaml composition.yaml functions.yaml | Test pipeline locally |
Common Functions
Section titled “Common Functions”# Install function-patch-and-transform
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-patch-and-transform
spec:
package: xpkg.upbound.io/crossplane-contrib/function-patch-and-transform:v0.7.0
---
# Install function-auto-detect-ready
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-auto-detect-ready
spec:
package: xpkg.upbound.io/crossplane-contrib/function-auto-detect-ready:v0.2.1
---
# Install function-go-templating
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-go-templating
spec:
package: xpkg.upbound.io/crossplane-contrib/function-go-templating:v0.6.0
Configuration
Section titled “Configuration”EnvironmentConfig
Section titled “EnvironmentConfig”apiVersion: apiextensions.crossplane.io/v1alpha1
kind: EnvironmentConfig
metadata:
name: production
data:
region: us-east-1
environment: production
vpcId: vpc-0abc123def456
subnetIds:
- subnet-0abc123
- subnet-0def456
- subnet-0ghi789
tags:
team: platform
costCenter: engineering
Connection Secret Publishing
Section titled “Connection Secret Publishing”| Command | Description |
|---|---|
kubectl create secret generic aws-creds -n crossplane-system --from-file=creds=./aws-creds.txt | Create provider credentials secret |
Set spec.credentials.source: Secret in ProviderConfig | Reference credentials secret |
kubectl apply -f environmentconfig.yaml | Create EnvironmentConfig |
kubectl get storeconfig | List store configurations |
Set spec.publishConnectionDetailsTo in Composition | Configure connection secret publishing |
Set spec.writeConnectionSecretToRef in claim | Write connection details to secret |
kubectl get secrets -l crossplane.io/claim-name=my-db | List secrets for a claim |
StoreConfig for External Secret Store
Section titled “StoreConfig for External Secret Store”apiVersion: secrets.crossplane.io/v1alpha1
kind: StoreConfig
metadata:
name: vault
spec:
type: Vault
defaultScope: crossplane-system
vault:
mountPath: secret
version: v2
auth:
method: Token
token:
source: Secret
secretRef:
namespace: crossplane-system
name: vault-token
key: token
Troubleshooting
Section titled “Troubleshooting”Diagnostics
Section titled “Diagnostics”| Command | Description |
|---|---|
kubectl get managed -o wide | Show managed resources with status |
kubectl describe managed | Show detailed managed resource info |
kubectl logs -n crossplane-system deploy/crossplane | View Crossplane controller logs |
kubectl logs -n crossplane-system deploy/crossplane -f | Follow controller logs |
kubectl get events --sort-by='.lastTimestamp' | View recent cluster events |
crossplane beta trace xdatabase my-db | Trace full resource tree |
crossplane beta trace xdatabase my-db -o wide | Trace with detailed status |
kubectl get managed -l crossplane.io/composite=my-db | Find resources for a composite |
kubectl annotate managed resource.api.example.com/name crossplane.io/paused=true | Pause resource reconciliation |
kubectl annotate managed resource.api.example.com/name crossplane.io/paused- | Resume resource reconciliation |
Common Issues
Section titled “Common Issues”| Command | Description |
|---|---|
kubectl get providerrevision | Check if provider is healthy |
kubectl describe providerrevision | View provider install errors |
kubectl get managed -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.conditions[*].reason}{"\n"}{end}' | Quick status of all managed resources |
kubectl patch managed resource.api.example.com/name --type merge -p '{"metadata":{"annotations":{"crossplane.io/paused":"true"}}}' | Pause via patch |
kubectl delete managed --all | Delete all managed resources (use caution) |
Best Practices
Section titled “Best Practices”-
Use Claims instead of direct Composites — claims are namespace-scoped and provide proper RBAC boundaries between teams.
-
Pin provider versions — always specify exact provider versions to prevent unexpected changes during upgrades.
-
Use Pipeline mode for new Compositions — Pipeline mode with functions is more flexible and testable than Resources mode.
-
Implement EnvironmentConfigs — store shared environment data like VPC IDs and subnet lists to avoid duplication across Compositions.
-
Set up connection secret publishing — always define
writeConnectionSecretToRefin claims so applications can consume connection details. -
Use
crossplane beta trace— this is the fastest way to debug issues by visualizing the entire resource tree from claim to managed resource. -
Label Compositions for selection — use labels like
provider: awsandengine: postgresso claims can select Compositions by label rather than by name. -
Test locally with
crossplane beta render— render your Compositions locally before applying them to a cluster. -
Implement readiness checks — use
function-auto-detect-readyor custom readiness checks to ensure composite resources report accurate status. -
Version your XRDs — start with
v1alpha1and promote throughv1beta1tov1as your API stabilizes.