skip to Main Content

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 🙂

2

Answers


  1. 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.

    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search