1. 简介

Terraform 工作区使用相同的配置来管理对应的资源。但每个工作区拥有独立的状态文件(state file)。这就带来一个问题:如果我们想在非原始工作区中管理某个资源,是否可以将状态从一个工作区迁移到另一个?

本文将通过实际操作演示如何在 Terraform 工作区之间迁移状态,帮助你在多环境或多团队协作中更灵活地管理资源状态。


2. 创建资源

为了演示状态迁移,我们先创建一个简单的资源。

创建一个名为 baeldung.tf 的文件,内容如下:

provider "aws" {
  region = "us-east-1"
}

resource "aws_instance" "baeldung" {
  instance_type               = "t2.micro"
  ami                         = "ami-0574da719dca65348"
  associate_public_ip_address = true
}

接着执行初始化和部署:

$ terraform init && terraform apply -auto-approve

输出内容略(与原文一致),最终显示资源创建成功。

此时我们没有显式创建或切换工作区,因此所有操作都在默认工作区 default 中进行。

确认当前工作区:

$ terraform workspace show
default

3. 使用 terraform state pull 下载状态文件

既然我们已经在默认工作区创建了资源,现在可以尝试将状态迁移到另一个工作区。

如果状态文件存储在远程(如 S3),我们需要先将其拉取到本地。使用命令:

$ terraform state pull > baeldung.tfstate

验证文件是否下载成功:

$ ls baeldung.tfstate
baeldung.tfstate

⚠️ 如果是本地状态(默认为 terraform.tfstate),则无需手动下载。


4. 使用指定状态文件初始化目标工作区

接下来,我们创建一个新的工作区,并使用刚刚下载的状态文件初始化它。

执行命令:

$ terraform workspace new -state=baeldung.tfstate ws2
Created and switched to workspace "ws2"!

✅ 该命令不仅创建了新工作区 ws2,还自动切换到了该工作区,并加载了指定的状态文件。

注意:-state 参数指定的状态文件必须存在且格式正确。


5. 执行 terraform plan 验证迁移效果

5.1 检查目标工作区状态

ws2 工作区运行:

$ terraform plan

输出:

aws_instance.baeldung: Refreshing state... [id=i-05b783b91246bf8b3]
No changes. Your infrastructure matches the configuration.

说明状态迁移成功,ws2default 拥有相同状态,且都能识别该资源。

5.2 在工作区中修改配置并规划变更

现在我们修改资源配置,比如将资源名称改为 baeldung2

resource "aws_instance" "baeldung2" {
  instance_type               = "t2.micro"
  ami                         = "ami-0574da719dca65348"
  associate_public_ip_address = true
}

再次运行 terraform plan

$ terraform plan

输出:

aws_instance.baeldung: Refreshing state... [id=i-05b783b91246bf8b3]
...
Terraform will perform the following actions:

  # aws_instance.baeldung will be destroyed
  # (because aws_instance.baeldung is not in configuration)

  # aws_instance.baeldung2 will be created
...
Plan: 1 to add, 0 to change, 1 to destroy.

这说明 ws2 正在基于当前状态进行规划,并准备将旧资源删除、创建新资源。

5.3 应用变更并检查默认工作区状态

执行:

$ terraform apply -auto-approve

资源 baeldung 被删除,新资源 baeldung2 被创建。

现在切换回 default 工作区并执行:

$ terraform workspace select default && terraform plan

输出:

Terraform will perform the following actions:

  # aws_instance.baeldung2 will be created
...
Plan: 1 to add, 0 to change, 0 to destroy.

说明 default 工作区的状态已与实际资源不同步。这正是迁移状态后需要注意的地方:两个工作区虽然拥有相同状态,但一旦其中一个修改了配置,另一个将无法正确识别资源状态。


6. 小结与注意事项

要点 说明
✅ 状态迁移方式 使用 terraform state pull 获取状态文件,再通过 terraform workspace new -state=xxx 初始化新工作区
✅ 工作区切换命令 terraform workspace select <name>
⚠️ 状态一致性 两个工作区共享同一状态时,资源状态一致,但一旦修改配置,状态将不同步
⚠️ 风险提示 状态迁移后,多个工作区控制同一资源,容易导致状态冲突,建议仅在必要场景下使用

7. 总结

本文介绍了如何在 Terraform 中将状态从一个工作区迁移到另一个工作区。核心步骤包括:

  1. 使用 terraform state pull 获取状态文件;
  2. 使用 terraform workspace new -state=xxx 创建新工作区并加载状态;
  3. 通过 terraform planapply 验证状态迁移效果;
  4. 注意状态同步和潜在冲突问题。

状态迁移是一个强大但需谨慎使用的功能,适合用于资源所有权转移、测试环境迁移等场景。使用时务必注意状态一致性,避免造成资源误删或重复创建。


原始标题:How to Migrate States Between Workspaces in Terraform