Airframe

Por qué Airframe

Un catálogo para toda la organización

Quién trabaja aquí, en qué equipo está, qué productos existen y quién es responsable de cada uno: Airframe guarda todo eso como archivos en un solo repositorio git, el catálogo. Toda automatización que necesita esos datos lee los archivos, así que un cambio se hace una vez, se revisa una vez y todos los lectores lo siguen.

Cómo un repositorio describe la organización

  1. La organización como archivos

    El catálogo es un repositorio git de archivos YAML pequeños. Los recorridos, dominios, contextos y productos forman su jerarquía, cada uno un archivo nombrado por su ruta, como contexts/shop.store.ordering.yaml, y el archivo de un producto nombra al equipo responsable de él. El archivo de un equipo nombra su contexto, su líder y sus miembros con sus roles. El archivo de una persona tiene un nombre, una dirección de correo, un estado (active, pending o departed), sus nombres de usuario de GitLab y de Grafana cuando ya tiene cuentas, y un perfil: acerca de, experiencia, enlaces y horario. Las reglas de responsables, en el mismo repositorio, dicen quién aprueba qué. En cada merge request, el lint del catálogo revisa cada archivo contra su JSON Schema, y las referencias entre archivos.

  2. Se cambia por merge request

    Nadie cambia la organización en la configuración de una herramienta: un cambio es un merge request al catálogo, y las propias reglas de responsables del catálogo deciden quién debe aprobarlo. El archivo de un equipo necesita a uno de sus líderes de equipo o de los líderes de su contexto; el propio perfil de una persona, a esa persona, que aprueba el cambio o lo abre solo con commits suyos; el resto del archivo de una persona, a un líder de uno de sus equipos; y la estructura, desde los recorridos hasta las propias reglas, a dos miembros del equipo de la plataforma. La compuerta de aprobación traduce cada regla a personas a partir de la rama main protegida del catálogo, nunca del cambio que evalúa, y el merge espera su aprobación. Así, cada cambio tiene un revisor, un historial en git y una forma de deshacerlo: otro merge request.

  3. Una fuente, muchos lectores

    Hoy lo leen: la compuerta de aprobación, para cada aprobación que da; la raíz de grupos de landing-zone, para un grupo de Google por equipo, por líderes de cada nivel y por usuarios de cada producto, el público que el nombre de host del producto admite detrás del inicio de sesión único; las raíces de GitLab de control-plane, para las membresías de grupo de cada persona y la lista de quién puede hacer merge en la rama main de cada producto; la raíz de Grafana de operations, para los miembros de la organización y un equipo por cada equipo del catálogo, con sus carpetas, su punto de contacto y su ruta de alertas; la raíz de carpetas, para una carpeta por recorrido, dominio y contexto; y el catálogo de arquitectura, para una página por equipo y por persona, con el acerca de, la experiencia y el horario de la persona. Las fábricas de proyectos le dan al grupo de un equipo acceso de lectura a los proyectos de sus productos y a sus registros; el resto de lo que deriva la entrada de un producto es la historia de autoservicio por merge request.

  4. Nada que mantener sincronizado

    Cuando cambia una persona o un equipo, los lectores lo siguen en su próxima ejecución, y un merge al catálogo la inicia. La compuerta de aprobación lee la rama main del catálogo en cada evaluación. El pipeline del catálogo en main dispara la cadena de reconciliadores: el pipeline de landing-zone, luego el de operations, luego el de control-plane y otra vez el de landing-zone, cada uno ejecutando solo las raíces que leen el catálogo. El mismo pipeline publica las páginas del catálogo en el catálogo de arquitectura. Para lo que derivan los lectores, no hay un segundo inventario ni un job de sincronización. Dos cosas siguen fuera del catálogo: la política de aprobación de todo el grupo nombra a sus aprobadores en security-policies, donde solo un merge request los cambia, y una verificación después de cada merge al catálogo advierte cuando esa lista y el catálogo no coinciden, mientras una ejecución diaria falla y mantiene un issue abierto hasta que coincidan; y los grupos de la plataforma y de emergencia se administran a mano.

  5. La próxima automatización es un lector más

    Una automatización que necesita saber quién es responsable de un producto, quién lidera un dominio o quién está en un equipo lee los mismos archivos en la rama main del catálogo, y hereda lo que ya traen: cada dato fue aprobado por sus responsables, tiene un historial y se puede deshacer. No necesita una lista, un formulario ni un job de sincronización propios. Una nueva raíz de Terraform en landing-zone, operations o control-plane que lee el catálogo lo declara en su pipeline, con la entrada reads_catalog del componente tf-apply, y la cadena la ejecuta después de cada merge al catálogo.

Lo que lo hace verdad

Cada archivo del catálogo se revisa antes del merge.
El componente validate de control-plane ejecuta el lint del catálogo en cada merge request y en main: cada archivo contra su JSON Schema, el padre de cada nivel presente, cada líder y cada miembro de un equipo una persona que no se ha ido, y el líder de cada equipo uno de sus miembros con el rol de líder de equipo. Cada hallazgo nombra su archivo.
Solo los responsables actuales pueden aprobar un cambio al catálogo.
La compuerta de aprobación lee las reglas de responsables, los equipos y las personas de la rama main protegida del catálogo, nunca del cambio que evalúa, y cuenta solo a personas activas con una cuenta de GitLab, nunca al autor ni a los autores de sus commits. Una política de aprobación en security-policies hace de la aprobación de la compuerta una condición para el merge en el catálogo, como en cada otro repositorio que la compuerta protege.
Un merge al catálogo llega a los lectores sin que nadie ejecute un comando.
El pipeline del catálogo en su rama main protegida dispara por turno los pipelines de landing-zone, operations y control-plane, y luego otra vez el de landing-zone, cada uno esperando al anterior. En ellos, el componente tf-apply ejecuta solo las raíces que declaran reads_catalog, contra la rama main del catálogo, cada una con su propia identidad de pipeline.
Cada lector deriva las membresías y las aprobaciones solo de personas activas.
La raíz de grupos sincroniza membresías solo para personas activas; las raíces de GitLab dan membresías y derechos de merge solo a personas activas con un nombre de usuario de GitLab, y les dan acceso a los repositorios de la plataforma y a security-policies a través de un solo grupo, projectairframe/contributors, así que una salida saca a la persona de todos ellos en la siguiente ejecución de la cadena; la raíz de Grafana agrega solo a personas activas con un nombre de usuario de Grafana; la compuerta de aprobación cuenta solo a personas activas. El lint rechaza a una persona que se fue en cualquier equipo o lista de líderes, así que el merge request que marca a alguien como departed también lo saca de cada equipo y cada lista de líderes.
La lista de personas de la política de aprobación no puede alejarse del catálogo sin que se note.
La política de aprobación de todo el grupo nombra a sus aprobadores uno por uno. Su verificación, policy:approvers, compara esa lista con las personas activas del catálogo con una cuenta de GitLab y nombra a cada persona que hay que agregar o quitar. En security-policies se ejecuta en cada merge request y en main, y falla ante cualquier diferencia. En control-plane se ejecuta en la pasada que la cadena del catálogo dispara después de cada merge, donde una persona que hay que agregar o quitar solo genera una advertencia, así que la cadena sigue, y en una ejecución diaria programada, donde falla y policy:approvers:report mantiene un issue abierto con el cambio exacto que hay que hacer hasta que las listas coincidan. Un rol, un grupo o un id entre los aprobadores, o cualquier aprobador que no sea la cuenta de la compuerta en la regla de la propia compuerta, hace fallar todas las ejecuciones. Mientras la lista no se pone al día, una persona que todavía no figura en ella no puede aprobar, y una persona que se fue y sigue en ella no llega a ningún repositorio de la plataforma. Una verificación fallida no cambia nada por sí sola: la lista cambia con un merge request en security-policies.