Reading Time: 3 minutes

If you’ve ever found yourself exhausted from manually using the aznaming tool through the UI to generate resource names, fret not! I’ve been there, and I understand the frustration and laziness.

Hereby introducing my latest brainchild / side-project: a custom Bicep module that communicates with the aznaming tool via Rest API to generate resource names programmatically! No more tedious clicking and typing through the UI. With this module, you can effortlessly automate the resource naming process, saving valuable time and effort.

In this blog post, I’ll walk you through the step-by-step process of creating and implementing this ingenious module. Say goodbye to manual resource naming and hello to the magic of automation in your Azure workflow!

The Anatomy of the Module

As I mentioned, I went full Bicep, well, almost! The reason I say “almost” is that I utilized a deployment script to make the Rest API call to the aznamingtool, enabling me to effortlessly generate resource names for my Azure resources. The script is nearly ready to use; the only modifications required are to replace line 19 the URL of aznaming tool and in line 20 the apikey with your actual API key.

By the way, the API key is generated on the first launch and can be retrieved from the application UI under the Admin Section.

@description('Required. Generates a resource name based on the provided request data')
param requestData object

@description('Required. Generates a resource name based on the provided request data')
var apostrophe = '\''

resource namerequest 'Microsoft.Resources/deploymentScripts@2020-10-01' = {
  name: 'aznamingtool'
  location: resourceGroup().location
  kind: 'AzurePowerShell'
  properties: {
    azPowerShellVersion: '8.3'
    scriptContent: '''
      param (
          [string]
          $requestData
      )
  
      $apiUrl = "https://xxxxx.azurewebsites.net/api/ResourceNamingRequests/RequestName"
      $apiKey = "xxxx-xxxx-xxxx-xxxx-1xxxxxxxx" # Replace with your actual API key
  
      $headers = @{
          "accept"        = "*/*"
          "APIKey"        = $apiKey
          "Content-Type"  = "application/json"
      }
  
      # Convert the request data to JSON string
      $jsonData = ConvertFrom-Json $requestData | ConvertTo-Json -Depth 5 -Compress
  
      try {
          $response = Invoke-RestMethod -Uri $apiUrl -Headers $headers -Method Post -Body $jsonData
          $output = $response.ResourceName.Trim()
          Write-Output $output.Trim()
      } catch {
          Write-Output "Failed to generate the resource name. Error: $($_.Exception.Message)"
      }
  

  $DeploymentScriptOutputs = @{}
  $DeploymentScriptOutputs["resourceName"] = $output
    '''
    cleanupPreference: 'OnSuccess'
    retentionInterval: 'P1D'
    forceUpdateTag: '1'
    timeout: 'PT10M'
    arguments: '-requestData ${apostrophe}${replace(string(requestData), '"', '\\"')}${apostrophe}'
  }
}

output resourceName string = namerequest.properties.outputs.resourceName

The Bicep Template

Let’s take a closer look below at the Bicep template that showcases how you can leverage the module to generate resource names and seamlessly pass them to the resources you want to deploy. However, there’s one essential point to be noted – if you choose not to use modules for deploying resources, Bicep might raise concerns about the naming convention you provide.

@description('Required. Resource location')
param location string

@description('Required. Generates a resource name based on the provided request data')
param requestData object

@description('Required. Storage account skuName')
param skuName string

@description('Required. Storage account type')
param kind string

module namerequest 'Modules/aznaming/aznamingtool.bicep' = {
  name: 'nameRequest'
  params: {
    requestData: requestData
  }
}

module stg 'Modules/storage/storage.bicep' = {
  name: 'default'
  params: {
    name: namerequest.outputs.resourceName
    location: location
    skuName: skuName
    kind: kind
  }
}

output storageAccountName string = stg.outputs.name

Last but not least, here’s the BicepParam file that perfectly complements the Bicep template we’ve discussed earlier. This file acts as a crucial link between your Bicep template and the deployment process, allowing you to customize various parameters as per your requirements.

One thing worth mentioning is that the information provided must and should match the configuration made in the aznaming tool. For example, if the request is made for components like “resourceEnvironment,” “resourceInstance,” “resourceLocation,” and “resourceType,” which all match the configuration, the name returned will align with the configuration settings. However, if additional components like “resourceUnitDept” or “resourceFunction” are included, the aznaming tool will disregard these extra components and only consider the ones that match the configuration. It’s essential to ensure consistency between the provided information and the aznaming tool’s configuration to get the desired resource names accurately.

using './main.bicep'

param location = 'westeurope'
param requestData = {
      resourceEnvironment: 'uat'
      resourceInstance: '029'
      resourceLocation: 'we'
      resourceProjAppSvc: 'sap'
      resourceType: 'st'
    }
param skuName = 'Standard_LRS'
param kind = 'StorageV2'

Below is the evidence that the name was generated through the Rest API.

IMPORTANT – Re-issuing the template deployment, will not trigger the resource name generation again! Meaning of it won’t break neither the deployment will be blocked because the resourceName already exists in the Azure Naming tool context.

In summary, whether you’re tired of repetitive manual naming tasks or seeking a more automated approach to resource naming, this module has you covered.

Let me know what you think or how can this module can become better in the comments down below.

Thanks for reading my blog!