Sometimes you need to move the state of a site to another: switch from local to remote state, change buckets, reorganize your project, or merge configurations. State migration is a delicate but common operation, and it’s important to know how to do it properly to avoid losing or corrupting your “source of truth.” In this subchapter, we’ll see how to migrate state safely.

Why Migrate State

Remember that the state is the record of what infrastructure exists (Chapter 11). There are several real situations where you need to move it:

  • From local to remote: you started with local state (on your laptop) and now want to move it to a shared S3 backend (subchapter 20.1) to work as a team. This is the most common case.
  • Backend change: you move the state from one bucket to another, or from one system to another (for example, to Terraform Cloud, Chapter 22).
  • Project reorganization: you split a large project into several smaller ones, or merge several into one, which involves moving resources between states.

Migrating from Local to Remote (the Most Common)

This is the most frequent migration and, fortunately, Terraform makes it almost automatic. The process:

1. You have LOCAL state (terraform.tfstate in your folder)
2. ADD the remote backend configuration (backend "s3" block)
3. Run: terraform init
4. Terraform detects the change and asks:
   "Do you want to migrate the existing state to the new backend?" → yes
5. Done! The state now lives in S3

When you run terraform init after adding the backend, Terraform is smart enough to realize you have a local state and offers to copy it to the new destination:

Initializing the backend...
Do you want to copy existing state to the new backend?
  Pre-existing state was found while migrating the previous "local" backend
  to the newly configured "s3" backend. ...
  Enter "yes" to copy and "no" to start with an empty state.

You answer yes and Terraform copies the state to the remote backend. From then on, it works from S3.

Changing from One Remote Backend to Another

If you already have a remote backend and want to change it (for example, another bucket), the process is similar:

1. CHANGE the backend configuration (new bucket, new path...)
2. Run: terraform init -migrate-state
3. Terraform copies the state from the old backend to the new one

The -migrate-state option explicitly tells Terraform that you want to move the state to the new backend, not start from scratch.

Moving Specific Resources Between States

Sometimes you don’t want to move all the state, but specific resources from one project to another (for example, when splitting a large project). For this, there’s the terraform state mv command, which relocates a resource within the state or to another:

terraform state mv aws_instance.web  module.servers.aws_instance.web

This tells Terraform: “this resource now lives elsewhere in the state, but it’s the same real resource; don’t destroy or recreate it, just update its record.” It’s very useful when refactoring (for example, when moving loose resources into a module, Chapter 18).

Why state mv matters: without it, if you reorganize your code and Terraform “loses sight” of a resource, it might think it no longer exists and want to destroy it and create a new one. state mv avoids that mess: you tell it “it’s the same, it just changed name/location in the code.”

Golden Rules for Safe Migration

State migration touches your “source of truth,” so caution is essential. Always follow these rules:

  1. Make a Backup BEFORE

Before any migration, save a copy of the current state. If something goes wrong, you can restore it. If your S3 bucket has versioning enabled (subchapter 20.1), you already have that history, but an extra manual copy never hurts.

Before migrating:  copy the tfstate  →  safety net

  1. Notify the Team and Make Sure No One Else Is Working

During migration, no one else should be running Terraform on that state. Coordinate with your team (remember the locking from subchapter 20.2: migration also requires the state not to be in use).

  1. Verify with Plan After Migrating

After migration, run terraform plan. If the migration was correct, the plan should show “no changes” (No changes): this confirms that the new state reflects exactly the real infrastructure, without having lost or altered anything.

After migrating:  terraform plan
   → "No changes. Your infrastructure matches the configuration."  ✓ perfect
   → if it shows unexpected changes  ⚠️ something went wrong, investigate before applying

  1. Never Edit the State by Hand

The state file is a JSON, but do not edit it manually except in extreme emergencies and only if you really know what you’re doing. Always use Terraform commands (state mv, state rm, init -migrate-state), which know its internal structure and prevent corruption.

What You Should Remember

  • Migrating state (moving it elsewhere) is necessary when switching from local to remote, changing backend, or reorganizing the project.
  • Local → remote: add the backend block and run terraform init; Terraform detects the local state and offers to copy it (you answer yes). It’s almost automatic.
  • Remote → another remote: change the configuration and use terraform init -migrate-state.
  • To move specific resources within the state (when refactoring), use terraform state mv, which prevents Terraform from destroying and recreating a resource that only changed location in the code.
  • Golden rules: make a backup first, notify the team (no one else working), verify with plan after (should say “no changes”), and never edit the state by hand.

In the last subchapter of the chapter, we’ll see a very related and very useful operation: terraform import, to bring into the state resources that already exist in AWS but that Terraform does not yet manage.

Cloud, AWS & Terraform — From Zero to Expert

Chapter 1 · What is cloud computing

Chapter 2 · The cloud market and major providers

Chapter 3 · Regions, availability zones and edge

Chapter 4 · Compute: EC2

Chapter 5 · Storage: S3

Chapter 6 · Networking: VPC

Chapter 7 · Identity and access: IAM

Chapter 8 · Managed databases

Chapter 9 · Why Infrastructure as Code

Chapter 10 · HCL: the Terraform language

Chapter 11 · Providers and state

Chapter 12 · Your first real infrastructure in Terraform

Chapter 13 · Load balancing and auto scaling

Chapter 14 · Serverless with Lambda

Chapter 15 · Messaging and events

Chapter 16 · Content delivery and DNS

Chapter 17 · Containers on AWS

Chapter 18 · Modules: reuse and composition

Chapter 19 · Workspaces and environment management

Chapter 20 · Remote backends and locking

Chapter 21 · Infrastructure testing

Chapter 22 · Terraform in CI/CD

Chapter 23 · Defense in depth

Chapter 24 · Observability: logs, metrics and traces

Chapter 25 · Cost optimization

Chapter 26 · High availability and disaster recovery

Chapter 27 · AWS Well-Architected Framework

Chapter 28 · Serverless architectures at scale

Chapter 29 · Data platforms on AWS

Chapter 30 · Multi-account and landing zones

Chapter 31 · Platform Engineering and Internal Developer Platform

Chapter 32 · Relevant AWS certifications

Chapter 33 · Projects to consolidate what you've learned

Chapter 34 · Resources and community

© Copyright 2024. All rights reserved