Terraform Azurerm Provider Functions
This article was written by Dave Lloyd and originally published on Medium. Cross-posting here.
I do a lot of Terraform development in both Azure and Google Cloud, however for some reason I never write about it. So I thought I would start.
I recently found a very useful function in the azurerm provider, parse_resource_id.
Background
An Azure Resource ID is a unique, fully qualified string that acts as the absolute address for a specific resource within your Azure environment.
Here are some examples:
SQL Dabatbase
/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Sql/servers/<server>/databases/<db>
Storage Account
/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Storage/storageAccounts/<sa>
Azure Container Registry
/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.ContainerRegistry/registries/<acr>
Cosmos DB
/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.DocumentDB/databaseAccounts/<cosmosSQL>
There are times when this is what you have to work with. In Terraform you could write your own series of difficult to read function calls using split(), slice(), length() and join() and any other terraform functions required to parse out each element.
However, when you want to do something more generic and you don’t know what the resource_id represents. This is where parse_resource_id comes in very handy.
Sample call
Here is how you call the function parse_resource_id( )
locals {
scope = "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.ApiManagement/service/service1/gateways/gateway1/hostnameConfigurations/config1"
parsed_id = provider::azurerm::parse_resource_id(local.scope)
}
output "parced_id" {
value = local.parsed_id
}
From this call you would get back the following output.
parsed_id = {
"full_resource_type" = "Microsoft.ApiManagement/service/gateways/hostnameConfigurations"
"parent_resources" = tomap({
"gateways" = "gateway1"
"service" = "service1"
})
"resource_group_name" = "resGroup1"
"resource_name" = "config1"
"resource_provider" = "Microsoft.ApiManagement"
"resource_scope" = tostring(null)
"resource_type" = "hostnameConfigurations"
"subscription_id" = "12345678-1234-9876-4563-123456789012"
}
Sample scenario
You have a resource_id and you want to look up it’s resource group and get a list of all the other resources in that resource group with the same tag.
Try this:
locals {
resource_group = provider::azurerm::parse_resource_id(var.scope).resource_group_name
}
data "azurerm_resources" "example" {
resource_group_name = local.resource_group
required_tags = {
mytag = "tag_value"
}
}
Even though all you have is a resource_id and you don’t actually care what the resource type is, this will return a list of resources in the same resource group with the tags listed in required tags.
Note: Provider defined functions are supported in terraform 1.8 and later, and this is available from version 4.0 of the provider.