我的状态文件与地形文件一起保存。(我知道这不是理想的情况,但这就是我目前工作场所的情况。我们计划放弃这种状态管理模式)
我的分支的目标是创建一个adhoc-ec2
具有各种策略附件的新 ec2 实例(名为)。更改经过测试,因此 ec2 实例存在于开发环境中。
最后我的分支及其相关的 PR 已经经历了 PR 审核流程,状态文件已经在另一个分支中更新并合并到该master
分支中。
两个版本的文件之间的差异太大,无法手动协调。
根本原因当然是 terraform 文件包含太多资源,但现在撤消此问题已经太晚了。
现在我必须解决所有冲突,然后才能将我的分支合并到master
。
我尝试用以下方式解决冲突:
将我的分支重新定位到 master(这样我的 terraform 文件将包含所有最新的更改)
使用最新版本覆盖分支中的过时状态文件
master
运行
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.tfstate
master 分支后,告诉您的同事 master 分支已再次解冻,他们现在必须根据 master 重新定位所有待定分支,以确保他们测试的是最新状态。(这相当于手动解锁状态。)
如您所知,不建议将 Terraform 状态保留在版本控制中,因为这会阻止自动锁定,并造成开发人员是否在针对最新状态快照进行工作的不确定性。但如果您小心地保留 Terraform 所做的所有假设(如我上面所述),那么您应该能够相对安全地使用 Terraform,直到您能够过渡到使用远程状态的标准方法。