We manage many customer-isolated AWS environments with CloudFormation, including EC2 instances, load balancers, Auto Scaling Groups, VPCs, security groups, and other services. We're evaluating a migration to OpenTofu and want to keep the process as safe and predictable as possible, especially for production.
What tools or workflows can help generate OpenTofu configuration and import existing resources? How should dependencies be handled, and is it best to migrate one stack or customer environment at a time? We'd also appreciate advice about state management, common pitfalls, preventing unwanted replacements, and ensuring OpenTofu only adopts existing resources rather than modifying or recreating them.
5 Answers
Protect the resources from CloudFormation before doing anything else. Add DeletionPolicy: Retain and UpdateReplacePolicy: Retain to the stack resources and deploy that change first. This prevents CloudFormation from deleting live infrastructure if the stack or a resource is later removed. Generated configuration may include explicit physical names assigned by CloudFormation; keep those names initially because removing a name can cause a replacement. Make the initial OpenTofu phase import-only, and handle intentional improvements or infrastructure changes in a separate phase.
The safest approach is to migrate one stack and customer environment at a time, starting with a lower-risk environment. Use OpenTofu import blocks and plan -generate-config-out to create an initial configuration, then review and clean it up manually. Treat a clean no-op plan as the completion criterion—not merely a successful import. Before every migration, back up and carefully inspect the state, and run plans with refresh-only or otherwise read-only checks until you’re confident the configuration matches reality.
Keep the first production apply extremely conservative. Import the resources, run a refresh and plan, and investigate every proposed update, replacement, or deletion. Don’t accept a plan just because the import succeeded. Use backups and locking for state, restrict who can apply during the migration, and preserve the original CloudFormation definitions until the OpenTofu state and no-op plan have been validated. After that, retire CloudFormation gradually rather than changing ownership and configuration all at once.
Resource dependencies are usually less difficult than expected because imports use the real AWS resource IDs rather than relying on CloudFormation’s creation order. Still, migrate related resources in logical groups and verify references between them. Don’t use lifecycle ignore_changes as a blanket solution for every difference; it can hide real drift and leave OpenTofu unable to manage important settings. If it is needed temporarily for provider-normalized fields or unavoidable external changes, document it and revisit it after the migration.
The generated configuration is useful as a starting point, but it often produces a huge collection of static resources. For repeated customer environments, use it to discover the actual settings and import IDs, then refactor the result into reusable modules with customer-specific root configurations and variables. A script using the CloudFormation API can generate import blocks or resource definitions and present drift in a more manageable way. Test the modules on development environments first, and compare two materially different environments early so you discover which settings really need to be configurable.

Related Questions
Can't Load PhpMyadmin On After Server Update
Redirect www to non-www in Apache Conf
How To Check If Your SSL Cert Is SHA 1
Windows TrackPad Gestures