O que é Crossplane e por que você deve aprender
Crossplane é um framework open-source que traz o conceito de Infrastructure as Code (IaC) para dentro do Kubernetes, permitindo que você provisione e gerencie recursos em nuvens (AWS, Azure, GCP) usando manifestos YAML nativos do Kubernetes. Em vez de usar ferramentas separadas como Terraform ou CloudFormation, você define sua infraestrutura através de Custom Resources (CRs) que o Kubernetes orquestra.
A grande vantagem é unificar o gerenciamento: aplicações, configurações e infraestrutura vivem no mesmo cluster, com o mesmo padrão declarativo. Você ganha versionamento de infraestrutura, RBAC nativo, GitOps pronto para usar, e elimina a necessidade de pipelines separados para aplicação e infraestrutura. Isso é especialmente poderoso em ambientes cloud-native onde a flexibilidade e a automação são críticas.
Arquitetura e Conceitos Fundamentais
Componentes Principais
A arquitetura do Crossplane repousa em três pilares: o control plane (o próprio cluster Kubernetes), providers (conectores para serviços em nuvem) e managed resources (representações dos recursos reais na nuvem).
Quando você instala o Crossplane no cluster, ele implanta controllers que ficam observando os CRs. Se você cria um recurso do tipo RDSInstance, o controller do provider AWS detecta e provisiona uma instância RDS real na sua conta. O estado é sincronizado: mudanças no manifest atualizam a nuvem, e mudanças na nuvem (detectadas via polling) são refletidas no Kubernetes.
Providers e Composições
Providers são pacotes que estendem o Kubernetes com novos tipos de recursos. O provider AWS adiciona RDSInstance, S3Bucket, VPC, etc. Você pode instalar múltiplos providers no mesmo cluster, permitindo gerenciar infraestrutura multi-cloud.
Composições (Compositions) são o ponto forte: permitem criar abstrações sobre recursos brutos. Por exemplo, em vez de expor toda a complexidade de criar um banco RDS (security groups, parameter groups, backups), você cria um CompositeResourceDefinition (XRD) chamado PostgreSQL que encapsula tudo. Aplicações usam apenas PostgreSQL, isoladas da complexidade.
Instalação e Configuração Inicial
Instalando Crossplane
A instalação é simples via Helm. Certifique-se de ter um cluster Kubernetes rodando (versão 1.16+) e acesso à conta de nuvem desejada.
# Adicionar repositório Helm
helm repo add crossplane-stable https://charts.crossplane.io/stable
helm repo update
# Instalar Crossplane no namespace crossplane-system
helm install crossplane crossplane-stable/crossplane \
--namespace crossplane-system \
--create-namespace \
--wait
Verifique se está rodando:
kubectl get pods -n crossplane-system
# Você deve ver crossplane e crossplane-rbac-manager rodando
Instalando um Provider
Vamos usar o provider AWS. Crie um manifesto YAML com a definição do provider:
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
name: upbound-provider-aws
spec:
package: xpkg.upbound.io/upbound-provider-aws:v0.45.0
Aplique no cluster:
kubectl apply -f provider.yaml
kubectl get providers
O Crossplane baixa o pacote e instala os CRDs automaticamente. Aguarde alguns minutos até que o status mude para Healthy.
Configurando Credenciais
Para que o provider acesse sua conta AWS, você precisa configurar credenciais. Crie um arquivo credentials.txt com sua chave de acesso:
[default]
aws_access_key_id = YOUR_ACCESS_KEY
aws_secret_access_key = YOUR_SECRET_KEY
Crie um Secret no Kubernetes:
kubectl create secret generic aws-secret \
-n crossplane-system \
--from-file=creds=./credentials.txt
Agora, crie uma ProviderConfig que informa ao provider como usar essas credenciais:
apiVersion: aws.crossplane.io/v1beta1
kind: ProviderConfig
metadata:
name: default
spec:
credentials:
source: Secret
secretRef:
namespace: crossplane-system
name: aws-secret
key: creds
region: us-east-1
Aplique:
kubectl apply -f provider-config.yaml
A partir de agora, qualquer recurso AWS que você criar usará essa ProviderConfig automaticamente.
Provisionando Recursos Gerenciados
Seu Primeiro Recurso: Um Bucket S3
Vamos criar um bucket S3 simples usando Crossplane. Crie um manifesto:
apiVersion: s3.aws.crossplane.io/v1
kind: Bucket
metadata:
name: meu-bucket-crossplane
spec:
forProvider:
region: us-east-1
acl: private
providerConfigRef:
name: default
Aplique:
kubectl apply -f s3-bucket.yaml
Verifique o status:
kubectl get buckets
kubectl describe bucket meu-bucket-crossplane
Em segundos, você verá o bucket criado na sua conta AWS. Se deletar o manifesto, o bucket é deletado automaticamente (por padrão). Isso é IaC real: sua infraestrutura vive como código no Git.
Criando um Banco de Dados RDS PostgreSQL
Um exemplo mais realista: provisionar um RDS PostgreSQL. Este manifesto cria a instância, a subnet group e handles automaticamente:
apiVersion: rds.aws.crossplane.io/v1
kind: DBInstance
metadata:
name: meu-postgres
spec:
forProvider:
dbInstanceIdentifier: meu-postgres
engine: postgres
engineVersion: "15.3"
dbInstanceClass: db.t3.micro
masterUsername: admin
masterUserPassword: "SuperSenha123!" # Melhor usar Secret
allocatedStorage: "20"
region: us-east-1
skipFinalSnapshot: true
publiclyAccessible: false
providerConfigRef:
name: default
kubectl apply -f rds.yaml
Aguarde alguns minutos. O Crossplane provisiona a instância e sincroniza o status no manifesto. Você pode inspecionar:
kubectl get dbinstances
kubectl describe dbinstance meu-postgres
Melhor Prática: Usar Secrets para Senhas
Nunca hardcode senhas. Use Kubernetes Secrets e referencie via connectionSecretRef:
apiVersion: rds.aws.crossplane.io/v1
kind: DBInstance
metadata:
name: meu-postgres-seguro
spec:
forProvider:
dbInstanceIdentifier: meu-postgres-seguro
engine: postgres
engineVersion: "15.3"
dbInstanceClass: db.t3.micro
masterUsername: admin
allocatedStorage: "20"
region: us-east-1
skipFinalSnapshot: true
connectionSecretRef:
namespace: default
name: postgres-creds
providerConfigRef:
name: default
O Crossplane cria automaticamente um Secret postgres-creds contendo endpoint, porta e credenciais. Suas aplicações podem montar esse Secret.
Abstraindo Complexidade com Composições
O Problema de Expor Complexidade
Expor todos os detalhes de RDS (security groups, parameter groups, backups, replication) para cada desenvolvedor criar é caótico. Eles precisam conhecer detalhes AWS, não de negócio. A solução: Composições.
Criando um CompositeResourceDefinition (XRD)
Um XRD define um novo tipo de recurso abstrato. Crie postgresql-xrd.yaml:
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
name: xpostgresqls.my.company
spec:
group: my.company
names:
kind: XPostgreSQL
plural: xpostgresqls
claimNames:
kind: PostgreSQL
plural: postgresqls
versions:
- name: v1alpha1
served: true
referenceable: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
size:
type: string
enum: ["small", "medium", "large"]
default: "small"
storageGB:
type: integer
default: 20
required:
- size
- storageGB
status:
type: object
properties:
endpoint:
type: string
port:
type: integer
Aplique:
kubectl apply -f postgresql-xrd.yaml
Agora você tem dois novos tipos: XPostgreSQL (recurso composto interno) e PostgreSQL (reclamação para aplicações).
Criando a Composition
A Composition mapeia os parâmetros abstratos para recursos AWS reais. Crie postgresql-composition.yaml:
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: postgresql-aws
spec:
compositeTypeRef:
apiVersion: my.company/v1alpha1
kind: XPostgreSQL
resources:
- name: rds-instance
base:
apiVersion: rds.aws.crossplane.io/v1
kind: DBInstance
spec:
forProvider:
engine: postgres
engineVersion: "15.3"
region: us-east-1
skipFinalSnapshot: true
connectionSecretRef:
namespace: default
providerConfigRef:
name: default
patches:
- fromFieldPath: "spec.size"
toFieldPath: "spec.forProvider.dbInstanceClass"
transforms:
- type: map
map:
small: "db.t3.micro"
medium: "db.t3.small"
large: "db.t3.medium"
- fromFieldPath: "spec.storageGB"
toFieldPath: "spec.forProvider.allocatedStorage"
- fromFieldPath: "metadata.uid"
toFieldPath: "spec.forProvider.dbInstanceIdentifier"
transforms:
- type: string
string:
fmt: "pg-%s"
- fromFieldPath: "metadata.name"
toFieldPath: "spec.connectionSecretRef.name"
Aplique:
kubectl apply -f postgresql-composition.yaml
Usando a Composição
Agora, desenvolvedores usam apenas:
apiVersion: my.company/v1alpha1
kind: PostgreSQL
metadata:
name: app-database
namespace: production
spec:
size: medium
storageGB: 50
kubectl apply -f app-database.yaml
O Crossplane automaticamente provisiona um RDS db.t3.small com 50GB de armazenamento. Simples, limpo, seguro. A Composition encapsula boas práticas: backups, tagging, networking.
Padrões Avançados e Boas Práticas
GitOps com Crossplane
A maior força do Crossplane é integração nativa com GitOps. Use Flux ou ArgoCD:
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
name: infra-repo
namespace: flux-system
spec:
interval: 1m
url: https://github.com/seu-usuario/infrastructure-repo
ref:
branch: main
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: infra-kustomize
namespace: flux-system
spec:
interval: 10m
sourceRef:
kind: GitRepository
name: infra-repo
path: ./crossplane-resources
prune: true
wait: true
Toda mudança no Git provoca alteração de infraestrutura automaticamente. Auditoria completa, rollback fácil, histórico versionado.
Usando XRD com Policies e Validação
Você pode adicionar policies ao XRD para forçar padrões corporativos:
apiVersion: my.company/v1alpha1
kind: PostgreSQL
metadata:
name: app-database
spec:
size: large # Vai gerar erro se não estiver na enum
storageGB: 5 # Pode adicionar validação de mínimo
Use validation.rules no OpenAPI schema do XRD para validações complexas.
Monitoramento e Troubleshooting
Inspecione o status detalhado:
kubectl describe postgresql app-database
# Mostra condições, eventos, recursos criados
Verifique logs do controller:
kubectl logs -n crossplane-system deployment/crossplane -f
Use kubectl get events -n default para ver eventos de reconciliação.
Conclusão
Aprendemos que Crossplane unifica aplicações e infraestrutura sob o mesmo paradigma Kubernetes, eliminando silos e ferramentas paralelas. Você provisionou recursos AWS em YAML puro, com reconciliação automática e sincronização de estado.
Segundo, Composições são o mecanismo de abstração que habilita plataformas internas: desenvolvedores trabalham com conceitos de negócio (PostgreSQL, WebApp) enquanto a Composition garante boas práticas, compliance e padrões corporativos. Isso escala em organizações grandes.
Terceiro, GitOps com Crossplane fornece auditoria, versionamento e rollback de infraestrutura que outras ferramentas não oferecem nativamente. Sua infraestrutura é código, tratado como tal.