Naming conventions made easy with Azure Bicep functions
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