El primer producto
Esta página es la guía práctica para el primer producto de un equipo en Airframe. Nombra el archivo que escribes en cada paso, quién tiene que aprobarlo, y qué mirar mientras la plataforma construye el resto. Sigue el mismo camino que la vida de un producto, un nivel más cerca del teclado, y supone que el dominio y el contexto del producto ya existen.
El ejemplo es un producto nuevo del equipo de la tienda de la organización de demostración, giftcards, en el contexto shop/store/ordering.
1. Escribe la entrada
Sección titulada «1. Escribe la entrada»Dónde: el repositorio del catálogo, un archivo nuevo con el nombre de la ruta del producto, products/shop.store.ordering.giftcards.yaml.
product: giftcardsjourney: shopdomain: storecontext: orderingteam: store-corecriticality: 3data_classification: internalrto: 4hrpo: 1hmonthly_budget: 10template: fullstackstack: nodeslo: { availability: 99.0, latency_p95_ms: 400 }sandbox: truelifecycle: { status: active }Qué contiene el archivo de un producto explica cada campo. Tres de ellos eligen lo que recibes: template: fullstack pide un repositorio generado a partir de la plantilla del golden path, stack elige su aplicación (node, python-fastapi o java-spring), y sandbox: true agrega un entorno permanente para los consumidores del producto.
Antes de abrir el merge request, revisa lo que va a verificar el lint del catálogo:
- el equipo existe y vive en este contexto, y al menos una persona que puede hacer merge en el producto tiene una cuenta de GitLab;
- el equipo de un producto de criticidad 1 o 2 tiene dos miembros con un rol de guardia;
- el nombre tiene de 2 a 10 caracteres, no se usa en el dominio, y nunca lo usó un producto eliminado;
- los presupuestos de todos los productos y espacios de prueba siguen cabiendo en el presupuesto mensual de la organización en
catalog.yaml.
Ejecuta npm run lint en un clon del catálogo para ver los mismos mensajes en tu laptop.
2. Abre el merge request y consigue las aprobaciones
Sección titulada «2. Abre el merge request y consigue las aprobaciones»Quién aprueba: una persona del equipo del producto, de los líderes del contexto o de los líderes del dominio, que no sea ni el autor ni alguien que hizo un commit, y un líder del dominio, porque el presupuesto de una entrada nueva cuenta como un aumento desde cero. La aprobación de un líder del dominio cubre las dos cosas. La compuerta de aprobación verifica esas aprobaciones contra el modelo de responsables del catálogo y agrega la suya, que la política de aprobación de security-policies exige antes de que el catálogo pueda integrar el cambio (aplicado).
Algunos campos suman otros aprobadores:
- un
monthly_budgetmayor que cero, que tiene toda entrada nueva, y cualquier aumento posterior necesitan a un líder del dominio; - una suscripción en
consumesnecesita a un responsable del producto que publica, salvo que el tópico esté marcado como inner source; - un destino en
callsnecesita a un responsable del producto llamado; - un servicio en
servicesnecesita a un líder del dominio.
3. Sigue la nota de progreso
Sección titulada «3. Sigue la nota de progreso»Después del merge, el pipeline del catálogo inicia la cadena de reconciliadores y un job, progress:track, que escribe una nota en el merge request integrado y la mantiene al día. La nota muestra cada pasada de la cadena con su hora y su enlace, después el repositorio nuevo, su primer pipeline y el momento en que responde el nombre de host. Si algo falla, la nota nombra el job que falló y el paso siguiente. El job se detiene cuando el producto está en funcionamiento o falló, o después de tres horas, y dice cuál de las dos cosas pasó.
En el ensayo de la plataforma del 2026-09-20, la cadena tardó unos treinta minutos desde el merge hasta el repositorio.
4. Factura el producto
Sección titulada «4. Factura el producto»Dónde: landing-zone, la fábrica de proyectos del dominio: agrega el nombre del producto a billed_products en roots/project-factory/shop-store/variables.tf.
Quién aprueba: el equipo de la plataforma.
Los dos proyectos del producto existen sin facturación, con sus identidades y permisos. Mientras no estén facturados, su pipeline planifica de verdad y su apply se detiene en el primer servicio que necesita facturación. La facturación va aparte porque la cuenta de facturación solo puede vincular una cantidad limitada de proyectos, así que ocupar dos más es una decisión en sí misma.
Este paso puede ir primero. En el ensayo, el merge request de facturación se integró tres minutos antes que la entrada del catálogo, así que el primer pipeline del producto aplicó enseguida. Si facturas después, sigue Costo y facturación, pasos 3 a 5. El pipeline del propio merge de facturación aplica solo la raíz de la fábrica; la raíz de red conecta los proyectos a la red compartida recién en un pipeline posterior de landing-zone, que alguien autorizado a ejecutar pipelines en la main de landing-zone inicia a demanda. Inicia un pipeline nuevo en la main del producto solo después de que ese haya aplicado: las personas que pueden hacer merge en el producto pueden hacerlo.
5. El primer despliegue
Sección titulada «5. El primer despliegue»Nadie aprueba este paso por separado: el primer commit del repositorio lo genera la plataforma a partir de la entrada, y el merge request del catálogo es su aprobación. La compuerta de aprobación lo admite como el primer commit de un repositorio de producto generado desde el catálogo.
El pipeline de ese commit se ejecuta en main como todos los siguientes. build:request hace que el constructor de confianza compile las imágenes, y el pipeline planifica cada raíz con plan:<root>, verifica cada plan con policy:<root> y lo aplica con apply:<root>: primero no producción, después el sandbox, después producción con la imagen promovida. Luego grafana:reconcile y edge:reconcile le piden a la compuerta de aprobación que ejecute los pipelines de operations y de landing-zone, que colocan los paneles del producto y su nombre de host en el borde compartido.
El producto responde en giftcards.store.shop.projectairframe.dev, detrás del inicio de sesión único para su grupo de usuarios. En el ensayo, eso pasó unos ochenta y cinco minutos después de que se integró la entrada del catálogo; crear las bases de datos se llevó la mayor parte.
6. El primer cambio
Sección titulada «6. El primer cambio»Dónde: el repositorio propio del producto, projectairframe/shop/store/ordering/giftcards.
- Clona el repositorio, crea una rama, cambia algo en
apps/o una raíz eninfra/, y ejecutaairframe validate. - Abre un merge request. Su pipeline se ejecuta en el runner sin confianza, sin ninguna credencial de la nube.
- Quién aprueba: una persona que el modelo de responsables nombra para lo que cambió, que no sea el autor: el equipo para
infra/; el equipo o el equipo de la plataforma para el archivo del pipeline y.airframe/. - Lee los planes y el costo que publica el ejecutor, y prueba la vista previa en el nombre de host propio del merge request.
- Haz el merge. El pipeline de main aplica.
El camino de un cambio sigue estos pasos en detalle.
Hasta que se integren dos merge requests más, la aprobación de la compuerta todavía no es obligatoria en el repositorio nuevo: solo la de una persona con nombre que no escribió el cambio. Dónde: gate/infra/terraform.tfvars de control-plane, que agrega el repositorio a ownership_enforced, y después .gitlab/security-policies/policy.yml de security-policies, que lo agrega al alcance de la política required ownership gate. Quién aprueba: el equipo de la plataforma en control-plane; un mantenedor que no lo escribió en security-policies. Hoy la segunda persona en cada caso es la segunda cuenta del mantenedor: el mecanismo se aplica, pero la separación entre dos personas todavía no es real.
Dónde está
En el repositorio landing-zone:
- docs/guides/greenfield.md: un producto nuevo, de la entrada al nombre de host
- docs/guides/product-lifecycle.md: cada reconciliador, y lo que espera a la facturación
En el repositorio catalog:
- README.md: quién aprueba qué en el catálogo
- ownership/protected-paths.yaml: el modelo de responsables
En el repositorio control-plane:
