Practice: Integrating legacy systems and running migrations

Generated by Claude through GigAI 0.1.11.10 on 2026-10-11.

Main tool: Microsoft Azure · Microsoft Azure documents the strangler fig facade, the anti-corruption layer, change data capture, cutover planning and safe decommissioning as one connected set of guidance, and its emulators and containers let you rehearse all of it on a laptop. · Alternatives: Debezium with Kafka Connect streams legacy database changes on open source infrastructure you run yourself; AWS Database Migration Service is a managed replication service tied to another cloud; Flyway, Liquibase and Alembic version schema changes but do no routing or integration; NGINX and Envoy give you only the facade proxy; MuleSoft is a commercial integration platform with ready-made connectors for SOAP and SFTP sources.

Every step links into the tool's own documentation; links were checked on 2026-10-11 · version 1

Setup (one time)

Steps

  • 1. Run a small legacy web app in a container and create a facade in front of it using a local API Management self-hosted gateway or a Functions proxy app, so that every client request goes through the facade.

    The facade is the first move of a strangler fig migration: clients stop knowing where functionality lives. Nothing changes for users yet, which is the point.

    Explained in: Strangler Fig Pattern - Azure Architecture Center | Microsoft Learn (learn.microsoft.com), checked 2026-10-11

    Done when: Every request to the facade address returns the same response as the legacy app, and the legacy app is no longer called directly.

  • 2. Create a new service for one narrow feature, such as order lookup, and configure the facade to route only that path to it while everything else still goes to the legacy app.

    Moving one slice at a time keeps each change small and reversible. The worked example in the cited section shows the same staged routing.

    Explained in: Strangler Fig Pattern - Azure Architecture Center | Microsoft Learn (learn.microsoft.com), checked 2026-10-11

    Done when: The order lookup path is answered by the new service, all other paths by the legacy app, and switching one route setting reverses it.

  • 3. Write an anti-corruption layer as a separate module that translates legacy column names, status codes and date formats into the new service's own model, and make it the only code that touches the legacy schema.

    Without this layer, legacy naming and quirks leak into the new design and outlive the old system. Isolating translation in one place also gives you one place to delete after cutover.

    Explained in: Anti-Corruption Layer Pattern - Azure Architecture Center | Microsoft Learn (learn.microsoft.com), checked 2026-10-11

    Done when: A search of the new service finds no legacy table or column name outside the translation module, and its unit tests pass.

  • 4. Enable change data capture on the legacy database and on the orders table, as the integration surface for a system that exposes no API.

    When the old system has no interface, its transaction log is the most reliable one: you observe changes without modifying the legacy application. The cited section explains what the capture process records.

    Explained in: What is change data capture (CDC)? - SQL Server | Microsoft Learn (learn.microsoft.com), checked 2026-10-11

    Done when: The database lists a capture instance for the orders table and the capture job is running.

  • 5. Query the change table after inserting, updating and deleting a few legacy orders, and load those changes through the anti-corruption layer into the new service's store.

    This closes the loop from legacy write to new-model record, which is how the new system stays current while the old one remains the system of record.

    Explained in: What is change data capture (CDC)? - SQL Server | Microsoft Learn (learn.microsoft.com), checked 2026-10-11

    Done when: Each legacy change appears as a translated record in the new store, with the operation type preserved.

  • 6. Run a parallel change on the legacy orders table: add a new column alongside the old one, create a second capture instance that includes it, backfill, switch readers, then drop the old column.

    Expand, migrate, contract is how you evolve a live schema without breaking consumers. Capture instances do not follow schema changes automatically, so you need to see how two instances cover the transition.

    Explained in: What is change data capture (CDC)? - SQL Server | Microsoft Learn (learn.microsoft.com), checked 2026-10-11

    Done when: Changes flow without a gap through all three phases, and the old column is gone with no failed reads in the new service.

  • 7. Write a cutover runbook that names the maintenance window, the freeze on legacy writes, the validation queries, the go or no-go criteria and the rollback steps.

    A cutover is safe only when the window, the checks and the way back are agreed before anyone touches production. Writing the runbook exposes missing steps while they are still cheap to fix.

    Explained in: Plan Your Workload Migration from Amazon Web Services (AWS) to Azure | Microsoft Learn (learn.microsoft.com), checked 2026-10-11

    Done when: The runbook is committed, and a colleague can state from it alone when the window opens, what is checked and how to roll back.

  • 8. Run the cutover as a rehearsal: freeze legacy writes, compare row counts and checksums between the legacy tables and the new store, then switch the remaining facade routes to the new service.

    Validation by reconciliation is what turns a hopeful switch into a proven one. Rehearsing locally shows how long each runbook step really takes.

    Explained in: Plan Your Workload Migration from Amazon Web Services (AWS) to Azure | Microsoft Learn (learn.microsoft.com), checked 2026-10-11

    Done when: The counts and checksums match, all facade routes point to the new service, and the rehearsal timings are recorded in the runbook.

  • 9. Configure the facade and the new service to emit request, error and reconciliation telemetry to a local collector, and set a retention period that covers the full observation time after cutover.

    You can only declare the legacy system unused if you have kept evidence for long enough to cover monthly and quarterly jobs. Retention chosen by usage pattern keeps that evidence without storing everything forever.

    Explained in: Architecture Strategies for Designing a Monitoring System - Microsoft Azure Well-Architected Framework | Microsoft Learn (learn.microsoft.com), checked 2026-10-11

    Done when: A query over the collected telemetry shows zero calls to legacy routes for the whole retention period you set.

  • 10. Run the decommissioning sequence on the rehearsal stack: disable the capture instances, archive the legacy data, remove the legacy routes and the anti-corruption layer, then stop the legacy containers.

    A migration is not finished until the old tool is switched off; leftover components keep costing money and attention. Doing it in a planned order keeps the last step reversible until the data is archived.

    Explained in: Architecture strategies for safe deployment practices - Microsoft Azure Well-Architected Framework | Microsoft Learn (learn.microsoft.com), checked 2026-10-11

    Done when: The stack runs and passes its tests with no legacy container, and the archive restores into a scratch database.

  • 11. Create a pipeline definition that rebuilds the stack from the templates, applies the schema scripts, runs the reconciliation checks and blocks promotion when any check fails.

    Customer migrations are repeated across environments, so the checks have to run the same way every time, without relying on memory. Quality gates make a failed reconciliation stop the release.

    Explained in: Architecture Strategies for Designing a Workload Development Supply Chain - Microsoft Azure Well-Architected Framework | Microsoft Learn (learn.microsoft.com), checked 2026-10-11

    Done when: A run from a clean checkout passes end to end, and a deliberately introduced row mismatch makes the run fail at the gate.

  • 12. Deploy a preproduction copy of the whole stack to a local kind cluster with the same routing rules, schema version and data volume shape as the target. A real cloud environment would need a paid subscription, so the local cluster is the substitute.

    The final rehearsal is only worth trusting if the environment resembles production where it matters. The cited section helps you choose which similarities to pay for and which to relax.

    Explained in: Architecture strategies for optimizing environment costs - Microsoft Azure Well-Architected Framework | Microsoft Learn (learn.microsoft.com), checked 2026-10-11

    Done when: The full runbook, from facade routing through cutover validation to decommissioning, completes on the cluster with every gate passing.