AWS → STACKIT · RUNBOOK

AWS to STACKIT cutover and rollback runbook

A cutover is a sequence of small, reversible steps followed by one irreversible one. This runbook orders the steps the way StackToIT orders them for a demo estate (a PostgreSQL database, a bucket, a server and a DNS zone), gives each an owner, a check and a way back, and marks the point after which the way back is a rebuild from backups.

How to use this runbook

The order comes from the run's execution plan, the owners and rollback lines from the manual steps it writes (execution/manual/actions.md). Rows marked practice are general good practice that the run does not write.

  • Source of the order

    Dependencies set the waves; the cutover steps carry "after" links, so readiness follows the last data reconcile, the switches follow readiness and the rollback decision follows every check.

  • Nothing runs by itself

    StackToIT creates, changes and deletes nothing. Each step is done by a person, by OpenTofu or by a script your team runs.

  • No timings

    The plan states no maintenance window and invents none. Take durations from your rehearsal, not from a table.

The build order: three waves

From migration/technical-sequencing.md of the demo run: nine units in three waves. Units of one wave can move in parallel; the file calls it a starting point for your wave plan, not a schedule.

Wave planmigration/technical-sequencing.md
## Wave 1 — 4 unit(s)

| Unit | Class | Target |
|---|---|---|
| `aws_route53_zone.main` | DIRECT / MEDIUM | STACKIT DNS |
| `aws_s3_bucket.uploads` | RECONFIGURE / MEDIUM | STACKIT Object Storage |
| `aws_secretsmanager_secret.api_key` | RECONFIGURE / MEDIUM | STACKIT Secrets Manager |
| `aws_vpc.app` | RECONFIGURE / MEDIUM | STACKIT project networking / Network Area (SNA) |

## Wave 2 — 3 unit(s)

| Unit | Class | Target |
|---|---|---|
| `aws_security_group.db` | RECONFIGURE / MEDIUM | STACKIT security group |
| `aws_subnet.app_a` | RECONFIGURE / MEDIUM | STACKIT network |
| `aws_subnet.app_b` | RECONFIGURE / MEDIUM | STACKIT network |

## Wave 3 — 2 unit(s)

| Unit | Class | Target |
|---|---|---|
| `aws_db_instance.orders` | REPLATFORM / MEDIUM | STACKIT PostgreSQL Flex |
| `aws_instance.app` | RECONFIGURE / MEDIUM | STACKIT Compute Engine |

Phase 1 · Before the window

StepOwner · done whenRollback
Answer the open decisions: data movement method for the database and for the bucket, the opt-in for the S3 API calls, the boot image of the server, the sizing and endpoint defaultsArchitects · the steps that wait for a decision are freed (executive/decisions.md; the demo has 6 decisions, 5 of which hold steps)Nothing changed yet
Fill the variables (project_id, access scope, client CIDRs, storage class, image, machine type), complete the pre-steps of execution/terraform/apply.md, then apply the reviewed Terraform (OpenTofu applies all its steps in one apply)Platform team · every item of execution/verify/checks.md tickedDestroy the new STACKIT resources; the source is untouched (practice)
Lower the TTL of the zone and of its delegation, then wait the old TTL (the demo zone's largest TTL is 300 s)Network Architect · the old TTL has passedRaise the TTL again (practice)
Query each record at a STACKIT name server directly and compare with Route 53Network Architect · answers match, except where the value is an AWS endpointDo not touch the registrar until they match
Data preflight and rehearsal for the database and for the bucket; initial copy and a replication watch where the method has oneData Architect · the elapsed time of each part is recorded and the freeze window is agreed from itDelete the scratch instance; the source is unchanged
Restore check: clone the new PostgreSQL Flex instance to a point in time, read it, compare, record the duration, delete the cloneStorage Architect · clone agrees with the source; AWS backup retention date recordedA check changes nothing; delete the scratch resources
Decide now whether writes made on the target after the switch are copied back or accepted as lostMigration Owner · decision recorded before the window, not in the incidentNot applicable

Phase 2 · Freeze and final copy

StepOwner · done whenRollback
Cutover readiness: confirm every workload step and data move is done before the first switchMigration Owner · each step it follows is recorded as doneA confirmation changes nothing
Write freeze: list who writes, record every client's connection settings, stop the services, jobs and migrations that writeMigration Owner · no client writes to the sourceStart the writers again against the source: nothing was changed
Final copy: dump and restore inside the freeze, or wait for zero replication lag, copy the sequences and disable the subscription; copy the last objects of the bucketData Architect · lag was 0, target sequences are not lower than the source'sThe slot is still on the source and the source untouched: put the writers back
Reconcile: row counts, checksums, sequences and one query the application runs; object counts and key lists for the bucket; record GO or NO-GOData Architect · numbers equal on both sidesOn NO-GO take the rollback without switching anything

Phase 3 · The switch

StepOwner · done whenRollback
Switch the connection of the applications that use the database: host, port, database name and credentialsData Architect · every application connects to PostgreSQL Flex and the AWS instance receives no reads or writesPoint the configuration back; what was written to the target meanwhile is not in AWS
Switch the applications that use the bucket: endpoint, bucket name and access keysStorage Architect · applications use the STACKIT bucket, the AWS bucket sees no requestsPoint the configuration back to the AWS bucket
Traffic switch for the server: move clients from its AWS address to its STACKIT addressNetwork Architect · requests reach the STACKIT address, the AWS address receives noneChange the clients back; the AWS resources stay until the GO
Delegation change of the zone: replace the Route 53 name servers with those STACKIT shows, at the registrar or the parent zoneNetwork Architect · the parent answers the STACKIT NS records and a resolver asked after one parent NS TTL agreesSet the NS records back to Route 53; keep the STACKIT zone for at least one parent NS TTL
Cutover completion: confirm every switch is recorded as doneMigration Owner · the owner records that the cutover is completeA confirmation changes nothing

The two steps that carry the rollback

Verbatim line ranges from execution/manual/actions.md of the demo run: the risk and the rollback of the delegation change, then the head and the rollback of the rollback decision step. The long dependency and state lines between them are left out.

Delegation change · risk and rollbackexecution/manual/actions.md
- Risk: while resolvers hold the old delegation (one parent NS TTL) some answer from Route 53 and some from STACKIT: a record changed in one zone and not in the other is seen by part of the clients only, so both zones hold the same records until the TTL has passed
- Rollback (manual): set the NS records at the registrar (or the parent zone) back to the Route 53 name servers; resolvers that hold the STACKIT delegation keep it for one parent NS TTL, so the STACKIT zone stays in service for at least that long after the rollback, and the Route 53 zone is retired only after the GO recorded at the rollback decision step
Rollback decision · what, why, who, whenexecution/manual/actions.md
#### The rollback decision step (`MAN/verify/rollback-decision`)

- Phase: Verification
- What: Decide GO or ROLLBACK for the migration once every check of the verification is done: GO lets the source resources be retired, ROLLBACK reverts the cutover and keeps AWS serving
- Why: reverting the cutover is a change of addresses only while the AWS resources exist; after the first decommission step the way back is a rebuild from backups
- Who: Migration Owner
- When: after every check of the verification
Rollback decision · risk and rollbackexecution/manual/actions.md
- Risk: the decision point follows every check of the verification (each is also an action-complete precondition); the retirement steps depend on it, and through it on the checks
- Rollback (manual): on ROLLBACK, revert each cutover step as its rollback says (the traffic switch of aws_instance.app, the delegation change of the hosted zone of aws_route53_zone.main, the switch of the applications that use aws_s3_bucket.uploads, the switch of the applications that use aws_db_instance.orders) and start no decommission step; on GO nothing is reverted

Phase 4 and 5 · Verify, decide, retire

StepOwner · done whenRollback
Endpoint check right after the traffic switch, then the data checks for the database and the bucket: counts agree, the application reads migrated records, a test write is read backNetwork, Data and Storage Architects · status and content match what the AWS address gaveChecks change nothing; remove the test record they wrote
Rollback decision: record GO or ROLLBACK with the date and the result of each checkMigration Owner · decision recordedOn ROLLBACK revert each switch as its own rollback says and start no retirement step
Clean up the data move: drop the subscription and publication, remove the move host from the access list, delete dump files, rotate the credentials, keep a final snapshot of the source; setting rds.logical_replication back means a reboot, a second outage of the source if you keep itData Architect · no slot, subscription, publication or dump file is left and the move host is out of the access listNone: after the cleanup the way back is the final snapshot of the source
Retire each AWS resource on its own (database, secret, server, bucket, zone, security group, subnets, network), each only after the resources that depend on it are goneEach resource owner · the resource no longer exists in the AWS account and its charges stop on the billImpossible for the database: only the final backup restores its data, into a new resource
Turn on instance protection for critical production instances of PostgreSQL Flex (practice; STACKIT's release notes advise it, because deleting an instance without it loses the data at once)Data Architect · protection enabledDisable it deliberately when you need to delete

The DNS draft behind the delegation step

The STACKIT DNS zone and record set the demo run wrote (terraform/dns.tf, without comments). The record keeps the 300 s TTL of the source.

STACKIT Terraform by StackToITterraform/dns.tf
resource "stackit_dns_zone" "main" {
  project_id = var.project_id
  name       = "orders.example.com"
  dns_name   = "orders.example.com"
}

resource "stackit_dns_record_set" "app" {
  project_id = var.project_id
  zone_id    = stackit_dns_zone.main.zone_id
  name       = "www.orders.example.com"
  type       = "A"
  records    = ["203.0.113.10"]
  ttl        = 300
}

Rules for the rollback

Where the way back ends, and what you give up on the way.

  • Keep the source whole until the GO

    The plan never makes the source read-only or changes it after the freeze, so a rollback is only configuration put back. Delete nothing in AWS before the rollback decision is GO.

  • Writes after the switch

    Whatever the applications wrote to STACKIT after the switch is not in AWS. Copy it back with a separately rehearsed method or accept it as lost, and decide before the window.

  • DNS needs patience

    Resolvers keep the old delegation for one parent NS TTL after a change, so both zones must hold the same records for that long. The TTL of the delegation at the registrar is not in the source.

  • DNSSEC (practice)

    AWS documents for the opposite direction that a domain cannot be signed by two providers at once and the DS record must be removed first. If your zone is signed, plan the DS record in both directions.

  • The point of no return

    After the first retirement step the way back is a rebuild from backups. That is why the decision step is separate and carries a date and the result of every check.

Questions teams ask

How long should the maintenance window be?

The plan states no window and invents none. Take the copy times from your rehearsal, add the comparison and the switch, and agree the window with the application owners.

Can StackToIT run the cutover for us?

No. It writes the steps, owners and checks. An executor that would carry out the plan step by step is described in the package as designed and not implemented.

Do we switch DNS first or the data first?

The plan orders the data reconcile, then readiness, then the switches. The delegation change waits for the STACKIT zone to hold every record and for the lowered TTL to have passed.

What if the reconcile fails?

Take the rollback without switching anything. The clients still point at the source, which is current up to the freeze.

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.