Pular para o conteúdo

O catálogo

O catálogo é onde o Airframe guarda sua intenção: um repositório git de pequenos arquivos YAML que dizem quais produtos existem, quem é responsável por eles e do que cada um precisa. Todo o resto que a plataforma constrói, dos projetos na nuvem aos painéis, deriva desses arquivos. Por isso, mudar a organização significa mudar um arquivo, por um merge request que as pessoas certas aprovam.

A maioria das organizações guarda essas informações em vários lugares ao mesmo tempo: uma planilha de serviços, um formulário de portal, as associações de uma dúzia de ferramentas. Essas cópias se distanciam, e ninguém consegue dizer qual está certa.

O Airframe guarda uma só cópia. Como o catálogo é um repositório git, toda mudança nele é um merge request: revisada antes de acontecer, registrada com quem a fez e por quê, e fácil de desfazer. Não há um inventário separado para manter sincronizado, porque o catálogo é o inventário.

Arquivos do catálogoO que derivajornadas, domíniose contextosum arquivo deprodutoequipes e pessoaso modelo deresponsáveispastas egrupos do Googleprojetos eidentidadesrepositório epermissões de mergepainéis eregras de alertaregras de responsáveisdo controle

O catálogo descreve a organização como uma árvore de quatro níveis:

  • uma jornada é uma área ampla do negócio; a organização de demonstração tem três: shop, fulfil e settle;
  • um domínio fica dentro de uma jornada, como store em shop;
  • um contexto fica dentro de um domínio, como ordering em store: um grupo de produtos muito relacionados e as equipes que os constroem;
  • um produto fica dentro de um contexto, como orders em ordering.

Cada nível é um arquivo com o nome do seu caminho completo: journeys/shop.yaml, domains/shop.store.yaml, contexts/shop.store.ordering.yaml e products/shop.store.ordering.orders.yaml. Um arquivo nomeia os líderes do seu nível, as pessoas que aprovam alguns tipos de mudança abaixo dele. Um nome só precisa ser único entre seus irmãos, porque o caminho é a identidade, e as verificações do catálogo recusam um arquivo cujo pai não existe.

Outros dois tipos de arquivo descrevem pessoas. Um arquivo de equipe, como teams/store-core.yaml, diz em qual contexto a equipe vive, quem a lidera, quem são seus membros e qual papel cada um tem (desenvolvedor, líder de equipe, plantão), e como funciona seu rodízio de plantão. Um arquivo de pessoa tem um nome, um endereço de e-mail no domínio da organização e um status: ativa, pendente (ainda sem conta) ou desligada.

Estes são os principais campos do arquivo do produto de pedidos, como estão no catálogo de demonstração:

product: orders
journey: shop
domain: store
context: ordering
team: store-core
criticality: 2
data_classification: internal
rto: 1h
rpo: 15m
monthly_budget: 5
stack: node
slo: { availability: 99.5, latency_p95_ms: 400 }
sandbox: true
lifecycle: { status: retiring, retire_after: "2099-12-31" }

Em palavras simples:

  • team é a equipe responsável pelo produto; seus membros podem aprovar mudanças nele.
  • criticality diz o quanto o negócio sofre quando o produto falha, de 1 (para o fluxo de pedidos) a 3 (ferramentas internas). Ela define, por exemplo, o nível do banco de dados e os limites dos alertas.
  • data_classification diz o quanto seus dados são sensíveis, de public a restricted; um produto restrito recebe um repositório privado em uma parte restrita do GitLab.
  • rto e rpo são seus objetivos de recuperação: em quanto tempo ele precisa voltar depois de uma falha, e quantos dados recentes pode perder. Eles definem os backups do seu banco de dados.
  • monthly_budget é em dólares americanos, produção e não produção juntas. É um limite, não uma anotação: um merge request cujos planos com preço passam dele não pode ser integrado.
  • stack escolhe a aplicação que o golden path gera: Node, Python ou Java.
  • slo é sua meta de confiabilidade, que suas regras de alerta usam.
  • sandbox pede uma cópia estável de não produção contra a qual outros produtos podem testar.
  • lifecycle diz se o produto está ativo, sendo aposentado ou removido.

Quando o arquivo de um produto é integrado, os reconciliadores criam, entre outras coisas:

  • o repositório projectairframe/shop/store/ordering/orders, com seu primeiro commit gerado a partir do template do golden path;
  • dois projetos do Google Cloud, lk-store-orders-<rnd> e lk-store-orders-np-<rnd>, com uma identidade de plan e uma de apply em cada um;
  • o grupo do Google dos usuários do produto, que é o público que seu nome de host admite atrás do login único;
  • seus painéis e regras de alerta no Grafana;
  • quando seus projetos têm faturamento, um orçamento do Google Cloud em cada um, 70 por cento do orçamento mensal para produção e 30 para não produção.

O faturamento em si não está no catálogo: os projetos de um produto são faturados ao adicioná-lo a uma lista no repositório landing-zone, em um merge request separado. A página de reconciliadores explica a cadeia que faz esse trabalho.

Cada produto recebe dois projetos do Google Cloud: um para produção e outro para tudo o que não é produção, como suas prévias e seu sandbox. É o design, não um passo rumo a compartilhá-los: a fábrica de projetos do domínio do produto cria os dois a partir da entrada do catálogo, para cada produto.

O motivo é o limite de permissões. As identidades de plan e de apply de um produto têm seus papéis nos projetos do próprio produto, então a identidade que aplica o Terraform de um produto pode mudar esse produto e nada mais. Um erro nesse código, ou um token de pipeline roubado, pode danificar no máximo um produto. Um projeto compartilhado por vários produtos não pode oferecer isso: uma identidade capaz de mudar um deles poderia mudar todos. As cotas e os logs de auditoria são mantidos por projeto, e a fábrica dá a cada projeto com faturamento seu próprio orçamento, então cada produto tem os seus. O segundo projeto deixa as prévias, suas identidades e seus dados de teste fora do limite de produção.

O que mais projetos custam, e o que não custam:

  • O Google Cloud não cobra nada por um projeto. O que se multiplica com os produtos é o que cada produto tem para si, como sua própria instância do Cloud SQL, e isso vem de manter os produtos separados, não do número de projetos.
  • Ninguém cria nem administra à mão o projeto de um produto. A fábrica cria cada um com suas identidades, permissões e rótulos, e lhe dá um orçamento quando ele passa a ter faturamento; os reconciliadores conectam à rede compartilhada os que têm faturamento. A equipe de plataforma mantém entradas do catálogo, não projetos.
  • A maioria das cotas do Google Cloud se aplica por projeto, como o número de instâncias do Cloud SQL e de contas de serviço e a taxa de solicitações às APIs. Projetos separados dão a cada produto seus próprios limites, então o pipeline muito ativo de uma equipe não consegue esgotar a cota de API de outra equipe.

Duas coisas crescem, sim, com o número de projetos, e vale verificá-las antes de adotar o Airframe:

  • Projetos por conta de faturamento. Uma conta de faturamento só consegue vincular ao faturamento um número limitado de projetos, e cada produto com faturamento ocupa dois. A do Airframe podia vincular cinco no início. Aumentar o limite é uma solicitação ao Google, como explicam os pré-requisitos.
  • Ferramentas com preço por projeto. Se a sua organização paga uma ferramenta pelo número de projetos do Google Cloud, como cobram alguns produtos de segurança e de monitoramento, conte dois para cada produto.

A alavanca é o que conta como produto. A unidade é o limite de uma carga de trabalho, não cada aplicação. Várias ferramentas pequenas de uma equipe, com a mesma criticidade e a mesma classificação de dados, podem ser um produto com vários serviços: um par de projetos e um conjunto de identidades de pipeline. O design acrescenta dois refinamentos, e nenhum está construído. Um produto com uma parte que difere em criticidade ou classificação de dados poderia declarar essa parte como um componente, e só o componente receberia um par de projetos próprio: o catálogo aceita o campo components, e nenhuma fábrica de projetos o lê ainda (projetado). E os produtos poderiam compartilhar computação, em namespaces de um cluster do GKE por ambiente, enquanto seus dados, identidades, segredos e estado ficam nos próprios projetos: ainda não existe nenhum cluster (projetado). As páginas de campos do catálogo e de trazer um sistema existente dizem mais.

O acesso não é concedido projeto a projeto. O acesso de leitura de uma equipe aos projetos dos seus produtos e aos seus logs vem do catálogo: a fábrica dá esses papéis em cada projeto dos produtos da equipe ao grupo do Google da equipe, e a raiz de grupos preenche o grupo a partir do arquivo da equipe. A concessão administrativa que uma pessoa pode pedir durante um incidente, o nível 2, é definida uma vez, na pasta da organização de demonstração, então cobre todos os projetos de produtos, inclusive os novos. Identidades e acesso e as concessões explicam as duas coisas.

O catálogo também diz quem precisa aprovar cada mudança, em um arquivo: ownership/protected-paths.yaml, o modelo de responsáveis. Para mudanças no próprio catálogo, ele diz:

  • o arquivo de um produto é aprovado pela equipe do produto, ou pelos líderes do seu contexto ou do seu domínio;
  • aumentar o orçamento de um produto, ou permitir que ele use um serviço novo do Google Cloud, precisa de um líder do domínio;
  • uma mudança de status do ciclo de vida precisa de dois aprovadores: um da equipe do produto e outro dos líderes do domínio ou da equipe de plataforma, e o merge request precisa ter o rótulo lifecycle;
  • o arquivo de uma equipe é aprovado pelos seus líderes ou pelos líderes do seu contexto;
  • o próprio perfil de uma pessoa precisa dela: da sua aprovação, ou de um merge request que ela abriu e cujos commits são todos seus; o resto do seu arquivo precisa dos líderes das suas equipes;
  • a estrutura, ou seja, as jornadas, domínios e contextos, o modelo de responsáveis, o esquema e os serviços aprovados, precisa de dois membros da equipe de plataforma.

O autor de uma mudança e os autores dos seus commits nunca contam como aprovadores. Uma pessoa que muda o próprio perfil ainda precisa da aprovação de outra pessoa nomeada, que a política de aprovação de todo o grupo exige em cada merge. Na demonstração, os líderes fictícios não têm conta no GitLab, então a equipe de plataforma os substitui.

O mesmo arquivo também cobre o repositório de cada produto: por exemplo, seu diretório infra/ precisa da aprovação da equipe, e seu arquivo de pipeline de uma única aprovação, da equipe ou da equipe da plataforma. O controle de aprovação o lê diretamente em cada merge request, sempre a partir da branch main protegida do catálogo, nunca da mudança que está julgando. Cada repositório também tem um arquivo CODEOWNERS. O de um produto é escrito uma só vez, quando o repositório é criado, e nomeia o grupo do seu contexto, e os arquivos dos repositórios da plataforma não são comparados com o modelo. O do próprio catálogo é gerado a partir do modelo pelo mesmo gerador do controle, e o job catalog:codeowners do control-plane compara os dois depois de cada merge no catálogo, onde uma diferença gera um aviso, e todo dia, onde uma diferença falha e uma issue fica aberta até que um merge request no catálogo gere o arquivo de novo. Em todos os casos é o controle, não o CODEOWNERS, que aplica o modelo.

Um produto nunca é simplesmente apagado. Ele passa por três estados, e cada um é uma mudança no seu arquivo:

  1. active: o produto funciona.
  2. retiring: seus serviços saem da borda compartilhada e vão a zero instâncias, e todos os projetos, bancos de dados e buckets são mantidos.
  3. removed: permitido só depois da data retire_after da entrada. Os projetos e o repositório do produto são excluídos.

Um produto removido deixa uma lápide: um arquivo em retired-names/, como retired-names/shop.store.returns.yaml para um produto removido em 2026-09-14. As verificações do catálogo recusam qualquer produto novo com esse nome em todo o domínio, e recusam qualquer mudança em uma lápide, de modo que um nome nunca é reutilizado.

Onde fica

No repositório catalog:

No repositório landing-zone:

Licença MIT. Copyright dos colaboradores do Airframe.

Este site descreve a versão 2026.10.20-1 da plataforma.