90

.tfstate对于是否将文件提交到 Git的问题,我有点困惑。Terraform 文档指出:

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

现在,另一方面,关于使用 Terraform 时的最佳实践的已接受和赞成的答案指出:

Terraform 配置可用于在不同的基础设施上配置许多盒子,每个盒子都可以有不同的状态。因为它也可以由多人运行,所以这个状态应该在一个集中的位置(如 S3),而不是git。

(强调的是原作者,不是我)

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

4

4 回答 4

68

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

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

有关更多信息,请查看如何管理 Terraform 状态Terraform:启动和运行

于 2016-08-03T16:23:24.857 回答
59

TL;博士:

重要的!存储在源代码控制中可能会暴露潜在的敏感数据,并有针对旧版本状态运行 Terraform 的风险。不要这样做。

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

与本地和存储在源代码管理中相比,远程状态具有显着优势。这些细节如下。


原答案:

叶夫根尼的回答很好。随着 Terraform 更新了他们的文档以声明:

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

因此,既定的最佳实践与官方建议之间不再存在分歧。


2019-05-17 更新

最新版本的文档中,这已更改为:

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

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

尽管上面的文档引用远程状态仍然是一个单独的开发人员有益的

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

  • 从多个设备上处理/运行他们的 Terraform 代码
  • 轻松备份并防止丢失状态文件,具体取决于所选的后端
  • 通过输出分隔其架构的各个部分
  • 根据选择的后端自动加密静态文件
于 2017-01-05T10:18:59.413 回答
11

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

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

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

我想说 S3 可能是您现在可以放置它们的最佳位置。它几乎是免费的,持久性和可用性都非常好,在 Terraform 中使用远程状态资源对它有很好的原生支持。可能最重要的是,您只需创建一个 S3 存储桶即可开始使用。必须首先在没有 Terraform 的情况下构建Consuletcd集群(否则您会遇到先有鸡还是先有蛋的问题,即在哪里存储用于创建它们的状态?)即使您打算使用这些产品中的任何一个,也有点痛苦。

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

于 2016-07-21T06:59:08.990 回答
1

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

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

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

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

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

于 2018-03-26T10:23:16.440 回答