Inheritance is not natively supported in Azure Bicep, but with the creative use of modules and functions like union, we can implement a similar behavior.
This article demonstrates a practical workaround to manage global tags and extend them with module-specific tags dynamically.
The example includes creating two modules.
- Storage Account
- Log Analytics Workspace
These modules receive and process tags via a centralized Tags module.
Problem Statement
Azure resources often require consistent tagging for governance, cost management, and resource tracking. While global tags can be applied at a subscription or resource group level, module-specific tags might still be needed. Combining these efficiently within the Bicep can be challenging.
Objective
- Create a centralized Tags module to handle global tags and allow extension with module-specific tags.
- Use the union function to combine global and module-specific tags dynamically.
- Demonstrate the implementation of a Storage Account and Log Analytics Workspace.
Features of Azure Bicep function Union
- Returns a single array or object with all elements from the parameters.
- For arrays, duplicate values are included once.
- For objects, duplicate property names are only included once.
- The union function merges not only the top-level elements but also recursively merges any nested objects within them. Nested array values are not merged.
Ref: https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/bicep-functions-array#union
Solution Design
![Solution Design]()
1. Tags Module
File: modules/tags.bicep
This module accepts the below params.
- global tags
- module-specific tags
Returns a new object by combining both the global tags and the module-specific tags using the Bicep function union.
param globalTags object
param moduleTags object = {}
var combinedTags = union(globalTags, moduleTags)
output tags object = combinedTags
2. Storage Account Module
File: modules/storage.bicep
This module demonstrates applying tags to a Storage Account resource.
param storageAccountName string
param location string
param tags object
resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = {
name: storageAccountName
location: location
kind: 'StorageV2'
sku: {
name: 'Standard_LRS'
}
tags: tags
}
3. Log Analytics Workspace Module
File: modules/loganalytics.bicep
This module applies tags to a Log Analytics Workspace resource.
param workspaceName string
param location string
param tags object
resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2023-03-01' = {
name: workspaceName
location: location
sku: {
name: 'PerGB2018'
}
tags: tags
}
output workspaceId string = logAnalyticsWorkspace.id
4. Main Bicep File
File: main.bicep
The main file integrates all modules and demonstrates the inheritance mechanism by combining global tags with module-specific tags.
// Global tags
var globalTags = {
environment: 'Production',
owner: 'TeamA'
}
// Module-specific tags
var storageTags = {
moduleType: 'StorageAccount'
}
var logAnalyticsTags = {
moduleType: 'LogAnalyticsWorkspace'
}
// Tags for Storage Account
module tagsStorage 'modules/tags.bicep' = {
name: 'tagsStorage'
params: {
globalTags: globalTags
moduleTags: storageTags
}
}
// Deploy Storage Account
module storage 'modules/storage.bicep' = {
name: 'storageAccount'
params: {
storageAccountName: 'prodstorage001'
location: 'eastus'
tags: tagsStorage.outputs.tags
}
}
// Tags for Log Analytics Workspace
module tagsLogAnalytics 'modules/tags.bicep' = {
name: 'tagsLogAnalytics'
params: {
globalTags: globalTags
moduleTags: logAnalyticsTags
}
}
// Deploy Log Analytics Workspace
module logAnalytics 'modules/loganalytics.bicep' = {
name: 'logAnalyticsWorkspace'
params: {
workspaceName: 'prodloganalytics001'
location: 'eastus'
tags: tagsLogAnalytics.outputs.tags
}
}
After running the bicep code, below is how the tags are created in Storage and the Log Analytics Workspace.
Storage Account Tags
![Storage Account Tags]()
Log Analytics Workspace
![Log Analytics Workspace]()
Explanation
- Tags Module: Combines global and module-specific tags using the union function.
- Storage and Log Analytics Modules: Create each Azure resource and also use the combined tags as inputs for resource creation.
- Main File: Demonstrates tag inheritance by passing global tags to the Tags module and dynamically adding a module type tag.
Benefits
- Centralized tag management simplifies governance.
- Flexible design allows module-specific customization without duplicating global tags.
- Scalable for additional modules.
Summary
This article provides a practical approach to implementing inheritance-like behavior in Azure Bicep by leveraging the union function for tag management. The solution centralizes global tags and allows dynamic extension with module-specific tags. By combining these efficiently, we achieve a scalable, maintainable, and consistent tagging strategy across different Azure resources.