Technology

Crossplane Composition CQRS Event Sourcing

crossplane composition cqrs event sourcing
Crossplane Composition CQRS Event Sourcing | SiamCafe Blog
2025-11-21· อ. บอม — SiamCafe.net· 10,574 คำ

Crossplane CQRS Event Sourcing

Crossplane Composition CQRS Event Sourcing Kubernetes Infrastructure Cloud AWS Azure GCP GitOps ArgoCD Audit Trail Production

PatternPurposeImplementationBenefit
Crossplane Compositionรวม Resources เป็น TemplateXRD + Composition YAMLSelf-service Reusable
CQRSแยก Read/WriteCommand API + Query APIScale แยก Optimize แยก
Event Sourcingเก็บทุก EventEvent Store (PG/Kafka)Audit Time Travel Debug
GitOpsGit เป็น Source of TruthArgoCD + Git RepositoryVersion Control Review

Crossplane Composition

# === Crossplane Composition Example ===

# CompositeResourceDefinition (XRD)
# 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
#   versions:
#     - name: v1alpha1
#       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 }

# Composition
# apiVersion: apiextensions.crossplane.io/v1
# kind: Composition
# metadata:
#   name: xdatabase-aws
# 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.medium
#             allocatedStorage: 20

from dataclasses import dataclass

@dataclass
class CompositionResource:
    claim_param: str
    small: str
    medium: str
    large: str

sizes = [
    CompositionResource("Instance Class",
        "db.t3.micro (2 vCPU 1GB)",
        "db.t3.medium (2 vCPU 4GB)",
        "db.r6g.large (2 vCPU 16GB)"),
    CompositionResource("Storage",
        "20GB gp3",
        "100GB gp3",
        "500GB io2"),
    CompositionResource("Backup Retention",
        "7 days",
        "14 days",
        "30 days"),
    CompositionResource("Multi-AZ",
        "false (Single AZ)",
        "true (Multi-AZ)",
        "true (Multi-AZ + Read Replica)"),
    CompositionResource("Monitoring",
        "Basic (CloudWatch)",
        "Enhanced (60s interval)",
        "Enhanced (1s) + Performance Insights"),
]

print("=== Database Composition Sizes ===")
for s in sizes:
    print(f"  [{s.claim_param}]")
    print(f"    Small: {s.small}")
    print(f"    Medium: {s.medium}")
    print(f"    Large: {s.large}")

CQRS + Event Sourcing

# === CQRS Event Sourcing for Infrastructure ===

# Event Types
# @dataclass
# class InfraEvent:
#     event_id: str
#     resource_id: str
#     event_type: str
#     payload: dict
#     user: str
#     timestamp: datetime
#
# events = [
#     InfraEvent("evt-001", "db-prod-01", "ResourceCreated",
#         {"engine": "postgres", "size": "medium", "region": "ap-southeast-1"},
#         "dev-team", datetime(2025,1,15,10,0)),
#     InfraEvent("evt-002", "db-prod-01", "ResourceScaled",
#         {"old_size": "medium", "new_size": "large", "reason": "traffic spike"},
#         "platform-team", datetime(2025,1,20,14,30)),
# ]

@dataclass
class EventType:
    event: str
    trigger: str
    payload: str
    read_model_update: str

events = [
    EventType("ResourceCreated",
        "Claim สร้างใหม่ → Crossplane สร้าง Resources",
        "resource_id engine size region team",
        "เพิ่ม Resource ใน Inventory + Dashboard"),
    EventType("ResourceUpdated",
        "Claim แก้ไข → Crossplane อัพเดท Resources",
        "resource_id old_config new_config changed_by",
        "อัพเดท Config History + Timeline"),
    EventType("ResourceScaled",
        "Scale Request → Composition Patch",
        "resource_id old_size new_size reason",
        "อัพเดท Capacity Dashboard + Cost"),
    EventType("ResourceFailed",
        "Crossplane detect Resource unhealthy",
        "resource_id error_message severity",
        "อัพเดท Health Dashboard + Alert"),
    EventType("DriftDetected",
        "Crossplane detect Configuration Drift",
        "resource_id expected_state actual_state",
        "อัพเดท Compliance Dashboard + Alert"),
    EventType("ResourceDeleted",
        "Claim ลบ → Crossplane ลบ Resources",
        "resource_id deleted_by reason",
        "ลบจาก Inventory + Archive Event"),
]

print("=== Infrastructure Events ===")
for e in events:
    print(f"  [{e.event}] Trigger: {e.trigger}")
    print(f"    Payload: {e.payload}")
    print(f"    Read Model: {e.read_model_update}")

Production Architecture

# === Production Stack ===

@dataclass
class ArchComponent:
    component: str
    tool: str
    role: str
    scaling: str

architecture = [
    ArchComponent("GitOps",
        "ArgoCD + Git Repository",
        "Source of Truth สำหรับ Crossplane Compositions Claims",
        "ArgoCD HA 3 replicas"),
    ArchComponent("Control Plane",
        "Crossplane + Providers",
        "Reconcile Claims → Cloud Resources",
        "Crossplane Pods HA + Provider Pods"),
    ArchComponent("Event Capture",
        "Custom Controller (Kubebuilder)",
        "Watch Crossplane Resources → Publish Events",
        "Controller HA 2 replicas"),
    ArchComponent("Event Store",
        "Apache Kafka (3 brokers)",
        "Store Infrastructure Events Durable Ordered",
        "Kafka Cluster 3+ brokers"),
    ArchComponent("Read Model",
        "PostgreSQL + Materialized Views",
        "Optimized Read Model สำหรับ Dashboard API",
        "PostgreSQL HA Primary + Replica"),
    ArchComponent("Dashboard",
        "Grafana + Custom UI (React)",
        "Infrastructure Inventory Timeline Audit Compliance",
        "Grafana HA + CDN for UI"),
]

print("=== Production Architecture ===")
for a in architecture:
    print(f"  [{a.component}] Tool: {a.tool}")
    print(f"    Role: {a.role}")
    print(f"    Scale: {a.scaling}")

เคล็ดลับ

Crossplane คืออะไร

Open Source IaC Kubernetes API Cloud AWS Azure GCP Providers Compositions XRD Claim Self-service GitOps ArgoCD Multi-cloud

CQRS คืออะไร

Command Query Segregation แยก Read Write Command Validate Execute Query Read Model Optimize Scale แยก Audit Trail Dashboard

Event Sourcing ทำอย่างไร

เก็บทุก Event History ResourceCreated Updated Scaled Failed Drift Deleted Kafka PostgreSQL Replay Time Travel Audit Compliance

Production ใช้อย่างไร

ArgoCD GitOps Crossplane Controller Kafka Event Store PostgreSQL Read Model Grafana Dashboard Drift Detection Compliance SOC2

สรุป

Crossplane Composition CQRS Event Sourcing Kubernetes GitOps ArgoCD Kafka PostgreSQL Audit Trail Drift Detection Compliance Production

📖 บทความที่เกี่ยวข้อง

MLOps Pipeline CQRS Event Sourcingอ่านบทความ → Java Micronaut CQRS Event Sourcingอ่านบทความ → Crossplane Composition Low Code No Codeอ่านบทความ → Crossplane Composition Event Driven Designอ่านบทความ → NFS v4 Kerberos CQRS Event Sourcingอ่านบทความ →

📚 ดูบทความทั้งหมด →