我应该将.tfstate文件提交给Git吗?

Gol*_*den 63 terraform devops

关于是否将.tfstate文件提交到Git 的问题,我有点疑惑.该Terraform文档状态:

Terraform terraform.tfstate默认情况下也会将一些状态放入文件中.这个状态文件非常重要; 它将各种资源元数据映射到实际资源ID,以便Terraform知道它正在管理什么.必须保存此文件并将其分发给可能运行Terraform的任何人.我们建议简单地将其置于版本控制中,因为它通常不会太大.

另一方面,现在,使用Terraform时最佳实践的接受和赞成回答如下:

Terraform配置可用于在不同的基础架构上配置多个盒子,每个盒子可以具有不同的状态.由于它也可以由多个人运行,因此该状态应该位于集中位置(如S3),而不是 git.

(原作者的重点,而不是我)

谁是对的,如果是的话,为什么?

Yev*_*man 51

有几个原因不将.tfstate文件存储在Git中:

  1. 您可能会忘记在运行后提交并推送更改terraform apply,因此您的队友将拥有过时的.tfstate文件.此外,如果没有对这些状态文件进行任何锁定,如果两个团队成员同时在同一.tfstate文件上运行Terraform,则可能会覆盖彼此的更改.您可以通过以下两种方法解决这两个问题:a).tfstate使用Terraform远程状态将文件存储在S3存储桶中,.tfstate每次运行时都会自动推送/拉取文件terraform apply; b)使用terragrunt等工具为.tfstate文件提供锁定.
  2. 这些.tfstate文件可能包含秘密.例如,如果使用aws_db_instance资源,则必须指定数据库密码,Terraform将以明文形式将其存储在.tfstate文件中.这是Terraform代表的一个不好的做法,开始并在版本控制中存储未加密的秘密只会使情况变得更糟.至少如果您.tfstate在S3中存储文件,您可以在静止时启用加密(SSL在运动时提供加密)并配置IAM策略以限制谁有权访问.这是非常不理想的,我们将不得不看看是否有关于它的讨论公开问题得到解决.

有关详细信息,请查看如何管理Terraform状态Terraform:Up&Running.

  • 以下是另一个理由/方式:将TF + Git视为使用版本控制的软件开发.在这种情况下,您不会将构建工件(即状态文件)存储在VC存储库中,而是存储在中央工件存储库(例如S3存储桶)中. (6认同)
  • 您不再需要Terragrunt提供锁定。现在它已内置到Terraform中:https://www.terraform.io/docs/state/locking.html (2认同)

Tom*_*eld 35

Yevgeniy的答案很好.由于Terraform已将其文档更新为州,因此该问题现在的争议较少:

Terraform默认情况下也会将某些状态放入terraform.tfstate文件中.这个状态文件非常重要; 它将各种资源元数据映射到实际资源ID,以便Terraform知道它正在管理什么.必须保存此文件并将其分发给可能运行Terraform的任何人.通常建议在使用Terraform时设置远程状态.这将意味着存储在状态文件中的任何潜在秘密都不会被检入版本控制

因此,已建立的最佳做法与官方建议之间不再存在分歧.


yda*_*coR 8

这可能会归结为首选,但我会说git(或任何其他源代码控制)不是存储状态文件的特别好的选项,因为它们是你编写的代码的输出,就像编译的二进制文件甚至最小化JS或LESS编译为CSS.

最重要的是,状态文件中的事情可能会相当快速地变化,作为正在运行的事物的输出,而不是代码中的实际更改,这使整个事情变得相当尴尬.

但是,如果您在不同的笔记本电脑/机器上进行开发,则需要某种方式与任何远程团队成员或甚至其他设备共享这些状态文件.您还需要一些方法来存储和备份它们,因为如果丢失状态文件,您将会有一些真正的痛苦,因为Terraform使用状态文件来计算它正在管理的内容,以免踩到脚趾其他工具.

我会说S3可能是你现在最好的地方.它几乎是免费的,耐用性非常好,因为可用性,使用远程状态资源在Terraform中有非常好的原生支持.最重要的是,您只需要创建一个S3存储桶即可开始使用.必须首先建立Consuletcd集群而不使用Terraform(否则你有鸡和蛋的问题,你在哪里存储创建它们的状态?)即使你打算使用这些产品中的任何一个,也会有点痛苦.

显然,如果你正在使用OpenStack,那么Swift应该是一个很好的选择(虽然我没有使用它).我也没有使用过Hashicorp的Atlas,但是如果你很乐意为这项服务付费,它可能同样有用.


Mak*_*hev 7

我发现通过其他方式(而不是 Git)共享terraform.tfstate具有优势。

例如:S3、Dropbox 等(版本控制打开)

然后就可以回滚到之前的基础设施状态。

例如,您从提交 B 回滚存储库,回到提交 A。如果terraform.tfstate未更改 - terraform 将考虑如何回滚您在提交 B 期间添加的所有内容。并且回滚将很容易。

如果terraform.tfstate也回滚到提交 A - 那么 terraform 会认为terraform.tfstate与所需的配置同步,并且不会将回滚应用到您的基础设施。