Un desarrollador necesita una base de datos para un servicio nuevo. Abre un ticket, el equipo de plataforma añade un módulo al repositorio de Terraform, alguien revisa el plan, alguien lo aplica. Dos días en el mejor caso. Crossplane cambia la ruta: el desarrollador aplica un manifiesto en su propio namespace y a partir de ahí trabaja un controlador. La diferencia no está en la velocidad del ticket, sino en el modelo. Terraform guarda una instantánea del estado en un fichero y la reconcilia bajo demanda; Crossplane convierte la API de Kubernetes en un control plane y reconcilia de forma continua.
De qué se compone un control plane
Un Provider es un plugin que habla con una API externa: AWS, GCP, Cloudflare, GitHub. Un Managed Resource es un recurso de bajo nivel de esa API, reflejado como objeto de Kubernetes. Ahí empieza el trabajo de plataforma: un XRD declara el esquema de tu propio tipo abstracto y una Composition describe en qué se despliega ese tipo. El desarrollador ve tres campos en lugar de veinte de RDS: size: medium, version: "16" y un nombre. Todo lo demás es el contrato del equipo de plataforma, escondido en la Composition.
Qué cambió la versión dos
Crossplane salió de la incubación: la CNCF lo graduó en octubre de 2025, la línea actual es la v2.3 de mayo de 2026 y las versiones siguen un ciclo trimestral. La versión dos reescribió el modelo de cara al usuario, así que cualquier artículo donde el desarrollador crea un Claim ya está desactualizado en ese punto.
- Los XR son namespaced por defecto (
scope: Namespaceden un XRDapiextensions.crossplane.io/v2) y el objeto Claim independiente desapareció: el desarrollador crea el XR directamente en su namespace. - Los Managed Resources también pasaron a ser namespaced y los providers ganaron grupos de API con
.m., por ejemplos3.aws.m.upbound.io/v1beta1. - Una Composition ensambla cualquier recurso de Kubernetes, con lo que provider-kubernetes como rodeo para objetos dentro del clúster deja de hacer falta.
- El patch & transform nativo (
mode: Resources) se eliminó y solo quedamode: Pipelinecon composition functions en Go, Python o KCL. El YAML puro sigue disponible comofunction-patch-and-transformy para migrar existecrossplane beta convert pipeline-composition. - Operations cubre el day 2: los trabajos recurrentes de limpieza y auditoría se describen como recurso en lugar de un CronJob colgado al lado.
Qué aporta la reconciliación continua
Deriva. Terraform se entera de un cambio hecho a mano en la consola cuando alguien ejecuta un plan: en la siguiente release o en el job semanal. El controlador de Crossplane compara deseado y real todo el tiempo y devuelve el recurso al manifiesto sin intervención humana. Esa misma propiedad regala la operación de day 2: reconciliación, estados y eventos usan el mecanismo que ya conoces de los Deployments.
Self-service. El control de acceso es el RBAC por namespace de siempre, el historial de cambios es el audit log del clúster y la entrega la hace ArgoCD sincronizando un XR como cualquier otro manifiesto. Terraform se cubre de una capa como Atlantis o Spacelift para dar self-service, y esa capa también la opera alguien.
Qué se paga a cambio
«No hay fichero de estado, luego es mejor» aparece en cada comparativa y sigue siendo el argumento menos honesto. El fichero no está, el estado sí: vive en el etcd de tu clúster. De ahí salen tres consecuencias.
Observabilidad. A la pregunta «qué está desplegado y en qué estado» Terraform responde con un comando y Crossplane con un conjunto de llamadas kubectl y herramientas como k9s o la CLI de crossplane. Evidencia a escala: el flujo con estado y revisión de plan está probado en instalaciones de miles de recursos, mientras que los casos públicos de ese tamaño con Crossplane son bastante más raros. Recuperación: el clúster del control plane se convierte en un sistema de producción, así que el backup de etcd, el procedimiento de restore y los accesos pasan a ser responsabilidad tuya en lugar de una línea sobre un backend en S3.
La curva de aprendizaje es una partida aparte. XRD, Composition y funciones significan desarrollar una API de plataforma, no «escribir HCL». Hace falta un equipo que sea dueño del contrato, versione el esquema y responda preguntas sobre él. Sin ese equipo Crossplane acaba siendo el mismo Terraform, solo que más difícil de depurar.
Dónde trazo la línea
OpenTofu o Terraform para el day 0: red, clústeres, la base de IAM y el propio clúster que aloja el control plane. Crossplane del day 1 en adelante: bases de datos, colas, buckets y repositorios que los equipos piden para sus servicios cada semana. La capa de abajo cambia poco y merece revisión del plan, la de arriba cambia a menudo y necesita self-service. Elegir entre OpenTofu y Terraform no mueve esa línea: hay un análisis aparte sobre ello.
Tres errores que se ven de inmediato
- Un XR sin RBAC ni aislamiento por namespace: un desarrollador acaba pudiendo tumbar la producción del equipo vecino.
- Una Composition sin
writeConnectionSecretsToNamespace: la contraseña de la base de datos aterriza donde la aplicación no la espera. - Una Composition de dos docenas de recursos en YAML puro: un muro de parches que nadie lee en lugar de una función con tests.
Crossplane gana no por no tener fichero de estado, sino porque convierte la infraestructura en una API con esquema versionado y reconciliación constante. El precio es un equipo de plataforma que diseñe y mantenga esa API. Si no existe, quedarse en Terraform es la opción honesta.