如何从另一个模块- Terraform (Azure)的模块中获取值



我试图从一个模块中获取值,并在另一个模块中使用它。

我有模块-vnet

resource "azurerm_virtual_network" "vnet" {
name                = var.vnet_name
resource_group_name = var.resource_group_name
location            = var.location
address_space       = var.address_space
}
resource "azurerm_subnet" "subnet" {
name                 = "${var.vnet_name}-subnet"
resource_group_name  = var.resource_group_name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes     = var.subnet_prefixes
}

输出是:

output "subnet_id" {
value = "${azurerm_subnet.subnet.id}"
}
output "vnet_name" {
value = "${azurerm_virtual_network.vnet.name}"
}

从这个模块,我想得到我的其他模块的vnet名称和子网id,我用来创建一个网卡。

<<p>网卡模块/strong>
module "vnet" {
source = "../vnet" 
}

resource "azurerm_network_interface" "nic" {
name                = "${module.vnet.vnet_name}-nic"
location            = "east us 2"
resource_group_name = "null"
ip_configuration {
name                          = " "
subnet_id                     = module.vnet.subnet_id
private_ip_address_allocation = "Dynamic"
}
}

这种方式是有效的,但地形计划,计划创建2个资源每一个资源,因为我使用的方式来获取值。

在nic模块下,我再次使用vnet模块,因此它将创建第二个vnet。

我的<<p> strong> main.tf
resource "azurerm_resource_group" "rg" {
name     = var.resource_group.name
location = var.resource_group.location
}
module "ib151w-vnet" {
source              = "./modules/vnet"
resource_group_name = azurerm_resource_group.rg.name
vnet_name = "ib151w-vnet"
address_space       = var.address_space
subnet_prefixes     = var.subnet_prefixes
}
module "ib151w-nic" {
source              = "./modules/nic"
name                = "nic-test-123"
location            = "east us 2"
resource_group_name = "ib151w"
}

问题是我如何获得vnet名称和子网id在网卡模块内使用?

我知道有很多更好的方法来建立我的请求,但我只是学习地形和尝试这种特定的方式:)

如何获得nic模块内使用的vnet名称和子网id

必须显式传递根模块中的值:

module "ib151w-nic" {
source              = "./modules/nic"
name                = "nic-test-123"
location            = "east us 2"
resource_group_name = "ib151w"
vnet_name             = module.vnet.vnet_name
subnet_id             = module.vnet.subnet_id
}

您还必须修改您的vnet模块,使vnet和子组件有条件. 例如,在vent模块中添加变量:

variable "should_create_vnet_and_subnet" {
default = true
}

则使资源有条件:

resource "azurerm_virtual_network" "vnet" {
count = should_create_vnet_and_subnet == true ? 1 : 0
name                = var.vnet_name
resource_group_name = var.resource_group_name
location            = var.location
address_space       = var.address_space
}
resource "azurerm_subnet" "subnet" {
count = should_create_vnet_and_subnet == true ? 1 : 0
name                 = "${var.vnet_name}-subnet"
resource_group_name  = var.resource_group_name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes     = var.subnet_prefixes
}

和其他的。基本上你需要重写整个vnet模块围绕条件资源。

这里有很多事情需要重新考虑,但我想只按照您的要求坚持您的查询。

如何从另一个模块中的模块获取值- Terraform

正如我所看到的,您已经为vnet(包括子网)和nic使用了两个模块,并且还使用了两个模块接口调用来使用它们。您可以简单地在nic模块中使用变量,然后在接口级别上,您可以将vnet模块的输出作为属性传递给nic模块。

参考下面的代码。


# main.tf or MODULE INTERFACES
## Default variables ##
variable "resource_group_name" {
type        = string
description = "(optional) resource group name in which resources will created"
default     = "stack-over-flow-query"
}
variable "location" {
type        = string
description = "(optional) location where resources would be created."
default     = "east us 2"
}
################################
resource "azurerm_resource_group" "rg" {
name     = var.resource_group_name
location = var.location
}
module "ib151w-vnet" {
source = "./modules/vnet"
resource_group_name = azurerm_resource_group.rg.name
location            = azurerm_resource_group.rg.location
vnet_name           = "ib151w-vnet"
address_space       = ["10.0.0.0/16"]
subnet_prefixes     = ["10.0.1.0/24"]
}
module "ib151w-nic" {
source = "./modules/nic"
name                = "${module.ib151w-vnet.vnet_name}-nic-test-123"
location            = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
subnet_id           = module.ib151w-vnet.subnet_id
ip_configuration    = "stackoverflow"
}
## NIC Module 
resource "azurerm_network_interface" "nic" {
name                = var.name
location            = var.location
resource_group_name = var.resource_group_name
ip_configuration {
name                          = var.ip_configuration
subnet_id                     = var.subnet_id
private_ip_address_allocation = var.private_ip_address_allocation
}
}
## Required variable definitions with defaults(best practice installation in your situation)

使用与vnet模块相同的输出

output "vnet_name" {
value = azurerm_virtual_network.vnet.name
}
output "subnet_id" {
value = azurerm_subnet.subnet.id
}

注意:当使用terraform引用时,没有变量或任何未知值的terraform不需要"${}"aka插值。

可以有更多的方法来实现这样的模块,但我建议至少有一些事情可以尝试和实践。

  • 在模块中使用循环,通过一个接口调用多个资源[仅在必要且有意义时]
    • https://developer.hashicorp.com/terraform/tutorials/configuration-language/for-each

警告:额外的循环会增加复杂度。

  • 使用条件来控制你的模块行为。

    • https://developer.hashicorp.com/terraform/language/expressions/conditionals
  • 和最重要的是什么时候使用一个模块。

    • https://developer.hashicorp.com/terraform/language/modules/develop when-to-write-a-module

我希望这有帮助,正如我所说的,这只回答你的查询,而不是一些最佳实践或最佳vnet-nic模块。

最新更新