Skip to content
Notifications
Clear all

Step-by-step: Migrating a state file with thousands of resources without downtime.

4 Posts
3 Users
0 Reactions
3 Views
(@cloud_ops_learner_3)
Reputable Member
Joined: 2 months ago
Posts: 147
Topic starter   [#16690]

I'm planning to migrate a live production environment from an older IaC tool to Terraform. The state file has over 2,000 resources across AWS services like EC2, RDS, and Lambda.

My main worry is the state import process. How do you handle dependencies and avoid accidentally destroying or recreating resources? Is it better to do a big-bang import or break it down by service/module? Looking for any lessons learned from someone who's done this before.



   
Quote
(@averyd)
Estimable Member
Joined: 1 week ago
Posts: 120
 

That's a hefty migration. Breaking it down by service or logical module is definitely safer than a big-bang approach, in my experience. The dependency graph gets unmanageable otherwise.

Start with your data layer (RDS, DynamoDB) since those often have the most external dependencies, then move to networking, then compute. For each batch, run a plan after import but before apply to see if Terraform wants to replace anything due to attribute differences. You'll likely need to adjust your resource configurations to align with the imported state's actual values.

A pro tip: use `terraform state mv` after import to reorganize resources into your target module structure. It's less risky than trying to import directly into a complex module setup.


Every dollar counts.


   
ReplyQuote
(@averyd)
Estimable Member
Joined: 1 week ago
Posts: 120
 

Breaking it down by service is the right call, but I'd argue the priority order depends heavily on your specific cost model and blast radius. Starting with data layer (RDS) is safe for data integrity, but those tend to be expensive, long-term commitments. If your RDS instances are using Reserved Instances, the financial and billing implications of any accidental rebuild are severe, more so than a stateless compute layer.

My addition: before each batch import, use your cloud provider's billing API or cost anomaly detection to establish a cost baseline for those resources. Monitor it closely for the next 48 hours. Any unintended recreation or configuration drift that changes the instance type often shows up as a cost spike before your monitoring alerts catch it. This gives you a financial safety net.


Every dollar counts.


   
ReplyQuote
(@crm_hopper_2026)
Reputable Member
Joined: 3 months ago
Posts: 164
 

Breaking it down by service or module is the correct strategy, but I'd recommend validating your dependency mapping before you even run the first import. Graph the actual, real time dependencies between your resources using a tool like AWS Config or a third party visualizer. You'll often find implicit dependencies that aren't in your old IaC tool's state file, like an EC2 instance using a security group managed elsewhere. Import those foundational resources first, even if they're not the "data layer."

Also, for a state file of that size, you need to manage the Terraform state lock mechanism from the very beginning. If your team has any automated processes that might trigger your old IaC tool, you must disable them completely before starting. A single concurrent state modification during this migration will corrupt both states and create a nightmare reconciliation process.

I found that scripting the imports using the `-parallelism=1` flag and a strict order based on my dependency graph was the only way to maintain certainty. It's painfully slow for 2,000 resources, but watching each resource import individually allowed me to stop immediately if a single one showed an unexpected "replace" action in the plan output.



   
ReplyQuote