CUTOVER → STACKIT · CHECKLIST
Cutover, rollback and decommissioning checklist for STACKIT
Tick these checks in order and the only irreversible moment of the migration, the retirement of the source data stores, comes after a recorded GO with a kept backup. The list follows the execution plan StackToIT wrote for a portal on AWS with a PostgreSQL database, an object bucket, a server with a public address, a certificate and a DNS record: 78 steps, 64 of them manual. Every check names the file that holds the answer, grouped by phase: design, build, data, cutover, rollback and after.
1 · Design: before anything is built
Answers to find in migration/technical-sequencing.md (the three boxes under "Before wave 1"), decisions.json and engineering/architect-report.md.
Every unit the draft does not write has an owner
migration/technical-sequencing.md asks for every REDESIGN, MANUAL_REVIEW and BLOCKED unit to be reviewed; this run has none. Its one gap is the certificate: RECONFIGURE, with stackit_alb_certificate named as the target but not written by this draft, so terraform/README.md lists it as left for the architect.
STACKIT organisation, folders and projects are laid out
One project per environment is the usual start, as the plan puts it. Everything later assumes the project exists.
A data-transfer method and window are agreed per data unit
The run lists the database and the bucket as data units, each with several candidate methods. No method is taken until the decision is answered.
The source provider version is pinned
Commit the lock file the run asks for. Until then every unit of that provider carries an open item.
Recovery point and tolerated downtime are written down
The run states neither: the plan marks them not provided. Without them the freeze window cannot be argued.
2 · Build: the target exists and is checked
Files: terraform/, execution/terraform/apply.md and execution/verify/checks.md, whose "before each step" and "after each step" lists are tick boxes.
Variables without defaults have a value
Eight in this run: project_id, the access scope, allowed address ranges and storage class of the database, the image, machine type and boot volume size of the server, and the DNS zone identifier. The checks file lists each as a before-step.
The draft is validated and planned in a test project
The README of the terraform folder asks for tofu init, validate and plan against a test project first. The engine never applies.
The STACKIT services are enabled and the state is protected
terraform/README.md names the services to enable in the project and region before apply (DNS, IaaS, Object Storage, PostgreSQL Flex) and warns that the state holds the generated database password and bucket secret in plain text, so the state backend must be encrypted and access-limited.
The new database, bucket, server and public address exist
Each Terraform step has an after-check "exists in the STACKIT project".
The DNS zone is bound
Choose or create the STACKIT zone that replaces the Route 53 zone and set the zone variable. The run does not check that the zone holds the right domain. The STACKIT documentation describes a script that copies the record sets of Route 53 zones into STACKIT DNS and skips the apex NS and SOA records.
The certificate question is answered
The source declares a certificate; whether it covers the names that move is not evaluated by the run. Decide reissue, import or replacement.
3 · Data: copy, rehearse, prove
Files: migration/data-movement.md and terraform/handover/database-portal/data-move.md.
Preflight closes every unknown check
Versions, extensions, roles, network and TLS, by read-only queries on source and target.
A rehearsal into a scratch database is timed
The freeze window is agreed from those timings, not guessed.
The initial copy and delta syncs run
For the bucket the candidate tools include the AWS CLI sync and rclone; for the database, logical replication or dump and restore.
Row counts, checksums, sequences and one application query agree
This is the reconcile step with the writers stopped. It ends in a recorded GO or NO-GO.
4 · Cutover: one switch after another
Files: the cutover section C1 to C5 of migration/technical-sequencing.md, and the MAN/cutover steps of execution-plan.json.
TTLs are lowered ahead of the switch
The plan reads the TTL of each record from the source (60 s here, so this record is already short) and suggests 60 s as the target. It asks you to record the change time and the old TTL, then wait one old TTL before the switch.
Cutover readiness is confirmed
Every workload step and data move is done. The plan cannot tell which entry point serves which store, so every switch waits for all of them.
Writers are listed, then stopped
List who writes, record the connection settings of every client, then stop services, jobs and migrations. Leave the source read-write and untouched.
Final sync and reconcile pass inside the freeze
If a number or the application query differs, stop and take the rollback without switching anything.
Connection strings of every client are switched
Host, port, database, credentials and TLS mode for the database; endpoint, bucket name and keys for the bucket. The applications are outside the source, so their owners list them.
The DNS record points to the new public address
The record value moves from the AWS address to the STACKIT address. Verify first by querying a STACKIT name server directly and comparing with the old answer.
Requests reach the new address and the old one receives none
The check reads access logs or metrics of both sides.
5 · Rollback: decided before the window opens
Files: the rollback entry of each step in execution-plan.json and the Rollback section of the data-move handover.
Old connection settings are recorded and kept
The rollback needs them. The handover tells you to keep the old values when you switch.
A rollback trigger and a source-retention date are named
Both are marked unknown in the plan and supplied by the migration owner. Nobody can invent them for you.
The rollback of the traffic switch is known
Change the DNS record back to the AWS address. Leave the TTL lowered during the rollback window, so a second switch takes effect quickly.
Writes made on STACKIT after the switch have a plan
They are not on the source. Copy them back with the same method in the other direction, after a separate rehearsal, or accept the loss in writing.
The AWS resources stay in place until GO
The plan retires nothing before the recorded GO of the rollback decision step.
6 · After: verify, decide, clean up, decommission
Files: MAN/verify and MAN/decommission steps of execution-plan.json; execution/manual/actions.md.
A restore is tested on STACKIT
Clone the PostgreSQL Flex instance to a point in time after the data moved, read and compare it, record the duration, delete the clone. Also record the date until which the AWS automated backups are kept.
GO or ROLLBACK is recorded with the result of each check
The decision step depends on every verification step. On GO restore the normal DNS TTL.
Replication leftovers are removed
Subscription, publication and slot, dump files, the move host in the access list. Rotate the credentials used for the move.
A final backup of each source store is kept
Decommissioning the database or the bucket cannot be undone by the plan; only the final backup restores the data, into a new resource. The source states no final_snapshot_identifier, so the plan warns that deleting the RDS instance as managed fails until a snapshot name is stated.
Source resources are retired in dependency order
Subnets before the VPC, for example. Remove them from the source configuration and apply that, instead of a targeted destroy that would delete what depends on them.
Where the window opens and where the way back ends
Verbatim line ranges from execution-plan.json of the run, written on 4 November 2026 for an estate made for this page: the operation, risks and rollback of two steps. Left: the TTL lowering that opens the cutover. Right: the retirement of the database, the step with no way back.
"operation": {
"manual": {
"what": "Lower the TTL of the DNS names the clients of aws_eip.portal (aws_eip) resolve, ahead of its traffic switch: the source holds 1 Route 53 record that point to it: \"portal.example.com\" (aws_route53_record.portal): the source states a TTL of 60 s. Lower each TTL that is not an alias record's to a short value the person chooses (the plan suggests 60 s, which is also the lowest TTL STACKIT DNS takes for a record set; it is a suggestion, not a fact of the source)",
"why": "a resolver keeps the answer it holds for one TTL: a switch of aws_eip.portal made while resolvers still hold an answer cached under the old TTL leaves part of the clients on the AWS address until that answer expires, and lowering the TTL first shortens that tail to the lowered TTL",
"owner_role": "Network Architect",
"when": "at least 60 s (the longest TTL the source states) before the maintenance window of the traffic switch of aws_eip.portal, because resolvers keep the old answer for up to one TTL: a change made later does not reach the resolvers that already hold the old answer",
"required_input": "the old TTL of each name (stated above, or read with the command named), the TTL to lower it to (the owner's choice; the plan suggests 60 s), and a person who can change the record sets in Route 53",
"success_condition": "the record set of each name that has a TTL of its own shows the lowered TTL (`aws route53 list-resource-record-sets`), the TTL a resolver is given for each alias name is read and recorded, and one old TTL has passed since the change (the time of the change and the old TTL are recorded)"
}
},
"postconditions": [],
"decisions": [],
"risks": [],
"rollback": [
{
"capability": "MANUAL",
"how": "restore the old TTL of each name after the GO recorded at the rollback decision step; on a ROLLBACK leave it lowered during the rollback window, so that a second switch (back to AWS, then again) takes effect within the lowered TTL, and restore it when the owner decides to stay on AWS"
}
], "operation": {
"manual": {
"what": "Retire aws_db_instance.portal (aws_db_instance) in the AWS account after the GO: delete it the way it is managed (remove it from the source configuration and apply that, or delete it in the AWS console), once the resources that depend on it are retired (the steps it follows); a targeted destroy of the source configuration would also delete what depends on it",
"why": "aws_db_instance.portal keeps costing money and can still take traffic or writes after the cutover, so the two copies drift apart; StackToIT deletes nothing (it is read-only): a person retires it",
"owner_role": "Data Architect",
"when": "after the GO recorded at the rollback decision step",
"required_input": "the final backup of aws_db_instance.portal, kept for a number of days the owner decides (the plan states no default), and the GO recorded at the rollback decision step",
"success_condition": "aws_db_instance.portal no longer exists in the AWS account and its charges stop on the bill"
}
},
"postconditions": [],
"decisions": [],
"risks": [
"StackToIT performs none of this: it deletes nothing in any cloud, and no step of this plan automates the retirement",
"the source states no final_snapshot_identifier and not skip_final_snapshot = true: the provider documents the identifier as required when skip_final_snapshot is false (its default), so deleting the instance as managed fails until a name is stated; state it, and the snapshot it names is the final backup this step needs"
],
"rollback": [
{
"capability": "IMPOSSIBLE",
"how": "the plan cannot bring aws_db_instance.portal back: only the final backup the owner kept restores its data, into a new resource"
}
],Two rollback capabilities
The TTL step is MANUAL: restore the old TTL after GO, or leave it lowered during a rollback so a second switch is fast. The retirement is IMPOSSIBLE: only the final backup brings the data back, into a new resource.
Owners are roles
The run names roles such as Migration Owner, Data Architect and Network Architect; map them to people before the window.
Questions before the window
Does StackToIT perform the cutover?
No. It writes the steps, owners, checks and rollback notes; people or OpenTofu carry them out. The sequencing file says it gives no time estimate.
Which steps cannot be rolled back?
In this run the retirement of the database and of the bucket: the plan states that only the final backup the owner kept restores the data, into a new resource. The VPC, the certificate and the DNS record can be re-created from the source configuration, though what they held beyond that configuration is not restored.
How long should the source stay in place?
The plan leaves that open and asks the migration owner for a date. Keep it until the recorded GO, and longer if your recovery objectives say so.
Why lower the DNS TTL?
So that the switch, and a switch back, take effect within the lowered TTL. The plan suggests 60 seconds and treats it as a suggestion, not a fact of your source.
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.