Terraform 在计划中显示将销毁/替换资源,但实际上只是创建在旁边

42次阅读
没有评论

问题描述

在使用 Terraform 模块时遇到了一个问题。在创建一个 Web 应用程序的同时,模块会将其 URL 插入到 Azure App Configuration 中,用于 API 网关。在开发过程中,用户对一些设置进行了更改,并希望 Terraform 能够跟踪这些更改并做出相应的修改,就像 plan 命令所显示的那样。然而,实际上 Terraform 只是在已有的密钥旁边创建了新的密钥,并没有进行替换。用户想知道这是一个 bug 吗?还是他在操作上存在问题?以下是他在 Terraform 配置文件中的一部分代码:

resource "azurerm_app_configuration_key" "Ocelot_downstream" {
  for_each               = toset(var.az_app_config.ocelot_indexes)
  configuration_store_id = data.azurerm_app_configuration.app_config.id
  key                    = "Ocelot/Routes:${each.value}:DownstreamHostAndPorts:0:host"
  label                  = "Ocelot Downstream URL override ${azurerm_linux_web_app.webapp.name}"
  value                  = azurerm_dns_cname_record.cname.fqdn
}

解决方案

以下解决方案假设你已经熟悉 Terraform 的基本概念和使用方法。如果你是初学者,请确保在操作前进行适当的学习和测试。

步骤1:了解问题

首先,让我们理解问题的本质。根据你的描述,Terraform 在计划中显示将要替换资源,但实际上只是创建了新的资源。这可能是因为资源的标识符在某种程度上发生了变化,导致 Terraform 认为需要替换而不是修改资源。我们需要仔细查看资源标识符以及 Terraform 计划的输出,以便更好地理解发生了什么。

步骤2:检查资源标识符

首先,确保在资源定义中使用的唯一标识符是稳定的,并且不会因为设置的更改而发生变化。在你的情况下,你使用了 for_each 来为每个资源创建多个实例。确保 var.az_app_config.ocelot_indexes 变量的值在不同的计划之间保持一致,以便 Terraform 能够正确地识别资源并进行修改。

步骤3:查看 Terraform 计划

运行以下命令来查看 Terraform 的详细计划:

terraform plan

在输出中,注意资源的计划操作。如果资源的计划操作是 replace 而不是 modify,则说明 Terraform 认为需要替换资源。在你的情况下,可能是资源标识符或其他配置发生了变化,导致 Terraform 认为需要创建新的资源。

步骤4:审查资源变更

如果计划操作是 replace,请仔细审查计划输出,查看哪些属性发生了变化。这将帮助你理解为什么 Terraform 认为需要替换资源。根据这些变化,你可以考虑采取以下措施:
– 如果只是一些次要的属性发生了变化,你可以尝试手动更新这些属性,然后重新运行 Terraform 命令,看是否会将资源修改为预期状态。
– 如果变化比较大,可能需要考虑先销毁资源,然后重新创建以适应新的设置。

步骤5:备份并执行更改

在尝试更改之前,请确保对你的配置文件进行了备份,以防出现意外情况。如果你认为某些设置可能会导致资源替换,可以先尝试在非生产环境中进行测试。

总结

通过仔细检查资源标识符、审查 Terraform 计划和了解资源属性的变化,你可以更好地理解为什么 Terraform 会执行替换操作而不是修改操作。根据发现的问题,你可以尝试手动修改属性或者在备份的前提下进行实验性的更改,以达到预期的结果。如果你发现问题仍然存在,可能需要进一步研究 Terraform 的文档或寻求社区的帮助,以解决这个问题。

正文完