How to inherit/pass on variables in terraform

Viewed 9599

I am pretty new with Terraform and having some issues with passing on variables between modules/ child directories.

I have a structure like:

.
|-- main.tf
|-- variables.tf
|-- terraform.tfvars
|-- data.tf
|-- compute
      |-- main.tf
      |-- variables.tf
      |-- terraform.tfvars
|-- network
      |-- main.tf
      |-- variables.tf
      |-- terraform.tfvars

My main.tf in the root dir looks like this:

provider "azurerm" {
}


resource "azurerm_resource_group" "test" {
  name     = "${var.resourcegroup}"
  location = "${var.location}"

  tags {
    costcenter  = "costcenter_nr"
    environment = "test"
  }
}

resource "azurerm_virtual_network" "test" {
  name                = "${var.vnet}"
  location            = "${var.location}"
  resource_group_name = "${var.resourcegroup}"
  address_space       = ["10.102.2.0/23"]

  subnet {
    name           = "${var.subnet_agw}"
    address_prefix = "10.102.3.128/28"
  }
  depends_on = ["azurerm_resource_group.test"]
}

module "compute" {
  source = "./compute"
}

module "network" {
  source = "./network"
}

In the network directory I want to create the network interfaces for the vm's. So the network interfaces depend on the subnet id. The vm's (I want to create with templates in compute) depend on the network interface id.

In the data.tf in the root directory I output the subnet id:

data "azurerm_subnet" "agw" {
  name                 = "${var.subnet_agw}"
  virtual_network_name = "${var.vnet}"
  resource_group_name  = "${var.resourcegroup}"

  depends_on           = ["azurerm_virtual_network.test"]
}

output "subnet_ag" {
  value = "${data.azurerm_subnet.agw.id}"
} 

How do I get to use that output/variable in network/main.tf so I can provision the network interface?

network/main.tf would look like:

resource "azurerm_network_interface" "sql_server" {
  name                = "${var.sql_server}"
  location            = "${var.location}"
  resource_group_name = "${var.resourcegroup}"

  ip_configuration {
    name                          = "${var.sql_server}"
    subnet_id                     = "${????????}"
    private_ip_address_allocation = "dynamic"
  }
    depends_on = ["azurerm_resource_group.test"]
}

Plus, will this dependency work since the dependency is created by the main.tf?!

2 Answers

In your main.tf at the root level add:

module "network" {
  source = "./network"
  subnet_id = "{data.azurerm_subnet.agw.id}"
}

Add the variable reference in your network module. Also be sure to declare the variable:

resource "azurerm_network_interface" "sql_server" {
  name                = "${var.sql_server}"
  location            = "${var.location}"
  resource_group_name = "${var.resourcegroup}"

  ip_configuration {
    name                          = "${var.sql_server}"
    subnet_id                     = "${var.subnet_id}"
    private_ip_address_allocation = "dynamic"
  }

  depends_on = ["azurerm_resource_group.test"]
}

Have a look into indirect and direct dependencies dependencies. In your code, you can use to create an indirect dependency like this resource_group_name = "${azurerm_resource_group.test.id}" . Then you don't need to explicitly define it.

resource "azurerm_virtual_network" "test" {
  name                = "${var.vnet}"
  location            = "${var.location}"
  resource_group_name = "${var.resourcegroup}"

Terraform natively does not support dependencies between modules, so it won't work. You could either move that code into main which would be cleaner, or look at a workaround like this Module dependencies.

Another option could be to create all your network stuff in one module, output the subnet or NIC ID. Then pass this these into the compute module as a variable?

hope this helps

Related