WAVE PLANNING · ARCHITECTURE DECISION

Planning migration waves for enterprise applications on STACKIT

A wave is a group of units that moves together. StackToIT computes the part that comes from dependencies: a unit moves after everything it depends on, and the steps of the plan are laid out in ten phases from decisions to decommission. It does not decide which application goes first. That choice rests on shared components, RTO and RPO, data volume and the capacity of your team, and the run keeps the application file's values exactly as you wrote them.

Four ways to cut the waves

Each option answers the same question differently: what moves together, and what has to be true before it does.

OptionWhat it gives youWhat it costs
By layer: network, then data, then workloadsThe order StackToIT computes. Every dependency is respected and each layer is tested once for the whole estate.Applications reach their cutover late and together. Source and target run side by side for the whole programme.
By application: a pilot first, then the restA team learns the full path on one application. The Microsoft Cloud Adoption Framework advises starting with simpler workloads and adding one or two complex ones to early waves.The shared network, security groups and identity must exist first, and anything an application shares with one that stays behind needs a link between both sides until the last wave.
By risk: least critical first, critical lastCritical systems move after the process has proven itself. Non-production environments go before production.Your most critical application needs a near-zero downtime method, with replication and a tested rollback, and it is scheduled last, so it waits longest on the source.
One window for the whole estateOne freeze, one cutover, one GO or ROLLBACK decision. No period in which two environments depend on each other.Everything is judged at once, the window must hold all data moves, and a failure puts the whole estate back.

The first row is what the run computes. The other three are choices you make on top of it; the run offers no ranking between them.

What the run does with an application file

A 13-resource AWS estate with two applications, assessed on 4 November 2026. Left: the billing application as the applications file states it. Right: waves.csv of the run, whole.

Example inputapplications.yaml
  - id: billing
    name: Billing
    selectors:
      - aws_instance.billing_app
      - aws_db_instance.billing_db
      - aws_sqs_queue.billing_events
      - aws_s3_bucket.billing_archive
    environment: production
    owners:
      business: finance
      technical: billing-platform
    business_criticality: critical
    availability:
      rto: 30m
      rpo: 5m
      downtime_tolerance: 15m
    data:
      classification: confidential
    sovereignty:
      tier: mandatory
Output of StackToITmigration/waves.csv
wave,wave_state,unit,type,module_call,presence,class,confidence,application,application_status,proposed_group
1,MEMBER,aws_s3_bucket.billing_archive,aws_s3_bucket,,KNOWN_PRESENT,DIRECT,MEDIUM,billing,CONFIRMED,
1,MEMBER,aws_s3_bucket.shop_assets,aws_s3_bucket,,KNOWN_PRESENT,DIRECT,MEDIUM,shop,CONFIRMED,
1,MEMBER,aws_sqs_queue.billing_events,aws_sqs_queue,,KNOWN_PRESENT,REPLATFORM,MEDIUM,billing,CONFIRMED,
1,MEMBER,aws_vpc.core,aws_vpc,,KNOWN_PRESENT,RECONFIGURE,MEDIUM,UNASSIGNED,UNASSIGNED,
2,MEMBER,aws_security_group.web,aws_security_group,,KNOWN_PRESENT,RECONFIGURE,MEDIUM,UNASSIGNED,SHARED,billing_app; shop_web
2,MEMBER,aws_subnet.db_a,aws_subnet,,KNOWN_PRESENT,RECONFIGURE,MEDIUM,UNASSIGNED,UNASSIGNED,
2,MEMBER,aws_subnet.db_b,aws_subnet,,KNOWN_PRESENT,RECONFIGURE,MEDIUM,UNASSIGNED,UNASSIGNED,
2,MEMBER,aws_subnet.web,aws_subnet,,KNOWN_PRESENT,RECONFIGURE,MEDIUM,UNASSIGNED,UNASSIGNED,
3,MEMBER,aws_db_instance.billing_db,aws_db_instance,,KNOWN_PRESENT,REPLATFORM,MEDIUM,billing,CONFIRMED,
3,MEMBER,aws_db_instance.shop_db,aws_db_instance,,KNOWN_PRESENT,REPLATFORM,MEDIUM,shop,CONFIRMED,
3,MEMBER,aws_instance.billing_app,aws_instance,,KNOWN_PRESENT,RECONFIGURE,MEDIUM,billing,CONFIRMED,
3,MEMBER,aws_instance.shop_web,aws_instance,,KNOWN_PRESENT,RECONFIGURE,MEDIUM,shop,CONFIRMED,
  • Applications are confirmed

    The seven units named in the file show application CONFIRMED with the application's name beside them. The servers and databases of both applications share the third unit wave.

  • Shared units stay unassigned

    The security group both applications use is marked SHARED and belongs to neither. Wave planning has to treat it as a prerequisite of both.

  • The file did not change the order

    A second run of the same estate without the applications file produced the same waves and the same 138 steps. The file adds owners, criticality, RTO and RPO as written, not a different sequence.

The units in dependency order

Unit waveUnitsWhy they sit there
1billing_archive and shop_assets (DIRECT), billing_events (REPLATFORM), the VPC (RECONFIGURE)They depend on no other unit. The buckets can start their first copy early, long before their applications cut over.
2The security group and three subnets (RECONFIGURE)They wait for the VPC. Servers and databases wait for them in turn.
3billing_db and shop_db (REPLATFORM), billing_app and shop_web (RECONFIGURE)They depend on the networks. This is the wave in which the applications become movable.

This is technical-sequencing.md of the run. It orders 12 units in three unit waves; the migration plan lays the 138 steps of the plan out in ten waves. The two numberings are not the same thing, so say which one you mean when you talk about wave 3.

The ten waves of the plan

Plan waveWhat the migration plan puts thereIn this run
0 DecisionsQuestions nobody has answered yet5 decisions with 8 questions that steps wait for
1 Landing zoneThe project and the preconditions a person provides before the first applyNo step; the project is yours to provide
2 Network and securityNetworks, routing and security groups5 work packages
3 Data servicesDatabases, object storage and volumes2 work packages
4 PlatformKubernetes, load balancers, logging and other shared services1 work package
5 WorkloadsServers and what attaches to them2 work packages
6 Data migrationCopying data from the source to the new services3 work packages of 20, 24 and 12 steps
7 CutoverMoving traffic and the steps that must come before production5 work packages
8 VerificationChecking the migrated estate5 work packages
9 DecommissionRetiring the source4 work packages

The plan holds 138 steps: 24 automated and 114 manual, in 27 work packages. Of the 138, 111 tie to one of the two applications; the rest belong to the estate.

The gates that span the whole estate

Wave planning by application still meets these. They come from the run's execution-plan.json, and they are where your own split has to happen.

  • One readiness gate before any cutover

    The readiness step waits for 23 steps: every workload step and every data move. The plan does not know which entry point serves which store, so every switch waits for all of them.

  • One GO or ROLLBACK decision

    The rollback decision waits for 32 steps. GO lets the source resources be retired; ROLLBACK reverts the cutover and keeps the source serving. Retirement steps wait behind it.

  • A switch is small once the gate is split

    The traffic switch of a server has 4 direct predecessors: its server, its network interface, its boot image decision and the estate-wide readiness gate. Remove that gate from the path per application and the switch itself is a small step; the gate is where you cut.

  • Data moves are not cutovers

    For a bucket the plan has a first copy while the writers keep writing, repeated copies until a pass fits the freeze window, then a reconcile. Start that early and the wave's cutover shrinks to a switch.

  • Decisions are a wave of their own

    Wave 0 is the one you control completely. Each answer, whether a boot image, a data move method, the opt-in to a messaging API that may still change or the default egress rule, unblocks steps in later waves.

How to decide, in order

  1. List what is shared

    Read the SHARED rows and the unassigned units. Shared networks, groups and queues decide which application can go first at all, and AWS Prescriptive Guidance names dependencies as a reason to hold an application back until others have moved.

  2. Write the application file

    Give each application its owners, criticality, RTO and RPO. The run keeps them as written and puts them beside every unit; it calculates nothing from them.

  3. Choose the pilot

    Pick an application of moderate criticality with a representative database, not the simplest bucket. A pilot that exercises a database move proves the path the critical application will take.

  4. Split the gates

    Turn the estate-wide readiness and rollback gates into one per wave of yours, and keep the run's step order inside each. Do this in your own schedule: the run keeps one gate of each kind, also after a rerun with your answers.

  5. Fix the freeze windows with the business

    The Microsoft Cloud Adoption Framework advises against scheduling migrations in critical business periods and asks for a tested rollback plan before the first move.

Questions architects ask

Does StackToIT produce a schedule?

No. The migration plan says a wave is a starting point for the schedule, not a schedule. The run orders units by dependency and lays out the steps with their owners and conditions; dates, windows and capacity come from you.

Can the application file reorder the waves?

In this build it did not: the same estate gave identical unit waves and the same 138 steps with and without the file. Use the file to record who owns what and which RTO and RPO apply, and cut the application waves yourself.

Which application should move first?

There is no ranking in the run. The Microsoft Cloud Adoption Framework suggests low-risk, standalone workloads first and one or two representative complex workloads in early waves. In the estate above that would point to the less critical application with a database, with the critical one after.

Why do buckets sit in the first unit wave while their application is in the third?

A bucket depends on no network unit, so it can be copied early. The cutover of its consumers still waits for the application's own wave, so an early copy shortens the later window instead of changing the order.

Sources

Your next move: STACKIT.

Tell us about your estate. We show you what StackToIT delivers for it: target architecture, Terraform artifacts and a structured migration plan.