Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Terraform, can a resource be passed as a variable into a module?

Tags:

I'm just getting to grips with Terraform (so apologies if this is a stupid question).

I'm setting up an azure vnet with a set of subnets, each subnet has a routing table that sends traffic via a firewall.

It looks like the subnet and route table combination would make a good re-useable module.

By convention, I'd like to create the subnet and the route table in the same resource group and location as the parent vnet.

If I provide all the values needed in the module as individual values, the module works ok :)

What I'd rather do is effectively pass the resource that represents the parent vnet into the module as a "parameter" and have the module read things like the resource group name, location and vnet name directly from the vnet resource, so that: - I type less (I create the module instance with just the vnet, rather than seperate values for vnet name, resource group name and location) - it removes the opportunity for error when setting the location and resource group names on the route table and subnet (if I read the values from the parent vnet in the module then the values will be the same as the parent vnet)

Currently the module variables are defined as:

variable "parent-vnet-name" {}  variable "parent-vnet-resource-group-name" {}  variable "parent-vnet-location" {}  variable "subnet-name" {   type = "string" }  variable "subnet-address-prefix" {}  variable "firewall-ip-private" {} 

and the module as:

resource "azurerm_route_table" "rg-mgt-network__testtesttest" {    name                = "${var.subnet-name}"   location            = "${var.parent-vnet-location}"   resource_group_name = "${var.parent-vnet-resource-group-name}"    route {     name                   = "Default"     address_prefix         = "0.0.0.0/0"     next_hop_type          = "VirtualAppliance"     next_hop_in_ip_address = "${var.firewall-ip-private}"   } } 

Really what I'd like to do is more like variables:

variable "parent-vnet" {}  variable "subnet-name" {   type = "string" }  variable "subnet-address-prefix" {}  variable "firewall-ip-private" {} 

with module doing something like:

resource "azurerm_route_table" "rg-mgt-network__testtesttest" {   name                = "${var.subnet-name}"   location            = "${var.parent-vnet.location}"   resource_group_name = "${var.parent-vnet.resource-group-name}"    route {     name                   = "Default"     address_prefix         = "0.0.0.0/0"     next_hop_type          = "VirtualAppliance"     next_hop_in_ip_address = "${var.firewall-ip-private}"   } } 

I've played around with a variety of things (such as trying to pass the vnet without specifying an attribute name (validation failure) or using a data source to pull back the vnet (the data sources doesn't have the resource group info) ) but haven't got anywhere so I'm wondering if I've missed something?

Cheers, Andy

like image 859
user2926169 Avatar asked Jun 07 '18 11:06

user2926169


People also ask

How do I pass a variable into a module Terraform?

Steps: Clone the repo from here. Change your directory to ./terraform/passing-outputs so you can list modules directory, variables.tf and main.tf files. Change the variables in root variables.tf file according to your needs.

Can we define variables in modules in Terraform?

Defining variables in a fileTerraform variables can be defined within the infrastructure plan but are recommended to be stored in their own variables file. All files in your Terraform directory using the . tf file format will be automatically loaded during operations.

What is the difference between Terraform resource and module?

A Terraform module is a collection of standard configuration files in a dedicated directory. Terraform modules encapsulate groups of resources dedicated to one task, reducing the amount of code you have to develop for similar infrastructure components.

How do you assign a value to a variable in Terraform?

The most simple way to assign value to a variable is using the -var option in the command line when running the terraform plan and terraform apply commands.


1 Answers

This is possible with terraform > 0.12. You can use the object type, butt you have to explicitly list fields that you use within your module.

# module's variables.tf variable "parent_vnet" {   # List each field in `azurerm_route_table` that your module will access   type = object({     name = string     location = string     resource_group_name = string   }) }   # caller resource "azurerm_route_table" "my_parent_vnet" {   # ... }  module "my-module" {   parent_vnet = azurerm_route_table.my_parent_vnet } 
like image 171
Cory ODaniel Avatar answered Oct 13 '22 16:10

Cory ODaniel