Naming conventions made easy with Azure Bicep functions

Francisco Vilches
tech-lah
Published in
2 min readMay 28, 2024

Rather than having multiple Azure resources with varying naming patterns like so:

  • acmeincwebapp-dev
  • webapp-prod-acmeinc

You’d likely rather a consistent and predictable naming approach. Example:

  • app-acmeinc-dev-auseast
  • app-acmeinc-prd-auseast

📗 One step towards this goal lays in how we can use some of Azure Bicep’s newest language features, User-defined functions and User-defined types.

Here’s an example of what I mean

We start by defining a bicep type. Let’s call it ‘environmentName’. It represents the full name of our environment.

type environmentName = 'Development' | 'Test' | 'Production'

Now we can create a bicep function that takes an ‘environmentName’ parameter and returns a friendly short name.

func environmentShortName(environmentName environmentName) string =>
{
Development: 'dev'
Test: 'tst'
Production: 'prd'
}[environmentName]

Similarly, we can define a function that takes an Azure location full name and returns a friendly short name. The location parameter can be typed of course.

@description('Locations supported by our organization')
type location = 'AustraliaEast' | 'CanadaCentral' | 'FranceCentral'

func locationShortName(location location) string =>
{
AustraliaEast: 'auseast'
CanadaCentral: 'cancen'
FranceCentral: 'fracen'
}[location]

Bonus

We might want to keep our types and functions separate from our actual Azure resource definitions. For instance, our folder structure could look like so

infrastructure
exports.bicep
main.bicep

exports.bicep contains our types and functions, whereas main.bicep can reference them by import them.

📗 See Imports in Bicep.

Putting it all together

Let’s say our goal is to deploy a Log Analytics Workspace for each of our environments. Here is what our bicep code now looks like.

exports.bicep

@export()
type environmentName = 'Development' | 'Test' | 'Production'

@export()
@description('Locations supported by our organization')
type location = 'AustraliaEast' | 'CanadaCentral' | 'FranceCentral'

@export()
func environmentShortName(environmentName environmentName) string =>
{
Development: 'dev'
Test: 'tst'
Production: 'prd'
}[environmentName]

@export()
func locationShortName(location location) string =>
{
AustraliaEast: 'auseast'
CanadaCentral: 'cancen'
FranceCentral: 'fracen'
}[location]

main.bicep

import * as exports from './exports.bicep'

param environmentName exports.environmentName
param location exports.location

var envShortName = exports.environmentShortName(environmentName)
var locationShortName = exports.locationShortName(location)
var logAnalyticsWorkspaceName = 'log-acmeinc-${locationShortName}-${envShortName}'

resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2023-09-01' = {
name: logAnalyticsWorkspaceName
location: location
properties: { /* properties omitted for brevity */ }
}

Result

We’ve now deployed the below Azure resources to the Australia East region:

  • log-acmeinc-dev-auseast
  • log-acmeinc-tst-auseast
  • log-acmeinc-prd-auseast

--

--