09 · Application Modernization
Milestones of the roadmap items in this theme
As of 2026-10-22 · today
Gantt
Milestones
| # | Milestone | Start | Target | Status | Waits for | Team | Epic | Derived |
|---|---|---|---|---|---|---|---|---|
| 25 · Application Containerization | ||||||||
| 25.1 | The paved road exists: base images, chart and CI templates | — | 2027-05-21 | planned | 32.2 | SRE · Platform Engineering | — | waiting 32.2 |
| 25.2 | Applications reach the container-ready conditions | — | 2028-02-25 | planned | 25.1 | Application development | — | waiting 25.1 |
| 25.3 | One image per service, built in CI and published | — | 2028-05-19 | planned | 25.2 | SRE · Platform Engineering | — | waiting 25.2 |
| 25.4 | Not-yet-Kubernetes apps run as containers on their current VM | 2026-10-01 | 2027-09-17 | planned | — | SRE · Platform Engineering | — | — |
| 25.5 | Every application removes its sticky-session dependency | 2026-10-01 | 2028-02-25 | planned | — | Application development | — | — |
| 26 · Application Migration to Kubernetes | ||||||||
| 26.1 | Migration waves planned from the 25.2 classification | 2027-03-01 | 2028-02-25 | planned | 25.2, 25.5 | SRE · Platform Engineering | — | waiting 25.2, 25.5 |
| 26.2 | Stage 2 through GitOps, cut over by canary, VM retired | 2027-06-19 | 2028-12-10 | planned | 26.1, 15.6 | SRE · Platform Engineering | — | waiting 26.1, 15.6 |
| 26.3 | Remaining waves complete, and what did not move is named | 2027-11-12 | 2030-02-23 | planned | 26.2 | SRE · Platform Engineering | — | waiting 26.2 |
| 26.4 | goods API Phase 1–10 moved off the middle, proven on 11/11 | 2026-08-13 | 2026-11-11 | in progress | — | Platform Engineering · Application development | — | — |
| 26.5 | Cart middle moved to Kubernetes | 2026-11-12 | 2028-02-25 | planned | — | Platform Engineering · Application development | — | — |
| 26.6 | Tracklist and purchased-list moved off the SRE-run cluster | 2026-11-12 | 2027-02-26 | planned | — | Platform Engineering | — | — |
| 26.7 | goods API Phase 11–12 cut over by canary | 2026-11-12 | 2027-03-21 | planned | 26.4, 15.5 | Platform Engineering · Application development | — | waiting 26.4, 15.5 |
| 26.8 | Middle scale-down P1, after 11/11 | 2026-11-12 | 2027-03-21 | planned | 26.4 | Platform Engineering | — | waiting 26.4 |
| 26.9 | Middle scale-down P2, after 6/18 | 2027-06-19 | 2028-05-18 | planned | 26.5, 26.7, 26.8 | Platform Engineering | — | waiting 26.5, 26.7, 26.8 |
| 30 · API-First Data Access | ||||||||
| 30.1 | Cross-application direct access inventoried, each dataset owned | — | 2027-02-26 | planned | — | SRE | — | — |
| 30.2 | The contract is written before the code, and CI blocks a breaking change | — | 2027-09-10 | planned | 30.1, 22.1 | SRE · Platform Engineering | — | waiting 30.1, 22.1 |
| 30.3 | The paved road: template, caller identity, shared conventions | — | 2028-03-10 | planned | 30.2 | SRE · Platform Engineering | — | waiting 30.2 |
| 30.4 | The lowest-blast-radius dataset moves across, and its direct grants are revoked | — | 2028-09-08 | planned | 30.3 | Application development · SRE | — | waiting 30.3 |
| 30.5 | A new direct grant cannot be issued | — | 2029-01-12 | planned | 12.2, 30.1 | SRE | — | waiting 12.2, 30.1 |
Details
25.1The paved road exists: base images, chart and CI templates2027-05-21planned · 0/4
- Base images maintained and patched by the platform, not copied per teamowner · TBDA copied base image is a fork nobody remembers to patch, and the next CVE has to be fixed in as many places as there are teams.
- A chart template that covers the common caseowner · TBD
- CI job templates that build one image per serviceowner · TBD
- One team has walked the road end to end without helpowner · TBDA paved road that needs the platform team sitting next to you is not paved. This task is the only honest test of whether the other three landed.
25.2Applications reach the container-ready conditions2028-02-25planned · 0/5
- Configuration from the environment, not baked into the imageowner · TBD
- Logs to stdoutowner · TBDLogs written to local storage disappear with the container, and are one of the reasons an application cannot be replaced freely — which is exactly what a scheduler needs to do.
- Health and readiness probes that mean what they sayowner · TBDA readiness probe that returns OK before the application can serve turns a rolling update into an outage.
- Local state identified for every one of the 79 services in the inventory, and named where it cannot go yetowner · TBDThis is what sorts the estate three ways: free of local state and bound for Kubernetes, still holding it and bound for 25.4, or not containerisable at all and staying on item 09's path — the last only when the workload is named, has a stated reason and SRE has approved it. The classification is a product of this milestone, not an input to it, and 26.1 plans its waves from it.
- Office Hour sessions on container readiness and configuration in codeowner · TBD
25.3One image per service, built in CI and published2028-05-19planned · 0/3
- Built in CI from the platform base image, never on a laptopowner · TBD
- 20.3 emits the audit event that says who built which revision into which artefact; this is the artefact it points at.
- Signing and the SBOM come from 15.4, applied to these imagesowner · TBDCard 25 asks for a signed SBOM, and 15.4 delivers that mechanism on 2027-09-24 — after this milestone. Requiring it here would push containerisation behind the pipeline rewrite and invert the order this item exists to respect, so the target is stated and no dependency is drawn.
25.4Not-yet-Kubernetes apps run as containers on their current VM2027-09-17planned · 0/4
- The application runs as a container on the VM it runs on todayowner · TBDThe same image that will later run in Kubernetes. Nothing is repackaged when it moves — what changes is where it is scheduled.
- An application starts here as soon as it is containerised, without waiting for the full 25.2 classificationowner · TBD
- Recorded as a stop, not a destinationowner · TBDEach application leaves for item 26 when its local state is gone. Unsaid, "containerised on a VM" quietly becomes the permanent answer for everything that was hard — which is how a migration ends with a second platform nobody chose.
- Released through the traffic-layer split, not a cluster toolowner · TBDFor release purposes these are VM workloads whatever they are packaged as, so 15.2 carries them.
25.5Every application removes its sticky-session dependency2028-02-25planned · 0/4
- Each application states whether it pins users to one instanceowner · TBD
- Session moved to a shared store or to tokens; affinity removed at the load balancer and gatewayowner · TBDAn application that pins users cannot scale out, cannot be rolled or evicted without logging users out, and cannot be cut over by weight.
- Verified: one instance killed, no user logged out, nothing interruptedowner · TBD
- Office Hour sessions on why and howowner · TBD
26.1Migration waves planned from the 25.2 classification2028-02-25planned · 0/7
- Only applications whose local state is gone are in a waveowner · TBD
- No application with a sticky-session dependency is in a waveowner · TBDThe prerequisite is 25.5; a wave that carries one would be cut over by weight and log its users out.
- The ones still holding state stay at 25.4 and are namedowner · TBD
- Wave order by blast radius, lowest firstowner · TBDThe same rule 2.1 set for the IaC rebuild — prove the pattern on something recoverable before the services everything depends on.
- Entry and exit criteria stated per wave, aligned to the 6/18 and 11/11 cut pointsowner · TBD
- Waves cover every service in the inventory — 79 services on 1796 hosts; wave order by business domain set hereowner · TBDThe baseline is the Legacy Estate inventory (Architecture, snapshot 2026-09-21). A service in no wave is either an SRE-approved exception or a gap in the plan.
- Per service, its owner confirms whether it can run on-prem and in the cloud side by side; the answer decides which cluster its wave targetsowner · TBD
26.2Stage 2 through GitOps, cut over by canary, VM retired2028-12-10planned · 0/5
- Deployed through GitOps, not by a personowner · TBD
- Old and new side by side before any traffic movesowner · TBD
- Traffic cut over by canary (15.6)owner · TBD
- The application team verifies its own cutoverowner · TBDThe code changes were theirs under 25.2; the platform moving it does not make the platform the judge of whether it works.
- The VM retired, not left running — its capacity goes to item 03owner · TBD
26.3Remaining waves complete, and what did not move is named2030-02-23planned · 0/3
- Stage 3 — applications that held local state — completed on the same criteriaowner · TBD
- What did not move, and which of the three categories it is inowner · TBDStill holding local state and parked at 25.4, or not containerisable at all and on item 09's path. A migration that reports only what moved hides the part that will still be there next year.
- The residue published as hosts and services remaining against the 1796 / 79 baseline, not left impliedowner · TBDEvery remaining workload is either an SRE-approved exception — named, with a stated reason — or still parked at 25.4. Anything else is unfinished migration, not residue.
26.4goods API Phase 1–10 moved off the middle, proven on 11/112026-11-11in progress · 1/3
- Phase 4, 5 and 10 cut overowner · TBD
- Phase 7, 8 and 9 cut over before the 9/30 freezeowner · TBD
- Carried the 11/11 peak on Kubernetesowner · TBD
26.5Cart middle moved to Kubernetes2028-02-25planned · 0/3
- Target date confirmed with the cart teamowner · TBD
- No sticky-session dependency (25.5) before any traffic movesowner · TBD
- Cut over by canary and the middle path retiredowner · TBD
26.6Tracklist and purchased-list moved off the SRE-run cluster2027-02-26planned · 0/2
- UAT moved to the platform clusterowner · TBD
- Production moved and the old service replacedowner · TBD
26.7goods API Phase 11–12 cut over by canary2027-03-21planned · 0/2
- Phase 11 and 12 cut over by canary (15.5)owner · TBD
- All 121 goods APIs served from Kubernetesowner · TBD
26.8Middle scale-down P1, after 11/112027-03-21planned · 0/2
- Middle VMs sized down to the traffic still on themowner · TBD
- Freed machines added to the platform clustersowner · TBD
26.9Middle scale-down P2, after 6/182028-05-18planned · 0/2
- Middle sized down again once stage 1 has movedowner · TBD
- Remaining middle APIs named, with the stage each moves inowner · TBD
30.1Cross-application direct access inventoried, each dataset owned2027-02-26planned · 0/4
- Inventory derived from the database side, not from asking teamsowner · TBDAudit output, pg_stat and proxy logs say what the estate does; a survey says what teams remember it does. Only one of the two is the thing being migrated.
- Every cross-application read and write named, with its callerowner · TBD
- The ownership map is this milestone's product, not its input — the same relation 25.2 has to the three-way classification.
- Datasets with no plausible owner escalated, not assigned by defaultowner · TBDA dataset handed to whoever happens to touch it most has an owner on paper and none in practice, and the contract it publishes will be nobody's to keep.
30.2The contract is written before the code, and CI blocks a breaking change2027-09-10planned · 0/5
- The contract is shaped by what callers need, not by what the tables look likeowner · TBDarchitecture →A CRUD API mirroring the tables one-to-one keeps every bit of the coupling and adds a network hop — worse than direct access, because a schema change now has to move the API and its callers in step instead of just the callers. Decoupling comes from the shape of the contract, not from the fact that HTTP is involved.
- The spec lives in git and the code is generated from it, never the reverseowner · TBD
- A contract nothing enforces is documentation, and documentation does not stop a caller from breaking.
- Specs published in the Backstage catalogowner · TBDA caller finds the contract without asking anyone. 22.1 wired the catalog and identity; this is one of the things it exists to carry.
- The synchronous and asynchronous line drawn per datasetowner · TBDReads that tolerate staleness belong to item 28's event bus and analytical reads to item 27's Trino. Undrawn, API-first turns batch queries into HTTP and takes the database down with it.
30.3The paved road: template, caller identity, shared conventions2028-03-10planned · 0/4
- A service template that covers the common caseowner · TBDThirty teams each inventing an API produces thirty dialects — the shared schema replaced by a shared absence of one.
- The caller's own identity carried to the owning service and into the audit trailowner · TBDThis is what a database credential cannot deliver: authorization decided per caller rather than per connection, and an audit trail that names who asked.
- Pagination, error shape and versioning settled once, in the templateowner · TBD
- One team has taken a dataset through the road end to end without helpowner · TBDThe same honest test 25.1 uses — a road that needs the platform team sitting next to you is not paved.
30.4The lowest-blast-radius dataset moves across, and its direct grants are revoked2028-09-08planned · 0/4
- One dataset chosen by blast radius, lowest firstowner · TBDThe rule 2.1 and 26.1 already follow — prove the pattern on something recoverable before the data everything depends on.
- The owning service serves it; readers move across one at a time, old and new side by sideowner · TBD
- This, not the shipped API, is what completes the milestone. An API running beside a still-open direct path has added a component and removed no coupling.
- The remaining waves recorded as crossing into the next half-yearowner · TBDStated on the page rather than inferred from a missing bar. Unsaid, "we have an API now" becomes the answer for an estate still wired straight to the database.
30.5A new direct grant cannot be issued2029-01-12planned · 0/4
- Credentials issued only through the dynamic secrets engine, and only to the dataset's owning serviceowner · TBD12.2 makes database credentials dynamic; this is the policy that decides who may receive one.
- No standing credential path outside it — the old grants are gone, not merely unusedowner · TBD
- A request for cross-application direct access has one answerowner · TBDThe owning service's contract. An exception process here is the mechanism by which the estate returns to where it started.
- Drift checked against the 30.1 ownership mapowner · TBDWithout one issuing path and a periodic check, direct access grows back and the inventory has to be run again.
Back to the Platform Roadmap overview · the direction behind these milestones is the Platform Roadmap.