Introduction
Shared variable file patterns with Azure Bicep, what is it and what does it mean? How can you benefit from this? What problems can it solve?
Without regurgitating too much from the Microsoft Docs on this at a high-level it’s a great way to utilise a JSON file to put common variables you want to reuse in your Bicep files.
In this post, we’ll cover some basics of how this can be useful and expand on the Microsoft examples to inspire more adoption of this where you see necessary for your own Bicep configurations.
All code examples in this post are in my GitHub project Bicepify, where I break down concepts into friendlier learning chunks. I update the repository frequently so be sure to star if you find it useful!
Why use this over my parameters file?
In many cases, we tend to reuse a lot of variables when writing Bicep code. Whether that’s the region(s), VM SKUs, NSG security rules. This is where the shared file pattern can help maintain commonly repeatable variables which otherwise would be defined in each file, over and over. With this method we can centrally store these and call them for use instead.
Additionally, this is a great way to set a global parameters that will be reused often, or needed to be set as some standard for other teams to import the configuration for. This reduces repetition and centralises commonly used variables.
It may be not be a case of using one or the other, but both to operate an operational excellence model whereby you appropriately put together commonly used variables into a central config file vs parameters that may be changed frequently in a parameter file.
Benefits of using commonly shared variables
- Reduce commonly used values across your Bicep files
- Standardise common values through centralised json files
- Simplify readability of common variables
- Housekeeping – keeps Bicep file sizes in check without having to populate these in every parameter file
Examples
Naming prefixes
Using naming prefixes in a global configuration JSON file means we can centralise commonly used variables for repeated use across many Bicep templates.
Loading the content from the JSON file naming-config.json
we can expand the variable referenced to call on our naming prefixes, for example:
@description('Naming standards JSON config file. Loads naming prefixes for Azure resources.')
var namingPrefixes = loadJsonContent('./configs/naming-config.json')
BICEPThe variable ‘namingPrefixes’ is now available to call on, below is an example JSON config file, where we can call the variable that has loaded this JSON content to call our prefix standard:
{
"virtualMachinePrefix": "vm-prod",
"webAppPrefix": "app-prod",
"functionPrefix": "func",
"sqlPrefix": "sqldb-prod",
"storagePrefix": "st",
"vnetPrefix": "vnet",
"subnetPrefix": "snet",
"nicPrefix": "nic",
"pipPrefix": "pip",
"nsgPrefix": "nsg",
"routeTablePrefix": "route"
}
JSONUsing ${namingPrefixes.storagePrefix}
we can call on the prefix to use for the storage account for the below example:
module storage_prefix 'br/public:storage/storage-account:3.0.1' = {
name: 'storage_deploy'
params:{
name: '${namingPrefixes.storagePrefix}riosengineer001'
sku: 'Standard_LRS'
kind: 'StorageV2'
location: 'uksouth'
}
}
BICEPVirtual Machine configurations
Similarly, we can use the same shared variable concept but for virtual machine configurations like publisher and OS versions, etc.
Here’s an example vm-config.json
file that contains VM metadata which we can then reuse across all our Azure Bicep deployment files when referencing VM images:
{
"winSvr2022": {
"imageReference": {
"publisher": "MicrosoftWindowsServer",
"Offer": "WindowsServer",
"sku": "2022-datacenter-azure-edition",
"version": "latest"
},
"VMSku": {
"size": "Standard_DS1_v2"
},
"licenseType": "Windows_Server",
"patchMode": "AutomaticByPlatform",
"OS": "Windows",
"OSDiskGB": 127,
"RoleExtensions": {
}
}
}
JSONLike the last example, we can call on the configuration file like so:
// Rios Engineer - Shared variable patterns
@description('Global VM JSON config file.')
var compute = loadJsonContent('./configs/vm-config.json', 'winSvr2022')
// Windows Server 2022 Global Config
var image = compute.imageReference
var sku = compute.VMSku.size
BICEPFurther to loading the shared variable json content to the compute
variable we can tailor the variable to shorten if you want which is where I am using the image
and sku
variables defined.
resource virtualMachine 'Microsoft.Compute/virtualMachines@2020-06-01' = {
name: vmName
location: location
properties: {
hardwareProfile: {
vmSize: sku
}
osProfile: {
computerName: vmName
adminUsername: adminUsername
adminPassword: adminPassword
}
storageProfile: {
imageReference: {
offer: image.Offer
publisher: image.publisher
sku: image.sku
version: image.version
}
osDisk: {
createOption: 'FromImage'
}
}
networkProfile: {
networkInterfaces: [ {
id: networkInterface.id
} ]
}
}
}
BICEPWithin the imageReference
block we’re calling on the shorten variable defined for image
to call on the sub objects.
This enables us to centrally store many virtual machine image offers in your vm-config.json
file to call on to reduce repeating these in all your Bicep files.
Conclusion
This method to store commonly repeated variables in a ‘shared variable’ config file centrally gives great benefits for teams to adopt in their IaC arsenal. Especially when it comes to virtual machine configurations which can be lengthy to repeat over and over.
There’s additional examples over on the Microsoft Docs here. Which I feel the security rule example is another great showcase of the benefit this method can be leveraged for.
Latest Posts
APIOps – A deep dive for APIM multi-environments
Never miss an update: Azure Verified Modules with GitHub Bot & Teams
Getting started: Continuous deployment with Azure Bicep and Azure DevOps