当状态文件保存在git中时,如何解决状态文件版本冲突?

当状态文件保存在git中时,如何解决状态文件版本冲突?

我的状态文件与地形文件一起保存。(我知道这不是理想的情况,但这就是我目前工作场所的情况。我们计划放弃这种状态管理模式)

我的分支的目标是创建一个adhoc-ec2具有各种策略附件的新 ec2 实例(名为)。更改经过测试,因此 ec2 实例存在于开发环境中。

最后我的分支及其相关的 PR 已经经历了 PR 审核流程,状态文件已经在另一个分支中更新并合并到该master分支中。

两个版本的文件之间的差异太大,无法手动协调。

根本原因当然是 terraform 文件包含太多资源,但现在撤消此问题已经太晚了。

现在我必须解决所有冲突,然后才能将我的分支合并到master

我尝试用以下方式解决冲突:

  1. 将我的分支重新定位到 master(这样我的 terraform 文件将包含所有最新的更改)

  2. 使用最新版本覆盖分支中的过时状态文件master

  3. 运行terraform refresh以尝试同步状态文件和 AWS 环境的实际资源。

但是显然这个计划行不通。因为当我terraform plan随后立即运行时,计划显示 terrafrom 仍然想要创建 ec2 实例adhoc-ec2(正如我之前在这个问题中提到的,该实例已经创建)

或者,我可以销毁具有所有依赖角色和策略的 ec2 实例,但这很耗时。

有没有更简单的方法来解决这种状态文件冲突?为什么refresh一开始就不起作用?

答案1

运行terraform refresh将仅更新状态文件中已有的资源,因此如果您的实例在状态文件中尚不存在,Terraform 仍会创建它。

您应该做的是terraform import根据 AWS API 的返回内容将资源添加到状态文件中,然后该文件应该与您的清单中的内容相匹配。

答案2

Terraform 的工作流不支持通过拉取请求共享对状态的更改,除非您可以保证一次只有一个拉取请求处于待处理状态。Terraform 期望,一旦它更新了状态文件,新文件将立即可供所有后续 Terraform 运行使用。

为了更好地近似标准 Terraform 工作流程(具有远程状态),我建议按如下方式修改您的方法:

  • 当你在开发一个改变时,用它terraform plan来看看它的效果会是什么,但是不要應用它。
  • 对更改满意后,请提交 PR,包括仅有的配置更改。由于更改尚未应用,因此没有状态快照更新可包含在此 PR 中。
  • 审查并合并更改后,以某种方式告知您的同事,master在您应用更改时,分支暂时冻结。(这是 Terraform 通常使用远程后端自动处理的锁定的手动版本。)
  • terraform apply针对已合并更改的主分支运行,并创建包含terraform.tfstate更新的新提交。将其直接推送到master分支,绕过拉取请求,因为这只是已审核的更改的效果。(master即使terraform apply没有成功,也必须将新状态推送到分支,因为您需要打开新的 PR 来响应任何错误,但您需要确保在此期间运行 Terraform 的任何其他人都能看到部分更新的状态。)
  • 将更新推送到terraform.tfstatemaster 分支后,告诉您的同事 master 分支已再次解冻,他们现在必须根据 master 重新定位所有待定分支,以确保他们测试的是最新状态。(这相当于手动解锁状态。)

如您所知,不建议将 Terraform 状态保留在版本控制中,因为这会阻止自动锁定,并造成开发人员是否在针对最新状态快照进行工作的不确定性。但如果您小心地保留 Terraform 所做的所有假设(如我上面所述),那么您应该能够相对安全地使用 Terraform,直到您能够过渡到使用远程状态的标准方法。

相关内容