Loading...
Loading...
Debug Crossplane compositions, functions (KCL, Go templates, patch-and-transform, auto-ready), and managed resources. Use when troubleshooting composition rendering issues, function errors, resource creation failures, dependency problems, or claim status issues. Supports remote cluster debugging when composition files are not available locally. Triggers on keywords like "crossplane", "composition", "XR", "claim", "function-kcl", "managed resource", or when debugging Kubernetes resources created by Crossplane.
npx skill4agent add kanzifucius/crossplane-debug crossplane-debugIssue reported
|
v
Do you have composition files locally?
|
+--NO--> Extract from cluster first
| Run: scripts/extract-composition.sh
| See: "Remote Cluster Debugging"
|
+--YES--> Is the composition rendering correctly?
|
+--NO--> Run `crossplane beta render` locally
| See: "Local Render Debugging"
|
+--YES--> Are resources being created in the cluster?
|
+--NO--> Check XR/Claim status and events
| Run `crossplane beta trace`
| See: "Cluster Debugging"
|
+--YES--> Are resources in Ready state?
|
+--NO--> Check managed resource conditions
| See: "Resource Status Debugging"
|
+--YES--> Issue is external to Crossplane# Extract composition, functions, and sample XR for debugging
./scripts/extract-composition.sh <composition-name> [xr-kind] [xr-name]
# Examples:
./scripts/extract-composition.sh my-database-composition
./scripts/extract-composition.sh my-app-composition XMyApp my-app-instancedebug-<composition-name>/crossplane beta render# List available compositions
kubectl get compositions
# Extract specific composition
kubectl get composition <name> -o yaml > composition.yaml# List installed functions
kubectl get functions
# Extract all functions to single file
kubectl get functions -o yaml > functions.yaml
# Or extract specific function
kubectl get function <name> -o yaml >> functions.yaml# Find XRs using this composition
kubectl get <xr-kind> -A
# Extract an XR as sample input (clean up status for render)
kubectl get <xr-kind> <name> -o yaml | \
yq 'del(.status) | del(.metadata.resourceVersion) | del(.metadata.uid) | del(.metadata.generation) | del(.metadata.creationTimestamp) | del(.metadata.managedFields)' \
> xr.yaml# View all pipeline steps and their inputs
kubectl get composition <name> -o jsonpath='{.spec.pipeline}' | jq
# Extract KCL source from specific step (adjust index [0] as needed)
kubectl get composition <name> -o jsonpath='{.spec.pipeline[0].input.source}'
# Pretty print KCL from inline composition
kubectl get composition <name> -o json | \
jq -r '.spec.pipeline[] | select(.functionRef.name == "function-kcl") | .input.source'# Find function pods
kubectl get pods -n crossplane-system -l pkg.crossplane.io/function
# Logs for specific function
kubectl logs -n crossplane-system -l pkg.crossplane.io/function=function-kcl -f --tail=100
# All function logs
kubectl logs -n crossplane-system -l pkg.crossplane.io/revision --tail=50# 1. Check function health
kubectl get functions
kubectl describe function <name>
# 2. Check function pod status
kubectl get pods -n crossplane-system -l pkg.crossplane.io/function=<name>
# 3. View function errors in XR events
kubectl describe <xr-kind> <xr-name> | grep -A5 "Events:"
# 4. Check crossplane core logs for function errors
kubectl logs -n crossplane-system deploy/crossplane --tail=100 | grep -i functioncrossplane beta rendercrossplane beta render <xr-file.yaml> <composition.yaml> <functions.yaml>xr-file.yamlcomposition.yamlfunctions.yamlDefault---
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-kcl
annotations:
render.crossplane.io/runtime: Default
---
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-auto-ready
annotations:
render.crossplane.io/runtime: Default---
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-kcl
annotations:
render.crossplane.io/runtime: Development
render.crossplane.io/runtime-development-target: localhost:9443
---
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-auto-ready# Terminal 1: Run KCL function server
docker run --rm -p 9443:9443 xpkg.upbound.io/crossplane-contrib/function-kcl:latest --insecure --debug# Terminal 2: Render with local function
crossplane beta render xr.yaml composition.yaml functions.yaml| Symptom | Likely Cause | Action |
|---|---|---|
| Empty output | Function not matched or no resources generated | Check function name matches pipeline step |
| KCL syntax error | Invalid KCL in composition | See references/kcl-patterns.md |
| "function not found" | Function not in functions.yaml | Add function definition |
| Wrong resource apiVersion | KCL schema mismatch | Update KCL imports |
# Trace from claim to all managed resources
crossplane beta trace <claim-kind>/<claim-name> -n <namespace>
# Trace from XR
crossplane beta trace <xr-kind>/<xr-name>kubectl get <xr-kind> <xr-name> -o yamlstatus.conditionsstatus.connectionDetailsspec.compositionRefspec.resourceRefskubectl describe <claim-kind> <claim-name> -n <namespace>status.conditionsstatus.connectionDetailskubectl get compositionrevision -l crossplane.io/composition-name=<composition-name>kubectl describe <managed-resource-kind> <name>Synced=FalseReady=False| Condition | Message Pattern | Cause |
|---|---|---|
| Synced=False | "cannot create" | Missing permissions or invalid spec |
| Synced=False | "rate limit" | API throttling, retry later |
| Ready=False | "pending" | Resource still provisioning |
| Ready=False | "failed" | External creation error |
# Find provider pod
kubectl get pods -n crossplane-system | grep provider
# View logs
kubectl logs -n crossplane-system <provider-pod> -f# Extract and validate inline KCL
kubectl get composition <name> -o json | \
jq -r '.spec.pipeline[] | select(.functionRef.name == "function-kcl") | .input.source' \
> extracted.k
kcl extracted.k
# Run with debug output
crossplane beta render xr.yaml composition.yaml functions.yaml 2>&1 | head -100{{ }}.observed.composite.resource.specfromFieldPathtoFieldPath# Validate composition against schema
crossplane beta validate <composition.yaml>
# Validate with extensions
crossplane beta validate <composition.yaml> --extensions=<extensions-dir># Remote cluster: Extract for local debugging
kubectl get composition <name> -o yaml > composition.yaml
kubectl get functions -o yaml > functions.yaml
kubectl get <xr> <name> -o yaml > xr.yaml
# Full debugging session
crossplane beta trace <kind>/<name> # See resource tree
kubectl get events --field-selector involvedObject.name=<name> # Recent events
kubectl get <xr> -o jsonpath='{.status.conditions}' # XR conditions
# Function debugging
crossplane beta render xr.yaml comp.yaml funcs.yaml # Local render
crossplane beta render xr.yaml comp.yaml funcs.yaml -o json | jq # Parse output
# View inline KCL
kubectl get composition <name> -o json | jq -r '.spec.pipeline[].input.source'
# Provider debugging
kubectl logs -n crossplane-system deploy/<provider> --tail=100