Moving a live site from CDK to Terraform without recreating anything
This site ran on a CloudFormation stack defined in CDK, and I wanted it on Terraform like the rest of my infrastructure. The rule for the move was one line: import, never recreate. A live site, its data and its user pool should not notice a change of tooling.
The approach
I generated 159 import blocks from the live stack, let Terraform generate configuration from them, then split that into readable files and replaced literal IDs with references. Each step had to leave the plan unchanged, so a mistake showed up as a diff rather than as an outage.
The first plan was not clean: 17 in-place changes. Rather than assume they were harmless, I checked each one. The seven Lambda updates were the best example. A zip built by Terraform never hash-matches one built by CDK, so I downloaded the live code and compared it to the new build. The difference was zero lines.
The two traps
Deleting a CDK stack also runs its custom resources' delete handlers, and two of mine were dangerous:
- The auto-delete resource empties the website bucket when it is removed.
- The config generator deletes
config.json removal, which takes the API configuration off the live site.
So the last CDK deploy existed only to defuse them: turn off auto-delete and mark everything Terraform would adopt as retained. Only then did the stack get deleted.
The result
Terraform adopted all 159 resources, and the next plan reported no changes. The first real deploy through the new path shipped with the usual build-identity check passing at both the origin and the CDN. Afterwards I removed the CDK app and its toolchain, 86 packages in all.
What I'd tell someone else
- Make "no changes" the test. Every step of a migration should have a plan you can read.
- Verify the no-ops. An in-place change you did not check is a guess.
- Read the delete handlers before deleting a stack. Retained resources are safe; custom resources still run.