Storage migration: copy, verify, cut over, rollback
This runbook migrates CaseBender objects without changing object keys. It uses copy-first semantics: the source remains authoritative and intact until the rollback window expires. It applies to local filesystems, MinIO/S3-compatible storage, AWS S3, and GCS throughrclone remotes.
Preconditions
- Read the storage support policy and release notes for both providers.
- Fix or account for the legacy MinIO-only attachment deletion path before moving to a non-MinIO destination.
- Confirm destination capacity, encryption, versioning, retention, lifecycle, object-size, metadata, and naming behavior.
- Create least-privilege source-read and destination-write migration identities.
- Configure TLS trust; never use
--no-check-certificate. - Take and test a consistency backup of PostgreSQL and source storage.
- Record object count, total bytes, source versions/snapshots, and configuration.
- Set a change window that permits write quiescence and rollback.
source:casebender and destination:casebender. Keep rclone
configuration and logs outside the repository and protect them as sensitive.
1. Inventory and dry run
sync for the initial copy because it can delete destination
objects.
2. Seed copy while the application is online
3. Quiesce writes and capture the consistency point
Block user and integration writes using the release’s maintenance procedure. Pause ingestion and workers only after the queue is drained or durably retained. Record the database timestamp/LSN, source bucket version/snapshot, and deployment replicas. Verify no storage writes are occurring. Run the final delta:4. Verify before cutover
rclone check --download hashes downloaded content and avoids provider ETag
ambiguity. Require zero missing, changed, or unreadable objects. Investigate
count differences from provider marker objects or local .meta.json sidecars;
do not waive differences without a recorded explanation.
Run the destination contract test from the application network:
5. Cut over
- Save the old provider configuration and Secret resource version in the encrypted change record.
- Change only the explicit provider variables and credentials. Preserve bucket contents and object keys.
- Restart the web application and wait for readiness.
- Run application upload/download/list/copy/delete tests and verify SHA-256.
- Verify existing attachments and evidence across several ages and sizes.
- Resume workers and ingestion, then user writes.
- Monitor storage errors, failed deletes, latency, throttling, queue depth, and audit events continuously through the rollback window.
6. Rollback
Rollback is safe only while the old source is retained and new writes can be reconciled.- Re-enter maintenance mode and quiesce writes.
- Record all objects written to the destination since cutover.
- Copy the reverse delta to the source without deletion:
- Require a clean check, then restore the prior provider configuration and credential version.
- Restart, run application lifecycle/integrity tests, and resume traffic.
- Keep both stores and all evidence until incident/change review completes.
7. Closeout
- Reconcile final counts/bytes and archive hashes, logs, tool versions, approvals, configuration versions, and sampled application results.
- Rotate temporary migration credentials.
- Keep source read-only for the approved rollback period.
- After formal sign-off and legal/retention review, remove source data using the provider’s audited disposal process.
- Update the support record with provider product/version, TLS/CA details, contract result, performance result, backup result, and rollback exercise.