Bringing an existing system
Most organizations already run systems when they adopt a platform, and those systems rarely look like a fresh product from Airframe’s template. This page says plainly what Airframe can take in today, what a product gives up when it skips the template, and which parts of the adoption path are designed but not built, so you can plan without surprises.
The short version: the catalog can register an existing system, and the platform then builds its cloud side, but nothing built today moves its code, its data or its deployment onto the platform. The working path today is a new product from the template, with the existing application brought into it.
What the catalog accepts today
Section titled “What the catalog accepts today”A product entry can say template: none, meaning “do not render a repository for me”, together with one of two fields:
source_repo, the address of the one repository the system lives in today;repos, a list of the system’s repositories, each with a role:infra,service,worker,frontendormigration.
The catalog’s lint refuses template: none without one of them (enforced). An entry may also carry conformance_level, from 1 to 3, how far along the platform’s adoption ladder the product is. The schema accepts it, and nothing reads it yet.
What happens to such an entry
Section titled “What happens to such an entry”The reconcilers treat it like any other product. The project factory creates its two projects and its identities, and bills them once the product is listed in the factory’s billed_products. The domain’s GitLab root creates a repository at the product’s path in its context group, with its protected main.
That repository stays empty. The platform’s render job, the only account allowed to push a product repository’s first commit, renders entries that say template: fullstack and skips the rest. Nothing reads source_repo or repos yet. So today template: none gives a system a place in the catalog and its cloud projects, and leaves its code where it is.
What the template would have given
Section titled “What the template would have given”A product rendered from the golden path’s template starts with:
- a working application for its stack, with JSON logs, traces and a health endpoint already wired to the platform’s telemetry;
- its Terraform roots,
infra/np,infra/sandbox,infra/prod,infra/ephfor previews andinfra/grafana, composed from the platform’s modules; - a pipeline made only of the platform’s components;
.airframe/with the list of images the trusted builder builds and the seeds for the sandbox and previews;- a file that names the product’s secrets and never holds a value, a runbook, a
CODEOWNERSfile that names the context’s group as owner of the paths the ownership model protects, and instructions for a coding agent.
A product without the template has to bring each of these itself, and the platform’s build and test jobs know only the three template stacks. A product on another stack runs none of them, and its merge requests fail the test coverage check until its entry sets quality.minimum_coverage to zero, a change a team lead or a domain lead approves.
The path that works today
Section titled “The path that works today”- Register the system as a new product with
template: fullstackand the closeststack, following the first product. - Replace the rendered application in
apps/with the existing code, through ordinary merge requests in the new repository. The team may change the Dockerfile or add more, as long as each one starts from one of the platform’s base images and is listed in.airframe/images.yaml, as any stack explains. - Recreate the system’s cloud resources through the product’s roots. Existing data has to be moved by the team: the import of existing databases and Terraform state into the product’s roots is part of the adoption design below, and is designed.
Designed, not built
Section titled “Designed, not built”Landing-zone’s ADR-0016 and ADR-0017 describe how the platform will take in the most common shape of an existing system. Both decisions are still proposals, and the catalog’s schema has only their first fields.
- Products spread over several repositories (designed). A product keeps one repository per application, plus a repository that changes its database schema and a new
infrarepository rendered by the template for what the product decides. Each repository has its own Terraform state, images and preview hostname,<product>-<repo>-eph-<iid>, and the migration repository’s identity owns the database schema. - Adoption by moving the group (designed). A product joins the platform when its GitLab group is transferred under
projectairframe/<journey>/<domain>/<context>/<product>/, one recorded transfer per product under the exceptional procedure. The entry would carrysource_group, the group’s old path, until the move. - Hostname aliases (designed). An adopted product’s existing hostnames, listed in the entry’s
hostnames, would be served by the shared edge as aliases of its canonical hostname. The catalog’s schema does not accept the field yet, so the lint refuses an entry that uses it. - Dependencies kept outside (designed). A data store the product keeps running elsewhere, such as a MongoDB, would be a
dependenciesentry: the network opens the way to it, and the policy pack warns. - GKE as a second place to run (designed). A product could say
runtime: gkeand run in its own namespaces on one shared Autopilot cluster per edition, deployed by Argo CD from what the product’s root applies, with no cluster credential in any pipeline. No cluster root exists yet. - The adoption ladder and
airframe adopt(designed). Level 1 registers a product, level 2 hosts its repositories and infrastructure on the platform, and level 3 adopts the template’s layout;conformance_levelrecords the level, and nothing acts on it yet. A command,airframe adopt, would draft the entry and the merge requests; it is planned last, after the manual path has been rehearsed.
Until these are built, an existing system on Airframe is a new product that the team moves its application into.
Where it lives
In the landing-zone repository:
- docs/guides/brownfield.md: the adoption design and what is built
- docs/adr/0016: GKE as a second workload kind, proposed
- docs/adr/0017: products over several repositories, proposed
- docs/contracts.md: the product fields and the hostnames
In the catalog repository:
In the golden-path repository:
In the control-plane repository:
