Skip to main content
Server & DevOpsAugust 25, 20266 min read

How to Migrate a Server to AWS Without a Big Bang Cutover

A big bang cutover is a plan with exactly one attempt in it. The incremental version costs a little more elapsed time and keeps a working rollback available until the very last step. This walks through the inventory that decides whether the cutover is clean, continuous replication that runs while the old server keeps serving, a dress rehearsal you can repeat, the DNS time to live arithmetic you have to do backwards from the cutover date, and the single action that ends the rollback window for good.

A big bang cutover is a plan with exactly one attempt in it. You stop the old server, move everything, start the new one, and if something nobody thought of breaks at 2am you are debugging with no traffic served and no way back except a restore. The incremental version costs a little more elapsed time and gives you a rollback that stays available until the very last step.

Inventory the box, not the plan

Before any tooling, write down what the server actually does, because a good half of what makes a cutover fail is not the application.

  • Every listening port and what talks to it.
  • Every outbound destination, including the ones that only fire monthly.
  • Every cron job, systemd timer and at job.
  • Every certificate on the box and when it expires.
  • Every DNS record anywhere that points at this server, including records in zones you do not control.
  • Every hard-coded IP address anyone has ever put in a firewall on the other side.

The last two are what turn a clean cutover into a week of follow-up. A partner allowlist holding your old address does not fail at cutover, it fails quietly on their next batch run.

# listening sockets with the owning process
ss -tulpn

# scheduled work, per user
systemctl list-timers --all
for u in $(cut -d: -f1 /etc/passwd); do crontab -l -u "$u" 2>/dev/null; done

# certificates and their expiry dates
find /etc -name '*.pem' -o -name '*.crt' 2>/dev/null | \
  xargs -r -I{} sh -c 'echo "{}"; openssl x509 -enddate -noout -in "{}" 2>/dev/null'

Replication runs while the server keeps working

For lifting a whole server, the AWS tool is Application Migration Service, now presented as AWS Transform MGN. It performs continuous block-level replication of your source servers and converts them for launch on AWS, and it covers physical, virtual and cloud servers across Windows Server and various Linux distributions. The source keeps serving traffic throughout. Nothing about the replication needs downtime, and AWS describes the cutover window itself as typically minutes.

Settings come from three configurable templates, for replication, launch and post-launch. They are applied to each newly added server and can be overridden per server at any time. Beyond a handful of machines, group servers into applications and applications into waves so that launch, cutover and archival can be done in bulk.

aws mgn describe-source-servers \
  --query 'items[].{id:sourceServerID,host:sourceProperties.identificationHints.hostname,state:lifeCycle.state}' \
  --output table

The dress rehearsal

The test launch is what makes this approach safe, and it helps to know exactly what it does not disturb.

Launching a test instance leaves replication running. After the test, data replication continues as before, and the new and modified data on the source server is transferred to the staging area subnet rather than to the test instance you launched. You can test as many times as you want. Each new test first deletes any previously launched test instance and its dependent resources, then launches a fresh one reflecting the most up-to-date state of the source. AWS recommends performing a test at least two weeks before you plan to migrate, which is realistic, because that is roughly how long it takes for the second and third problems to surface.

aws mgn start-test --source-server-ids s-0123456789abcdef0

Then connect to the launched instance over SSH or RDP and actually exercise it. Validate connectivity and run your acceptance tests against it. When you are done you either revert the test, which returns the server to the Ready for testing lifecycle state, or mark it as ready for cutover, which moves it to Ready for cutover. Both offer to terminate the launched test instances, and you should take that option.

DNS is the part you cannot rush

Lower the TTL on every record pointing at the server days before the cutover, not on the day. Route 53's own guidance for a domain or subdomain that is already in use is to specify a shorter value first, such as 300 seconds, and increase the value again after you have confirmed the new settings are correct.

Lowering a TTL does not take effect immediately. A resolver that already cached the record under the old TTL keeps it until that expires, so if the record sat at a day, the change only becomes reliable a day later. Do the arithmetic backwards from the cutover date.

# what a resolver is handing out right now, TTL included
dig +noall +answer app.example.com

# what the authoritative nameserver says
dig +noall +answer @ns-1.example.net app.example.com

After you flip the record, watch traffic on the old server. The tail of clients still arriving is the honest measure of whether the TTL plan worked.

Cutover, and the point of no return

Launching a cutover instance moves the server to Cutover in progress. As with a test, MGN first deletes any previously launched test instance, then launches a cutover instance reflecting the most up-to-date state of the source. Crucially, after the cutover data replication continues as before, and new and modified data on the source is still transferred to the staging area subnet rather than to the cutover instance.

That is your rollback window. The source server is still running, still replicating, and DNS is the only thing pointing at AWS. If the new instance misbehaves you point the record back and lose nothing.

The point of no return is a separate, deliberate action. Finalizing the cutover changes the state to Cutover complete, stops data replication, causes all replicated data to be discarded, and terminates all AWS resources used for data replication. Do not finalize on cutover night. Finalize once the new server has been through a full business cycle, including the monthly jobs that only exist in the inventory you wrote at the start.

aws mgn start-cutover --source-server-ids s-0123456789abcdef0

# destructive: stops replication and discards all replicated data
aws mgn finalize-cutover --source-server-id s-0123456789abcdef0

Databases move differently

Block-level replication of a running database gives you a crash-consistent copy, which is not the same thing as a database you would choose to serve from. For the data itself, use AWS Database Migration Service with a task that migrates existing data and replicates ongoing changes, the option called full-load-and-cdc in the API. It loads what is there, then applies the changes captured during the load as units of single committed transactions, so the target keeps catching up while the source stays live. The switch becomes a short pause on writes rather than an export and an import.

Run a premigration assessment before you start the task, since it warns you about potential migration issues before the migration runs rather than halfway through it.

Everything above is the shape of a low-risk move, and the details that decide whether it is low-risk in your case are the ones in your inventory. If you would rather not carry that alone, this is what our migration services do, with the target design settled first in architecture and planning.

Talk to the engineer who will own your stack.

No account managers, no offshore handoff. Senior DevOps, direct. Tell us what you are dealing with and you get a straight answer.