Terraform中是否可能存在提供程序变量?

13

在 Terraform v0.12.6 中是否仍然无法使用变量提供程序?在 *.tfvars 文件中,我有一个名为supplier的列表变量。

supplier = ["azurerm.core-prod","azurerm.core-nonprod"]

在provider.tf中定义的提供者:

provider "azurerm" {
  ...
  alias           = "core-prod"
}

provider "azurerm" {
  ...
  alias = "core-nonprod"

那么我想在*.tf中引用它。下面的示例是使用"data",但同样适用于"resource"。

data "azurerm_public_ip" "pip" {
  count = "${var.count}"
   ....
   provider = "${var.supplier[count.index]}"
} 

什么是解决方法?错误:无效的提供者配置引用,这表明提供者参数需要一个提供者类型名称,可选地跟随一个点和一个配置别名


1
你需要为此设置提供程序别名。文档在这里:https://www.terraform.io/docs/configuration/providers.html#alias-multiple-provider-instances。关于如何使用它们的答案也可以参考Stack Overflow上的内容。此外,自0.11版本以来就已经可以实现了。 - Matt Schuchard
抱歉,我已经更新了我的问题并添加了provider.tf文件,当然我已经设置好了。 - irom
1个回答

17
无法动态地将资源与提供程序关联起来。就像在静态类型的编程语言中,通常不能在运行时动态切换特定符号以引用不同的库一样,Terraform需要在表达式评估之前将资源块绑定到提供程序配置。您可以编写一个模块,该模块期望从其调用者接收提供程序配置,然后针对该模块的每个实例静态选择提供程序配置。
provider "azurerm" {
  # ...

  alias = "core-prod"
}

module "provider-agnostic-example" {
  source = "./modules/provider-agnostic-example"

  providers = {
    # This means that the default configuration for "azurerm" in the
    # child module is the same as the "core-prod" alias configuration
    # in this parent module.
    azurerm = azurerm.core-prod
  }
}

在这种情况下,模块本身与提供者无关,因此可以在生产和非生产环境中使用,但是模块的任何特定用途都必须指定是哪个环境。一种常见的方法是为每个环境设置单独的配置,共享模块表示环境具有的任何特征,但同时也给出了可能需要存在于它们之间的任何差异的机会。在最简单的情况下,这可能只是两个配置,每个配置仅包含一个模块块和一个提供程序块,每个块都有一些不同的参数,表示该环境的配置,并且共享模块包含所有资源和数据块。在更复杂的系统中,可能会使用模块组合技术将多个模块集成在一起。

1
感谢您的帖子。在上述情况下,如果我们在模块的“providers”块中放置4个别名提供程序(所有AWS,每个美国地区1个),那么子模块将如何使用它们?它们可以传递一个地区,然后使用插值从列表中选择正确的提供程序吗? - tavor999
查看此链接,了解如何引用传递给模块的不同提供者配置:https://www.terraform.io/language/providers/configuration#alias-multiple-provider-configurations - alex
2
这很令人难过,但也可以理解。 - kap
是的,但是对于需要提供程序作为参数的模块怎么办?例如,可以参考阿里云CEN Transit路由器 https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/cen_transit_router_peer_attachment。 - Ricky Levi
这真是令人难过,也难以理解。对于一个模块来说,无法迭代地处理各个区域,因为每个区域都需要单独的提供者别名。 - Jeffrey Aguilera
这真是令人难过,也难以理解。对于一个模块来说,无法对区域进行迭代,因为每个区域都需要一个单独的提供者别名。 - undefined

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