【问题标题】:What does terraform refresh really do?terraform refresh 到底有什么作用?
【发布时间】:2017-07-26 12:02:54
【问题描述】:

在使用 terraform 在 AWS 中部署相当大的基础设施时,我们的远程 tfstate 已损坏并被删除。

从文档中,我收集到 terraform refresh 应该查询 AWS 以获取基础设施的真实状态并相应地更新 tfstate,但这并没有发生:我的 tfstate 没有受到影响,plan + apply 提供了很多 @987654323 @错误。

terraform refresh 到底是做什么的?

【问题讨论】:

    标签: amazon-web-services terraform


    【解决方案1】:

    terraform refresh 尝试查找状态文件中保存的任何资源,并更新自上次运行以来在 Terraform 之外的提供程序中发生的任何偏差。

    例如,假设您的状态文件包含 3 个 EC2 实例,实例 ID 为 i-abc123i-abc124i-abc125,然后您在 Terraform 之外删除了 i-abc124。在运行terraform refresh 之后,plan 将显示它需要创建第二个实例,而销毁计划将显示它只需要销毁第一个和第三个实例(并且不会破坏丢失的第二个实例)。

    Terraform 做出了一个非常具体的决定,即不干预不受 Terraform 管理的事物。这意味着如果资源在其状态文件中不存在,那么它绝对不会以任何方式触及它。这使您能够与其他工具一起运行 Terraform,并在 AWS 控制台中进行手动更改。这也意味着您可以通过提供不同的状态文件来在不同的上下文中运行 Terraform,从而允许您将基础架构拆分为多个状态文件并避免灾难性的状态文件损坏。

    为了让自己摆脱当前的困境,我建议您大量使用 terraform import 将内容恢复到您的状态文件中,或者如果可能的话,手动销毁 Terraform 之外的所有内容并从头开始。

    以后我会建议拆分状态文件以应用更精细的上下文,并将您的远程状态存储在启用版本控制的 S3 存储桶中。您还可以使用 Terragrunt 之类的工具来锁定您的状态文件,以帮助避免损坏或等待即将发布的 0.9 版本的 Terraform 中的本机状态文件锁定。

    【讨论】:

    • 感谢您清晰详细的回答。事实上,我们将 tfstate 保存在 S3 存储桶中,可惜没有版本控制。正如您建议的那样,我们手动销毁了所有内容,启用了 s3 版本控制并在几天前再次运行 terraform apply。我提出这个问题是为了更好地了解造成非常危急情况的根本原因。
    • 我注意到terraform refreshoutputs 进行了更改。这是它应该做的吗?如何防止它对其进行更改?
    【解决方案2】:

    计划-> 在上述场景中,当第二个 EC2 实例被删除并且您再次尝试使用 terraform plan 时,它确实会刷新 terraform 状态,但会在计划之前在内存中。 刷新状态将用于计算此计划,但不会 保存在本地或远程状态存储中。

    刷新-> 但是如果我单独运行terraform refresh,那么它实际上会刷新本地或远程状态存储中存在的状态文件。

    希望您现在得到答案...

    【讨论】:

      【解决方案3】:

      我知道这对聚会来说有点晚了,但在我最近与 terraform 打交道时,我读到它仍然保留一个本地状态文件 tfstate.backup,以防远程状态文件损坏。貌似我没试过,你可以terraform state push,它会将备份推送到远程。

      干杯

      【讨论】:

        【解决方案4】:

        @Philip 看来我是最后一个,继续回答您的问题。

        直到您来到这里,您已经知道 Terraform 刷新会针对任何真实世界的漂移更新本地状态,并与您的 terraform 模板中的实际基础设施进行比较。

        然后,Terraform 将放弃不属于您所需配置的内容。

        例如: 1.) 具有 1 条规则的所需 SG,有人手动将另一条规则添加到 SG。 2)您运行 Terraform Refresh 或 Plan,Terraform 说明,然后在您的远程或本地状态下运行并相应地生成一个计划。 3.) 然后在您接下来应用它来删除手动添加的更改。

        但如果您想保留这些手动更改,则需要使用 ignore_changes 向您的资源添加生命周期块。

        例如:

        resource "aws_security_group" "default" {
           lifecycle {
             ignore_changes = [ingress]
           }
        

        }

        【讨论】:

          猜你喜欢
          • 2021-10-30
          • 2011-04-18
          • 2019-11-03
          • 2010-10-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-02-16
          相关资源
          最近更新 更多