Terraform - 重构模块:错误:提供程序配置不存在。

78

我正在重构一些 Terraform 模块,但出现了以下问题:

Error: Provider configuration not present

To work with
module.my_module.some_resource.resource_name its
original provider configuration at
module.my_module.provider.some_provider.provider_name is required, but it
has been removed. This occurs when a provider configuration is removed while
objects created by that provider still exist in the state. Re-add the provider
configuration to destroy
module.my_module.some_resource.resource_name, after
which you can remove the provider configuration again.

看起来我需要从tfstate文件中删除该资源,然后使用新的tf配置重新添加它。

当我重构一些单块代码时,有数百个这样的 Error: Provider configuration not present 消息。

有什么快捷方式可以进行删除和重新添加吗?


4
如果您不需要处理资源的存在,则可以使用以下命令直接修改状态:terraform state rm module.my_module.some_resource.resource_name - Ikar Pohorský
这篇 HashiCorp 故障排除文章提供了两种情况及其解决方案。https://support.hashicorp.com/hc/en-us/articles/1500000332721-Error-Provider-configuration-not-present - Dayong
6个回答

82
正如错误消息所解释的那样,Terraform检测到状态中仍存在资源对象,其提供程序配置不可用,因此它没有足够的信息来销毁这些资源。
在这种特殊情况下,似乎是因为其中一个子模块中有一个provider配置块。虽然这是兼容旧版本Terraform的,但建议只在根模块中放置provider,以便它们始终可以超过提供程序正在管理的任何资源实例。
如果您的意图是销毁module.my_module中的资源实例,那么您必须在从根模块中删除module "my_module"块之前这样做。这是一种不寻常的情况,我们可以使用-target来帮助Terraform理解我们想要它执行的操作:
terraform destroy -target=module.my_module

一旦所有这些对象都被销毁,您就应该能够删除module "my_module"块,而不会看到“Provider configuration not present”错误,因为状态中不会有依赖于该提供程序配置的资源实例。
如果您的目标是将资源块移动到另一个模块中,则另一个可能的解决方案是使用terraform state mv指示Terraform在新地址下跟踪现有对象。
terraform state mv 'module.my_module.some_resource.resource_name' 'module.other_module.some_resource.resource_name'

再次强调,最好在删除旧模块之前进行此操作,以便旧提供程序配置保持存在,直到没有任何东西需要其管理为止。将现有对象移到状态中的新模块中,并在配置中放置一个“resource”块后,Terraform应该能够理解您的意图,从现在开始使用不同的提供程序配置来管理此资源,并且您可以安全地删除旧的“module”块,因此也会删除其中的“provider”块。

4
terraform mv 命令现在改为 terraform state mv。请参阅 https://www.terraform.io/docs/commands/state/mv.html。 - mmell
3
"-target" 标志是我所需要的,你救了我。 - Lokesh
如果我们想保留资源不变,而只是使用不同的提供商怎么办?我还没有找到其他解决方法,除了手动编辑状态文件。 - apottere

7

在将 Terraform v0.12 升级到 v0.13 后,我开始出现了“Provider configuration not present”错误。

遵循 显式提供程序源位置 以与 Terraform v0.13 对齐可能是正确的方法,但在此期间降级到v0.12已经解决了该问题。


7

如果您想销毁模块中的资源,可以在模块中暂时注释掉这些资源,重新创建时取消注释,然后按照以下步骤避免错误。

从该模块中删除提供程序,并明确将提供程序传递给该模块。

module "pass_provider" {
  source = "../module"
   providers = {
    aws = aws
  }
}

使用别名传递密码提供程序。

module "pass_provider_alias" {
  source = "../module"

   providers = {
    aws = "aws.alias_name"
  }
}

3

这应该更高排名。这是我个人情况的真正原因。 - MatthewMartin
未来的人们:即使没有任何更改,请运行terraform plan和apply。这样可以强制更新状态文件的tf版本,然后误导性的错误就会消失。 - MatthewMartin

3
如果你注释掉/移除了一个模块,然后看到这个错误,那么另一个选项是使用terraform state rm来忘记它。 Terraform state rm 你肯定想要销毁资源,terraform destroy -target=module.mymodule,但在某些情况下资源并不是物理的,例如模块中的random。此外,如果你正在使用Terraform Cloud,并且工作区是VCS链接的,则无法在本地运行applydestroy。在这些情况下,请使用rm,如果存在未解决的资源,则手动删除它们。

0

在重构我的monorepo以添加多个环境(staging,prod)时,我在开发环境中遇到了这个问题。我正在使用Terraform Cloud。我通过销毁Terraform跟踪的所有内容,进行重构,然后从头开始执行新的plan/apply来解决它。这对于大多数情况都不起作用,但对于我来说,这是最简单的解决方案,因为有100多个资源已经移动。

enter image description here


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