This is a post about resource naming in Terraform. As I was working on my first production use of Terraform to deploy resources to Azure, my goal was to parameterize the resource so that in the future I could easily re-use the .TF file with a simple replacement of my .TFVARS file.
I struggled for a while because I was trying to do something like this:
resource "azurerm_virtual_network" "AZ${var.clientcode}Net" { name = "AZ${var.clientcode}" address_space = ["${lookup(var.networkipaddress, "AZ${var.clientcode}")}"] location = "${var.location}" resource_group_name = "${azurerm_resource_group.Default.name}" dns_servers = "${var.dnsservers}" } |
Effectively, I wanted my resource to result in something like “AZABCNet” both in the name property and the resource identifier as well.
Then I would try and reference that in a different resource attribute, for a subnet like this:
virtual_network_name = "${azurerm_virtual_network.AZ${var.clientcode}Net.name}"
However, this gave me errors when trying to validate:
Error: Error loading C:\terraform\ABC\ABC_Network.tf: Error reading config for azurerm_subnet[${var.location}]: parse error at 1:28: expected expression but found invalid sequence "$"
My assumption of how the resource identifier worked was incorrect thinking; resource names should be local and static, as described here on StackOverflow.
This means that I can give my resource an identifier as “AZClientNet”, since that is used only within Terraform while the Name attribute is what will become the deployed name in Azure.
This leaves a little bit of a gap where I might want a resource declared with multiples of something, with attributes defined in a map variable, without having to declare multiple resource blocks.
It appears this functionality is coming in Terraform in the form of a “for each” function, according to this Github discussion. Not having used the proposed syntax in a test environment, I don’t fully have my head around it.