Crossplane Composition
Crossplane Composition Low Code No Code Cloud Infrastructure Self-service XRD Composition Functions Platform API Kubernetes GitOps Enterprise
| Feature | Crossplane | Terraform | Pulumi |
|---|---|---|---|
| Paradigm | Declarative (K8s API) | Declarative (HCL) | Imperative (Code) |
| Reconciliation | Continuous (Controller) | On-demand (apply) | On-demand (up) |
| Self-service | XRD + Claim (built-in) | Module + Wrapper | Component + Automation |
| GitOps | Native (ArgoCD/Flux) | Atlantis/TF Cloud | Pulumi Operator |
| State | Kubernetes etcd | State file (S3/Cloud) | Pulumi Cloud/S3 |
| Learning Curve | สูง (K8s + Cloud) | กลาง (HCL) | กลาง (Programming) |
XRD and Composition
# === Crossplane XRD and Composition ===
# CompositeResourceDefinition (XRD)
# apiVersion: apiextensions.crossplane.io/v1
# kind: CompositeResourceDefinition
# metadata:
# name: databases.platform.example.com
# spec:
# group: platform.example.com
# names:
# kind: Database
# plural: databases
# claimNames:
# kind: DatabaseClaim
# plural: databaseclaims
# versions:
# - name: v1alpha1
# served: true
# referenceable: true
# schema:
# openAPIV3Schema:
# type: object
# properties:
# spec:
# type: object
# properties:
# engine:
# type: string
# enum: [postgres, mysql]
# size:
# type: string
# enum: [small, medium, large]
# region:
# type: string
# default: ap-southeast-1
# required: [engine, size]
# Composition
# apiVersion: apiextensions.crossplane.io/v1
# kind: Composition
# metadata:
# name: database-aws
# spec:
# compositeTypeRef:
# apiVersion: platform.example.com/v1alpha1
# kind: Database
# resources:
# - name: rds-instance
# base:
# apiVersion: rds.aws.upbound.io/v1beta1
# kind: Instance
# spec:
# forProvider:
# instanceClass: db.t3.micro
# allocatedStorage: 20
# engine: postgres
# patches:
# - fromFieldPath: spec.engine
# toFieldPath: spec.forProvider.engine
# - fromFieldPath: spec.size
# toFieldPath: spec.forProvider.instanceClass
# transforms:
# - type: map
# map:
# small: db.t3.micro
# medium: db.t3.medium
# large: db.r5.large
from dataclasses import dataclass
@dataclass
class PlatformAPI:
resource: str
inputs: str
creates: str
claim_lines: int
cloud_resources: int
apis = [
PlatformAPI("Database", "engine, size, region",
"RDS + Security Group + Subnet Group + Secret",
8, 4),
PlatformAPI("Cache", "engine, size, replicas",
"ElastiCache + Security Group + Parameter Group",
7, 3),
PlatformAPI("Bucket", "name, versioning, encryption",
"S3 Bucket + Policy + Lifecycle Rule",
6, 3),
PlatformAPI("Network", "cidr, azs, nat_gateway",
"VPC + Subnets + IGW + NAT + Route Tables",
8, 8),
PlatformAPI("Cluster", "version, node_size, node_count",
"EKS + Node Group + IAM Roles + Add-ons",
9, 6),
]
print("=== Platform APIs ===")
for a in apis:
print(f" [{a.resource}] Inputs: {a.inputs}")
print(f" Creates: {a.creates}")
print(f" Claim: {a.claim_lines} lines YAML | Cloud: {a.cloud_resources} resources")
Self-service Portal
# === Developer Self-service ===
# Developer Claim (what devs write — just 8 lines!)
# apiVersion: platform.example.com/v1alpha1
# kind: DatabaseClaim
# metadata:
# name: my-app-db
# namespace: team-alpha
# spec:
# engine: postgres
# size: medium
# region: ap-southeast-1
# Backstage Integration
# - Backstage Software Template creates Claim YAML
# - Developer fills form in UI (no YAML needed)
# - Template commits to Git repository
# - ArgoCD detects change, applies to cluster
# - Crossplane creates all cloud resources
# - Connection details stored in Kubernetes Secret
# GitOps Workflow
# 1. Developer opens PR with Claim YAML
# 2. CI validates schema, cost estimation
# 3. Reviewer approves PR
# 4. Merge triggers ArgoCD sync
# 5. Crossplane creates resources (~2-10 minutes)
# 6. Secret with connection details created
# 7. App reads Secret, connects to database
@dataclass
class SelfServiceFlow:
step: int
actor: str
action: str
tool: str
duration: str
flow = [
SelfServiceFlow(1, "Developer", "Select resource type and size in portal",
"Backstage / Port UI", "30 seconds"),
SelfServiceFlow(2, "CI/CD", "Validate schema, estimate cost, lint",
"GitHub Actions + OPA", "1 minute"),
SelfServiceFlow(3, "Reviewer", "Approve PR (optional for non-prod)",
"GitHub PR Review", "0-30 minutes"),
SelfServiceFlow(4, "ArgoCD", "Sync Claim to Kubernetes cluster",
"ArgoCD", "30 seconds"),
SelfServiceFlow(5, "Crossplane", "Create cloud resources",
"Crossplane Controller", "2-10 minutes"),
SelfServiceFlow(6, "Crossplane", "Store connection in Secret",
"Crossplane Connection Secret", "Automatic"),
SelfServiceFlow(7, "Developer", "Use resource via Secret reference",
"Kubernetes Secret Mount / Env", "Immediate"),
]
print("Self-service Flow:")
for s in flow:
print(f" Step {s.step}: [{s.actor}] {s.action}")
print(f" Tool: {s.tool} | Duration: {s.duration}")
Production Setup
# === Production Crossplane ===
# 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
# apiVersion: pkg.crossplane.io/v1
# kind: Provider
# metadata:
# name: provider-aws
# spec:
# package: xpkg.upbound.io/upbound/provider-family-aws:v1.0.0
# ProviderConfig with IRSA (EKS)
# apiVersion: aws.upbound.io/v1beta1
# kind: ProviderConfig
# metadata:
# name: default
# spec:
# credentials:
# source: IRSA
@dataclass
class ProductionCheck:
category: str
item: str
config: str
importance: str
checks = [
ProductionCheck("Security", "IRSA for AWS credentials",
"No static keys, use IAM Roles for Service Accounts",
"Critical"),
ProductionCheck("Security", "RBAC for Claims",
"Namespace-scoped Claims, restrict who can create what",
"Critical"),
ProductionCheck("Reliability", "HA Crossplane deployment",
"replicas: 2, PDB, resource limits",
"High"),
ProductionCheck("Observability", "Crossplane metrics",
"Prometheus ServiceMonitor for controller metrics",
"High"),
ProductionCheck("Cost", "Cost estimation in CI",
"Infracost or custom OPA policy for cost limits",
"Medium"),
ProductionCheck("Governance", "OPA/Kyverno policies",
"Enforce naming, tagging, size limits",
"High"),
ProductionCheck("GitOps", "ArgoCD Application per team",
"Separate ArgoCD App per namespace/team",
"High"),
ProductionCheck("Backup", "XRD and Composition in Git",
"Version control all platform definitions",
"Critical"),
]
print("=== Production Checklist ===")
for c in checks:
print(f" [{c.importance}] {c.category}: {c.item}")
print(f" Config: {c.config}")
เคล็ดลับ
- XRD: ออกแบบ XRD Schema ให้เรียบง่าย Developer ไม่ต้องรู้ Cloud Detail
- Patch: ใช้ Transforms Map แปลงค่าจาก Enum เป็น Cloud-specific Config
- GitOps: ใช้ ArgoCD Sync Claim จาก Git ไม่ให้ kubectl apply ตรง
- RBAC: จำกัด Claim ตาม Namespace ให้แต่ละทีมเห็นเฉพาะของตัวเอง
- Cost: ใส่ Cost Estimation ใน CI ก่อน Merge PR
Crossplane คืออะไร
Open Source Cloud Infrastructure Kubernetes API CRD AWS GCP Azure Platform Team Developer Self-service Terraform GitOps ArgoCD Flux Provider
Composition คืออะไร
รวม Resource หลายตัว Higher-level API XRD Database RDS Security Group Subnet Secret Claim Functions Patches Transforms
Low Code No Code ทำอย่างไร
XRD Schema name size region Composition Resource Claim YAML 5-10 บรรทัด Backstage Port UI GitOps Git PR ArgoCD Sync
เปรียบเทียบกับ Terraform อย่างไร
Crossplane Kubernetes Reconcile อัตโนมัติ Self-service API GitOps Terraform Imperative apply Infrastructure Team Community ใหญ่กว่า
สรุป
Crossplane Composition Low Code No Code XRD Claim Self-service Platform API Kubernetes GitOps ArgoCD AWS GCP Azure Enterprise Production
