如何使用Terraform将资源创建拆分为不同的模块?

如何使用Terraform将资源创建拆分为不同的模块?,terraform,terraform-provider-azure,Terraform,Terraform Provider Azure,我想使用不同的模块来划分资源创建,但我一直无法弄清楚如何进行 对于这个例子,我想创建一个web应用程序(我使用的是azurerm提供程序)。为此,我在模块中添加了以下内容: resource "azurerm_app_service" "test" { name = "${var.app_service_name}" location = "${var.location}" resource_group_name = "${var.

我想使用不同的模块来划分资源创建,但我一直无法弄清楚如何进行

对于这个例子,我想创建一个web应用程序(我使用的是azurerm提供程序)。为此,我在模块中添加了以下内容:

resource "azurerm_app_service" "test" {
  name                = "${var.app_service_name}"
  location            = "${var.location}"
  resource_group_name = "${var.resource_group_name}"
  app_service_plan_id = "${var.app_service_plan_id}"

  app_settings {
    SOME_SETTING = "${var.app_setting}"
  }
}
它可以工作,但我希望有一个单独的模块用于应用应用程序设置,因此:

  • 模块1创建web应用程序
  • 模块2应用应用程序设置
  • 潜在模块3将其他内容应用于web应用程序
这可能吗?我尝试将其拆分(有两个模块定义web应用程序,但其中只有一个模块包含应用程序设置),但我得到一个错误,指出web应用程序已经存在,因此它似乎不理解我试图操作相同的资源

有关如何使用它的详细信息: 我将为最终用户提供一个用户界面,在该界面上,他/她可以选择所需的一堆资源,并勾选该人员项目所需的一系列选项,同时填写基础设施所需的参数

完成并提交后,参数将应用于地形模板。为每个选项排列设置模板是不可行的,因此必须根据所选选项的不同包括不同的模块

例如:如果用户勾选web app、Cosmos DB和application insights,Terraform模板将包括这些模块(使用计数技巧创建条件)。在本例中,我需要将instrumentation键从application insights传递到web应用程序的应用程序设置,这就是我的问题所在

如果用户没有选择application insights,我就不想为web应用程序设置,这就是为什么我需要逐步建立地形资源的原因。此外,根据用户选择的数据库类型,将向web应用程序的设置中添加不同的设置


所以我的想法是创建一个模块来应用某些应用程序设置。我不知道这是否可行(或者是否存在更好的方法),因此我提出了一个问题。

实现这一点的最佳方法是使用bash脚本或任何您想要的脚本语言(python)包装terraform。然后在bash或python(jinja2)中创建一个模板,用客户为设置选择的任何选项生成资源,运行该模板生成您的地形代码,然后应用它


我已经用S3桶做了很多。在terraform 0.12中,您可以在terraform中生成模板。

我知道这已经5个月了,但我认为这里的部分情况是,您描述的拆分方式并不完全适合模块的使用方式。首先,您不能动态地“构建资源”,因为Terraform是按设计声明的。您只能定义一个资源,然后动态地提供它的预定义输入(包括要激活/停用的计数)。其次,模块不需要通过配置来打开和关闭堆栈的某些部分。模块只是一种将资源集分组在一起以进行包含和重用的方法。任何由复杂的模块层次结构组成的堆栈所提供的动态性,在一个巨大的单片blob中都可以使用基本相同的代码。这个巨石会是一团糟,这就是问题所在,你不能把它的碎片用在其他事情上。最后,使用模块提供设置并不是它们真正的用途。是的,从理论上讲,您可以创建一个具有“null_data_source”的模块,然后将其纯粹用作某种垫片来提供设置,但这可能是一种复杂的、不必要的方法,通过简单地提供一个变量(如您所示)来做得更好

您可能需要像其他答案中提到的那样,在顶层将其封装在某种bash(etc)脚本中,这不是terraform的限制。例如,一旦您拥有了模块,您就会希望将当前应用的所有堆栈(针对每个客户或其他客户)保存在某种组合存储库中。在这些客户填写设置表后,您将如何为他们创建合成堆栈?您将不得不通过一些文件创建自动化来实现这一点,而Terraform并不是这样做的。Terraform用于执行现有的堆栈。这不是Terraform的限制,您必须首先使用外部文本编辑器创建.tf文件,也不是在这种情况下使用外部脚本为客户动态创建合成堆栈的限制,这只是使用自动化为Terraform做准备的方法的一部分,Terraform的工作就是应用堆栈

因此,您无法避免使用此外部脚本工具,您可能会使用它为特定于客户的合成堆栈(引用您的模块)创建文件夹,使用默认文件填充文件夹,并根据客户从表单中输入的内容创建.tfvars文件。然后您可以通过多种方式进行此操作:

  • 您将.tfvars文件作为客户组合堆栈之间的唯一区别。给定.tfvars中的变量,您使用或不使用的任何模块都将通过您提到的“计数技巧”激活/停用。这种方法的优点是易于推理,因为所有客户组合堆栈都是相同的,只是配置不同而已

  • 您可以让工具将您想要的模块定义实际插入到组合堆栈的文件中。这将创建更简洁的合成堆栈,使用更少的janky“计数技巧”,但每个客户的堆栈将是它自己的怪异雪花

  • 至于模块的划分,请注意这是一个完整的艺术/科学/哲学。我把你介绍给和(releva)