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

时间:2016-07-20 16:48:00

标签: devops terraform

关于是否将.tfstate文件提交给Git,我有点疑惑。 Terraform documentation州:

  

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

现在,另一方面,Best practices when using Terraform州的接受和赞成的回答是:

  

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

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

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

4 个答案:

答案 0 :(得分:45)

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

  1. 运行terraform apply后,您可能会忘记提交并推送更改,因此您的队友将拥有过时的.tfstate个文件。此外,如果没有对这些状态文件进行任何锁定,如果两个团队成员同时在相同的.tfstate文件上运行Terraform,则可能会覆盖彼此的更改。您可以通过以下方法解决这两个问题:a)使用Terraform remote state.tfstate文件存储在S3存储桶中,每次运行.tfstate时都会自动推送/提取terraform apply个文件b)使用terragrunt之类的工具为.tfstate文件提供锁定。
  2. .tfstate个文件可能包含机密。例如,如果使用aws_db_instance资源,则必须指定数据库密码,Terraform将以明文形式存储在.tfstate文件中。这是Terraform代表的一个不好的做法,开始并在版本控制中存储未加密的秘密只会使情况变得更糟。至少如果您在S3中存储.tfstate个文件,则可以在静止时启用加密(SSL在运动时提供加密)并配置IAM策略以限制谁有权访问。这与理想情况相差甚远,我们必须看看有关它的open issue discussing this problem是否得到修复。
  3. 有关详细信息,请查看How to manage Terraform state Terraform: Up & Running

答案 1 :(得分:28)

<强> TL; DR:

重要! 在源代码管理中存储可能会暴露potentially sensitive data并冒着针对旧版本状态运行Terraform的风险。不要这样做。

Terraform不再建议在源代码管理中存储状态。您的“好”选项是远程或本地的。

远程状态对源控制中的本地和存储都有很大的好处。详情如下。

原始回答:

Yevgeniy的答案很好。由于Terraform已将其文档更新为州:

,因此该问题现在的争议较少
  

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

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

更新2019-05-17

the most recent version of the docs中,这已被更改为:

  

...此状态默认存储在名为的本地文件中   “terraform.tfstate”,但它也可以远程存储,这是有效的   在团队环境中更好。 ...

我不希望这些建议会恢复为源控制是存储状态的首选方法。

尽管上面的文档引用远程状态作为独立开发者仍然是有益的

远程状态允许独奏开发者:

答案 2 :(得分:8)

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

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

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

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

显然,如果您正在使用OpenStack,那么Swift应该是一个不错的选择(尽管我还没有使用它)。我还没有使用过Hashicorp的Atlas,但如果您愿意为该服务付费,那么它可能同样有用。

答案 3 :(得分:-1)

我看到通过其他方式分享 terraform.tfstate 的优势,而不是Git。

例如S3,Dropbox等..(打开版本控制)

然后可以回滚到以前的基础架构状态。

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

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