Golden Paths: Como Templates Backstage Garantem Serviços Corretos por Padrão
Documentação é ignorada. Runbooks ficam desatualizados. Páginas de wiki acumulam instruções conflitantes de três autores diferentes. Quando o "jeito certo" de criar um serviço existe apenas em documentação, cada novo serviço é uma chance de desviar da convenção.
Os templates do Backstage Scaffolder mudam essa equação. Em vez de documentar o caminho correto e torcer para que os engenheiros sigam, codificamos o caminho correto em um formulário que produz saída correta todas as vezes. Este post é sobre como nossa cadeia de templates funciona, por que a ordem de dependência importa, e o que acontece quando você clica em Create.
O problema com padrões baseados em documentação
Nossa convenção de plataforma define um padrão preciso de nomenclatura, 9 labels obrigatórios, padrões de segurança e uma estrutura específica de repositório. Antes dos templates, aplicar esses padrões significava:
- Ler 3 páginas diferentes de wiki
- Copiar e colar YAML de exemplos (frequentemente desatualizados)
- Torcer para o revisor pegar o que você esqueceu
- Esperar o time de plataforma corrigir o que o revisor não pegou
O resultado: 80% dos novos serviços precisavam de pelo menos um PR de correção após a criação inicial. Conformidade com a convenção era aspiracional.
Templates como mecanismo de aplicação
Um template do Backstage Scaffolder é uma definição YAML que combina um formulário voltado ao usuário com uma sequência de ações automatizadas. O desenvolvedor preenche o formulário. O template gera todos os arquivos, abre os PRs e registra a entidade no catálogo.
O template não documenta a convenção — ele implementa a convenção. Não existe como criar um serviço com labels faltando, nomenclatura errada ou contexto de segurança incorreto, porque o template gera tudo isso.
A cadeia de templates
Templates têm dependências. Você não pode criar um serviço sem um system. Não pode criar um system sem um domain. A cadeia impõe esta ordem:
Camada de pessoas (execute a qualquer momento)
──────────────────────────────────────────────────────
create-group → entidade Group + RBAC + papéis ArgoCD
create-user → entidade User + RBAC + acesso ArgoCD
Camada de plataforma (execute em ordem)
──────────────────────────────────────────────────────
create-domain
│ Entidade Domain, repositório {domain}-gitops, AppProject
▼
create-system
│ Entidade System, ApplicationSet
▼
├─────────────────────────┬─────────────────────┐
▼ ▼ ▼
create-service create-resource create-secret
Entidade Component, Entidade Resource, SealedSecret
App Repo (CI/CD, Claim Crossplane/env, manifesto/env
TechDocs, .k8s), namespace de infra
manifestos k8s/env
Cada template usa EntityPicker para selecionar seu pai. Você escolhe o domain de um dropdown que mostra apenas domains existentes. Escolhe o system de um dropdown filtrado pelos systems daquele domain. A integridade referencial é aplicada pela própria interface.
O que o create-service realmente faz
Quando um engenheiro de produto executa create-service, ele preenche:
- System: selecionado do catálogo (domain, repo e AppProject resolvem automaticamente)
- Nome do serviço: ex.,
api,worker,frontend - Tipo do serviço: api / worker / frontend / grpc / cronjob
- Imagem do contêiner: caminho do registry
- Perfil de recursos: qual tier de CPU/memória
- Ambientes alvo: em quais envs fazer deploy
Então o template executa:
Passo 1 — Gerar o Repositório da Aplicação
Um novo repositório é criado com:
{app}-repo/
├── src/ ← código fonte boilerplate
├── Dockerfile ← otimizado, non-root, específico da linguagem
├── .github/workflows/
│ └── ci.yaml ← lint, test, build, publish, atualização de tag
├── .k8s/
│ └── values.yaml ← sobrescrições (tag da imagem, réplicas, recursos)
├── docs/
│ └── index.md ← base do TechDocs
└── catalog-info.yaml ← entidade Component do Backstage
Passo 2 — Gerar manifestos Kubernetes no repositório do domínio
Em {domain}-gitops/k8s/{env}/{service}/, o template cria:
- Namespace com todos os 9 labels obrigatórios
- Deployment com contexto de segurança, limites de recursos, probes de readiness/liveness
- Service expondo a porta correta
- HPA com escalonamento apropriado por env (dev: 1→2, staging: 2→5, prod: 3→10)
- PDB (apenas prod,
minAvailable: 1) - NetworkPolicy isolando por fronteira de projeto
Passo 3 — Atualizar o ApplicationSet
No platform-gitops, o template adiciona o novo serviço como elemento no ApplicationSet existente:
elements:
- service: api # ← existente
- service: worker # ← adicionado pelo template
Passo 4 — Registrar e abrir PRs
O template abre dois PRs:
- PR do repositório do domínio: manifestos k8s + entidade Component
- PR do repositório da plataforma: elemento do ApplicationSet
Ele também registra o novo catalog-info.yaml no catálogo do Backstage.
A ordem de merge importa: PR da plataforma primeiro (o ApplicationSet deve existir antes que o ArgoCD possa sincronizar), depois o PR do domínio. Em minutos após ambos serem mergeados, o serviço está rodando no cluster dev.
O workflow de dois PRs
Todo template segue o mesmo padrão: um PR no repositório do domínio/catálogo, um PR no platform-gitops. Essa separação existe porque:
- Times de domínio são donos de seus manifestos — eles revisam e mergeiam o que implantam
- Time de plataforma é dono do roteamento — eles revisam mudanças na configuração do ArgoCD e RBAC
- CODEOWNERS impõe isso — mudanças no repositório errado são bloqueadas automaticamente
Resultados
Desde a adoção dos templates:
- 100% de conformidade de labels em todos os novos serviços (era < 20%)
- < 3 minutos do clique em Create até os PRs abertos (eram horas de YAML manual)
- Zero violações de convenção em serviços gerados por template
- Serviço rodando em dev em < 30 minutos (era 2–5 dias)
Os templates não apenas tornaram a criação de serviços mais rápida — tornaram violações de convenção estruturalmente impossíveis para novos serviços. O "jeito correto" é o único jeito.
A cadeia completa de templates e resumo de saída estão documentados na Convenção da Plataforma — Templates. O modelo de entidades do Backstage e design do catálogo estão na Convenção Backstage.