使用 terraform plan --refresh-only 检测漂移的资源时,该命令会返回一个计划,其中 1 个或多个资源在外部发生更改。它们都用空映射标记 tags
属性 {}
# aws_iam_role.lalala_poweruser has changed
~ resource "aws_iam_role" "lalala_poweruser" {
id = "lalala_poweruser"
name = "lalala_poweruser"
+ tags = {}
# (11 unchanged attributes hidden)
}
为了强调,+ Tags = {}
不应使用 +
符号进行标记,因为没有人在已部署的基础架构中更改此属性。
到目前为止我已经尝试过:
- 向每个资源添加带有空映射
{}
的属性 - 为每个资源添加真实标签的属性
- 将
defaults_tags
添加到提供程序配置
使用此命令检测偏差的最终目标是在部署新更改之前以编程方式检测 CICD 管道中的任何更改。如果存在真正的偏差,我们想知道,并且我们想停止这种部署。此外,此命令的一个有用之处是,当检测到真正的偏差时,它会返回差异,以便我们可以记录信息并采取行动。
Terraform 文档中有关此过程的更多信息:
最佳答案
在 Terraform 的架构中,提供者的职责之一是读取已在管理下的每个远程对象的当前状态,将其与最近应用的结果进行比较,并生成一个协调两者的新对象。
该职责的一部分是处理以下情况:值在 Terraform 中可能看起来不同,但就远程系统而言实际上是相同的。对于每个检测到的更改,提供商必须将其大致分为以下两类之一:
- “漂移”:远程系统状态与之前的运行状态在功能上存在显着差异。
- “标准化”:远程系统返回的一些数据的形状与之前返回的略有不同,但它仍然意味着相同的事情。一些典型的示例包括:不区分大小写的字符串(远程 API 始终以小写形式返回它们)或 JSON 字符串(无论输入如何,远程 API 始终返回缩小后的字符串)。
在您在此显示的情况下,该提供程序似乎没有进行正确的分类:tags = {}
和完全省略该参数之间没有功能差异,因此提供商应该将此归类为标准化,并保留您未设置它的事实,而不是将其报告为漂移。
您提到您已经尝试在配置中显式设置 tags = {}
,但这并没有解决问题。不幸的是,这表明提供程序中存在第二个相反的错误:在其创建/更新步骤中,它似乎将空映射规范化为与 null 相同,因此提供程序不同意关于这个论证的规范化形式是什么。如果这是真的,那么我认为您在 Terraform 模块中无法做任何事情来避免这个问题;唯一的办法是修复提供程序代码库中的错误。
AWS 提供商团队是 tracking various bugs of this type 。该问题表明提供商版本 v3.70.0 修复了许多此类错误,因此我建议您首先确保至少运行该版本。然而有a comment describing a similar problem with aws_iam_policy
,并且这两种资源类型密切相关,因此在这方面可能具有相同的错误。如果您已经在运行最新版本的提供程序,那么我认为这里最好的做法是通过向同一 GitHub 问题添加另一条评论来报告此问题,以便提供程序团队能够意识到这一点。
很抱歉,我没有只能在您的 Terraform 模块中实现的答案。
关于Terraform 计划 --refresh-only 返回 False Drift,部署的资源中带有空标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74043276/