在Terraform中,是否可能将状态从一个工作区移动到另一个工作区?

20

一开始我使用的是默认工作区。由于增加了更多复杂性,我想要使用多个工作区。我希望将默认工作区中的内容移动到它自己的工作区或将默认工作区重命名为另一个工作区。我该怎么做?

4个回答

45

是的,可以在工作区之间迁移状态。

我假设您正在使用 S3 远程 backend 和 terraform 版本 >= 0.13。让我们看看这个状态转换是什么样子:

需要在工作区之间迁移的示例资源配置:

provider "local" {
  version = "2.1.0"
}

resource "local_file" "foo" {
  content  = "foo!"
  filename = "foo.bar"
}

terraform {
  backend "s3" {
    bucket         = ""
    region         = ""
    kms_key_id     = ""
    encrypt        = ""
    key            = ""
    dynamodb_table = ""
  }
}

让我们初始化默认工作区的后端并执行apply操作:

terraform init
<Initialize the backend>

terraform workspace list
* default

terraform apply
local_file.foo: Refreshing state... [id=<>]

Apply complete! Resources: 0 added, 0 changed, 0 destroyed

如您所见,本地文件已经创建并且状态存储在默认工作区。Terraform apply 没有改变任何内容。

现在,我们想要迁移到一个新的工作区:

当您仍在默认工作区时,拉取状态。

terraform state pull > default.tfstate

创建一个新的工作区;我们称其为test
terraform workspace new test
Created and switched to workspace "test"!

如果您尝试运行terraform state list,您不应该看到任何状态。

让我们将状态推送到新创建的工作区,并查看状态中的内容;还要查看在执行apply时会发生什么。

terraform state push default.tfstate

terraform state list
local_file.foo

terraform apply
local_file.foo: Refreshing state... [id=<>]

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

您的local_file.foo已迁移到test工作区。

别忘了切换回default工作区并删除此文件的状态引用。

terraform workspace select default
terraform state rm local_file.foo
Removed local_file.foo
Successfully removed 1 resource instance(s).

PS:我强烈建议您阅读更多关于管理Terraform状态的内容。


3
若您拥有较大规模的状态(state),可使用此命令清理 default 中的无用信息: terraform state list | xargs -n 1 terraform state rm - Alan Cabrera

5

之前的所有答案对我来说都不起作用,每次新的工作区都是空的,正如应该的一样。为了填充它,您需要根据文档使用-state

https://www.terraform.io/cli/commands/workspace/new

所以成功的方法:

  • 创建本地备份:terraform state pull > default.tfstate
  • 通过注释后端块并执行terraform init -migrate-state切换到本地
  • 使用terraform workspace new -state=default.tfstate newspace创建新的工作区。这将把default复制到newspace
  • 运行terraform plan进行检查
  • 取消后端块的注释以切换回云端,然后运行terraform init -migrate-state 将新的工作区迁移到云端
  • 运行terraform planterraform workspace list进行检查。

3
这里提供一种与默认答案略微不同的逐步操作方法。
首先,我们有一个默认的s3后端。
terraform {
  backend "s3" {
    encrypt        = true
    bucket         = "cool-bucket-name"
    key            = "production/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "cool-dynamo-db-lock-name"
  }
}

现在,检查我们的工作区。

terraform workspace list

  default  
* weird-workspace-name

通过首先注释掉terraform后端来拉下状态。

#terraform {
#  backend "s3" {
#    encrypt        = true
#    bucket         = "cool-bucket-name"
#    key            = "production/terraform.tfstate"
#    region         = "us-east-1"
#    dynamodb_table = "cool-dynamo-db-lock-name"
#  }
#}

运行命令在本地迁移状态。

terraform init -migrate-state

您可以检查状态并查看是否仍然可以继续。

terraform apply

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

接下来,获取状态。状态文件的名称由您最初给定的键决定。
terraform workspace new cool-workspace-name

terraform state push terraform.tfstate

terraform apply

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

好的,现在去清理你的旧状态。

terraform workspace select weird-workspace-name

terraform state list | cut -f 1 -d '[' | xargs -L 0 terraform state rm

terraform workspace select cool-workspace-name

terraform workspace delete weird-workspace-name

再次运行terraform apply命令。

terraform apply

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

现在将您的状态移回到S3中,取消注释terraform backend.tf文件。

terraform {
  backend "s3" {
    encrypt        = true
    bucket         = "cool-bucket-name"
    key            = "production/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "cool-dynamo-db-lock-name"
  }
}

运行:

terraform init -migrate-state

我非常感激bhalothia的回答,我只想添加另一个逐步说明,这是一个略有不同的情况。


0

根据后端的不同,Terraform 可能能够自行完成迁移。

为此,只需在 terraform 块中更新您的后端配置,然后运行以下命令以自动迁移状态:

terraform init -migrate-state

这样做将会复制所有从旧的定义到新的工作区的状态。

我可以确认在 Terraform Cloud 上运行良好,即使使用前缀定义了多个工作区。


问题是关于将状态从“native”工作区移动到另一个工作区,而不是关于将状态从一个后端迁移到另一个后端。 - LoganMzz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接