如何缩短刷新Terraform状态所需的时间?

15

我工作的公司使用Terraform来描述和管理大部分AWS基础设施。

我们有几个不同的服务,包括容器化的后端和CDN加速的前端。

从Route53域名和命名空间到ELBs、ECS和CloudFront,都有很多事情要处理。

目前遇到的一个问题是,由于Route53 DNS的原因,检查、刷新和验证Terraform状态需要很长时间。

我们正在解决的问题是:

如何大幅缩短刷新/检查tf state所需的时间?

将其移动到单独的存储库中似乎不是一个好主意,因为那样会使所有与Route53相关的变量无法访问或者可能过时。


4
你的Terraform配置是否全部放在一个地方?最佳实践表明,你应该将它们分开,只将需要同时应用的内容分组,以最小化影响范围,使并发更易于变更而不破坏状态,并减少Terraform刷新和构建依赖图所需的时间。 - ydaetskcoR
一个计划需要多少资源(以每行输出的1个资源为单位),需要多长时间?例如:我有250多个资源,其中大约20个是route53相关的 - 进行计划需要不到20秒。你看到的时间与这个差不多吗? - Shorn
@ydaetskcoR 我们有一个单一的代码库来描述整个公司的基础设施。有不同的.tf文件,根据我们的逻辑来组织资源。但它们仍然被“一次性”读取。 - Jonathan Soifer
@Shorn,我需要将我的数据与你的进行比较,感谢你提供它。尽管我们拥有的Route53资源数量至少比你们多一个数量级。 - Jonathan Soifer
3
单一代码库是可以的,但通常只有在需要同时应用时才将.tf文件放在同一个目录中。然后,您应该按照在Stackoverflow上提到的其他Terraform项目结构问题所述的方式拆分您的目录结构。 - ydaetskcoR
状态存储在哪里?如果您将其存储在S3上,可以使用优化IO存储桶,并将基础架构拆分为组件。为了尽可能少地访问状态,您可以将状态输出存储在SSM参数存储中。如果您将输出保留在SSM上,则很少访问状态,运行速度更快。如果您有多个帐户,还可以将状态放在不同的存储桶中,并启用跨帐户访问以使用远程状态之间进行通信。 - victor m
2个回答

6
我来到这里是因为我正在研究一个类似的问题。看起来TF在图遍历方面做得很糟糕,所以你的东西越相互关联,它的性能就越差。我有一个由2300个资源组成的线团,在具有足够内存和处理器以并行度10运行而不会达到峰值的机器上,规划需要49分钟。其中三分之一的时间用于刷新状态,由于受AWS CLI调用的限制,这可能无法缩短。但是,在状态刷新之前和之后花费的三分之一似乎主要是TF在图中胡闹(根据日志)。
我找到了一些讨论,似乎表明您的代码结构可能会极大地影响计划时间,特别是使用for_each(链接#1#2)。由于我的代码库大量使用它,我觉得这很有意思。你的情况可能有所不同;)

2
哦,显然,如果您可以通过拆分堆栈来减小其大小,那么您应该看到规划时间的超线性减少,但我猜来这里的人已经尝试过了;) - mhvelplund

4

你应该将状态分解为组成部分的子状态,这些子状态具有合理的逻辑区分,比如“前端”,“缓存”或者根据公司组织和分类基础设施的方式进行分类。

在使变量可访问方面,你可以声明其他状态作为数据源并从中提取(假设它们对你感兴趣的值具有有效的输出)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接