Home > database >  How to get value from module in another module - Terraform (Azure)
How to get value from module in another module - Terraform (Azure)

Time:12-27

Im trying to get value from one module and use it in another module.

I have module - 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
}

and the output is :

output "subnet_id" {
    value = "${azurerm_subnet.subnet.id}"
}

output "vnet_name" {
    value = "${azurerm_virtual_network.vnet.name}"
}

from this module i would like to get the vnet name and the subnet id for my other module that im using to create a nic.

nic module

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"
  }
}

this way is working BUT the terraform plan , planning to create 2 resource per each resource because the way im using to get the values .

under nic module im using again the vnet module so its will create second vnet.

my main.tf is

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"
}

the question is how can i get the vnet name and subnet id to use inside the nic module ?

i know there is alot of better ways to establish my request but im just learning terraform and trying this specific way :)

CodePudding user response:

how can i get the vnet name and subnet id to use inside the nic module

You have to explicitly pass those values in the root module:

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
}

Also you have to modify your vnet module to make vnets and subents conditional. For example, add variable in the vent module:

variable "should_create_vnet_and_subnet" {
    default = true
}

then make the resource conditional:

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
}

And the rest. Basically you have to rewrite your entire vnet module around conditional resources.

CodePudding user response:

There are a lot of things to reconsider here but I would like to stick to your query only as you have requested.

How to get value from the module in another module - Terraform

As I can see you are already using two modules for vnet(which includes subnet) and nic and also using two modules interface calls to use them. You can simply use variables in your nic module and then at the interface level you can pass the outputs from vnet module as an attribute to your nic module.

Refer to the below code.


# 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)

Using the same outputs as yours in the vnet module.

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

Note: "${}"aka interpolation is not required when using terraform referencing without variables or any unknown value to terraform.

There can be a lot more ways to have a module like this but I would suggest at least a few things to try and do hands-on.

Warning: extra looping can increase complexity.

I hope this helps and as I have stated this only answers your query, not some best practices or best vnet-nic module.

  • Related