【问题标题】:Wait\Depend on resources in parent from module等待\依赖来自模块的父级资源
【发布时间】:2019-04-22 21:57:13
【问题描述】:

我在main.tf 中创建资源组和vNet,并在同一个文件中引用模块。问题是,模块无法从模块访问这些资源。相关代码(大部分代码去掉,只剩下相关部分):

main.tf:

module "worker" {
  source = "./vmLoop"

  vmName = "worker"
  prefix = "${var.reference["name"]}"
  loop   = "${var.reference["workerCount"]}"
}

resource "azurerm_resource_group" "rg" {
  name     = "${var.reference["name"]}"
  location = "${var.reference["location"]}"
}

如何在模块中引用此资源组?在main.tf 里面我可以这样做:"${azurerm_resource_group.rg.name}"。不仅如此,如果我想在模块内使用数据,那会失败,因为资源尚未创建(大部分代码已删除,只剩下相关部分):

Module.tf:

data "azurerm_resource_group" "rg" {
  name = "${var.prefix}"
}

如果我预先创建资源组\vnet,一切正常。

在 arm 模板中,我会添加一个 dependsOn 属性。但是,terraform 中的模块不支持depends_on

【问题讨论】:

    标签: azure reference virtual-machine terraform


    【解决方案1】:

    在模块中,您应该传递子网 ID 或资源组,或者您正在创建的任何变量作为变量。例如,在您的主配置中,您可能会调用以下内容:

    module "vnet" {
      source              = "Azure/network/azurerm"
      resource_group_name = "${var.resource_group}"
      vnet_name           = "${terraform.workspace}-vnet"
      location            = "${var.arm_region}"
      address_space       = "${var.arm_network_address_space}"
      subnet_prefixes     = ["${var.arm_subnet1_address_space}", "${var.arm_subnet2_address_space}"]
      subnet_names        = ["subnet1", "subnet2"]
    
      tags = {
        environment = "${terraform.workspace}"
      }
    }
    

    然后调用使用子网 ID 的 vmdeploy 模块,如下所示:

    module "vmdeploy" {
     source = "./vmdeploy"
     subnetID = "${module.vnet.vnet_subnets[0]}"
    }
    

    通过将另一个模块引用为 vmdeploy 模块的值,您正在创建一个隐式依赖项,Terraform 将识别该依赖项并将其包含在资源图中。

    在模块本身中,您将定义一个名为 subnetID 的变量,如下所示:

    var "subnetID" {}
    

    这有帮助吗?

    【讨论】:

    • 嘿,内德,谢谢(感谢您的 tf 课程)!这或多或少是我现在正在做的事情。我希望有一种不那么骇人听闻的方式
    【解决方案2】:

    有一个相当hackish的解决方法。

    您可以在下游的上游模块的输出变量上使用depends_on,但是您必须确保在下游模块中使用该变量,而不仅仅是在depends_on子句中使用它。

    很遗憾,这不是一个理想的解决方案,并且在某些情况下可能不适用。

    【讨论】:

    • 嘿,你能提供一些示例代码吗,我不太明白这个解释,对不起
    • 一个代码 sn-p 会太长,所以我会在这里解释。这个想法是,当你调用一个模块时,你很可能会有输出变量。您可以在其他模块中使用这些值。因此,您可以做的是,在调用第二个模块时使用 depends_on = output_var 子句。但是您必须确保,在第二个模块内的某个地方,您使用已传递给您的 depends_on 子句的输出变量。我不精通 Azure,但精通 AWS,例如创建 VPC > 传递 ID 作为depends_on 值 > 在第二个模块中使用 VPC_ID。
    • 在我的情况下,我没有输出值,并且我没有该模块之前的模块,只有调用该模块的 main.tf。因为您清楚地知道您在说什么 - 您有一个指向 aws 示例的链接?
    • 很遗憾,我没有,我在我工作的一个项目中使用了这种方法,但我们可以开始聊天,这样我们就不会在这里发垃圾邮件并更好地讨论。
    • 呸,cmets 中的一个选项应该显示,你从哪里开始......,以为它已经在那里了
    【解决方案3】:

    您需要将资源组的名称传递给模块。 即:

    module "worker" {
      source = "./vmLoop"
    
      rg     = "${azurerm_resource_group.rg.name}"    
      vmName = "worker"
      prefix = "${var.reference["name"]}"
      loop   = "${var.reference["workerCount"]}"
    }
    

    然后在工作模块代码本身中,您将使用 rg 变量作为工作人员的资源组。

    【讨论】:

    • 是的,但就像我说的,问题是子网资源,rg资源只是为了展示。
    猜你喜欢
    • 1970-01-01
    • 2020-09-16
    • 2013-06-29
    • 2018-03-18
    • 1970-01-01
    • 2019-11-04
    • 2021-07-09
    • 1970-01-01
    • 2023-02-23
    相关资源
    最近更新 更多