Revamping Shared Code with Azure Bicep User Defined Functions
Welcome to this article, where we will delve into creating clean and reusable code in Azure Bicep.
Overview
Discover how to simplify deploying your cloud resources on Microsoft Azure using Bicep’s new feature, “User Defined Functions,” currently in preview. This blog will guide you on writing code that can be recycled multiple times, aiding in better organization and management of your projects.
Whether you are new to Bicep or already have experience with it, this guide will demonstrate the effective use of functions for improved Azure deployments.
Pre-requisites
Since Bicep — User Defined Functions is currently in preview, please enable it in the Bicep Config of your root folder. You can do this by clicking on the View Command Palette as illustrated below.
This will open a popup where you can select Bicep: Create Bicep Configuration File as shown in the image below.
By following these steps, a bicepconfig.json file will be created. You can replace the existing content with the provided JSON content.
"experimentalFeaturesEnabled":
"userDefinedFunctions": true
Note: If you prefer not to delete the existing content, you can simply add lines 2–4 from the code above to the bicepconfig.json file.
Before we begin creating Bicep — User Defined Functions, let’s consider a scenario where duplicate code may exist in various locations.
Real-World Scenario
Imagine you need to create a Storage account with different replication strategies based on the environment.
For non-production environments, you might choose Locally Redundant Storage (LRS) for cost-efficiency, while for production environments, Geo-Redundant Storage (GRS) might be preferred for increased resilience.
It’s important to note that multiple storage accounts may need to be created based on specific requirements.
Author Bicep Code
Let’s craft the following Bicep code that takes Storage Replication Type as a parameter.
storage.bicep
param pStorageAccountName string
param pLocation string = resourceGroup().location
param pStorageSKU string
resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' =
name: pStorageAccountName
location: pLocation
sku:
name: pStorageSKU
kind: 'StorageV2'
main.bicep
param pEnv string
param pLogicAppStorageAccountName string
param pFunctionAppStorageAccountName string
param pLocation string = resourceGroup().location
module fappStorage 'modules/storage.bicep' =
name: 'fappStorage'
params:
pStorageAccountName: pFunctionAppStorageAccountName
pLocation: pLocation
pStorageSKU: pEnv == 'prd' ? 'Standard_GRS' : 'Standard_LRS'
module lappStorage 'modules/storage.bicep' =
name: 'lappStorage'
params:
pStorageAccountName: pLogicAppStorageAccountName
pLocation: pLocation
pStorageSKU: pEnv == 'prd' ? 'Standard_GRS' : 'Standard_LRS'
In the provided code snippet, a logical condition is set to determine the environment classification as ‘PRD’. Based on this classification, the pStorageSKU parameter is assigned either ‘Standard_GRS’ or ‘Standard_LRS’ accordingly.
The repetitive logical code in the condition can be optimized. Let’s utilize Bicep User Defined Functions to refactor and create more concise and cleaner code.
User Defined Function
Let’s introduce a new Bicep User Defined Function as outlined below.
func GetStorageAccountKind(Env string) string => Env=='prd' ? 'Standard_GRS' : 'Standard_LRS'
module fappStorage 'modules/storage.bicep' =
name: 'fappStorage'
params:
pStorageAccountName: pFunctionAppStorageAccountName
pLocation: pLocation
pStorageSKU: GetStorageAccountKind(pEnv)
module lappStorage 'modules/storage.bicep' =
name: 'lappStorage'
params:
pStorageAccountName: pLogicAppStorageAccountName
pLocation: pLocation
pStorageSKU: GetStorageAccountKind(pEnv)
As seen in the code snippet above, the logical condition is now streamlined in the Bicep User-Defined Function called GetStorageAccountKind. This function is then invoked instead of the previous logical condition.
Any future changes to the logic will only require modification in one place, making the code clean and concise.
While the GetStorageAccountKind function is currently confined to the current bicep file, you can expand its usability to other bicep files by creating a Bicep Module for the User Defined Function. Let’s create a new module named udf.bicep as illustrated below.
Udf.bicep
param pEnv string
func GetStorageAccountKind(Env string) string => Env=='prd' ? 'Standard_GRS' : 'Standard_LRS'
output StorageAccountKind string = GetStorageAccountKind(pEnv)
It’s important to note that StorageAccountKind is set as an output parameter.
Now, we need to call the UDF.bicep module from the main.bicep file.
main.bicep
param pEnv string
param pLogicAppStorageAccountName string
param pFunctionAppStorageAccountName string
param pLocation string = resourceGroup().location
module udf 'modules/udf.bicep' =
name: 'udf'
params:
pEnv: pEnv
module fappStorage 'modules/storage.bicep' =
name: 'fappStorage'
params:
pStorageAccountName: pFunctionAppStorageAccountName
pLocation: pLocation
pStorageSKU: udf.outputs.StorageAccountKind
module lappStorage 'modules/storage.bicep' =
name: 'lappStorage'
params:
pStorageAccountName: pLogicAppStorageAccountName
pLocation: pLocation
pStorageSKU: udf.outputs.StorageAccountKind
Summary
This article introduces the concept of User Defined Functions (UDFs) in Bicep, highlighting how they can enhance code reusability, readability, and maintainability in infrastructure deployment tasks. By providing practical examples and insights, readers can learn how to leverage UDFs to modularize their Bicep code and streamline Azure deployments effectively.
Whether you’re a novice or an experienced developer, this guide empowers you with the necessary knowledge to maximize the potential of Bicep functions for seamless and scalable Azure deployments.
To explore more about Skrots, our services, and blogs, visit Skrots. Discover the range of services we offer at Skrots Services.
Know more about our company at Skrots. Know more about our services at Skrots Services, Also checkout all other blogs at Blog at Skrots
Thanks, Harsh
Founder | CEO — Skrots
Learn more about our blog at Blog at Skrots. Checkout our list of services on Skrots. Give a look at our website design at Skrots . Checkout our LinkedIn Page at LinkedIn.com. Check out our original post at https://blog.skrots.com/refactoring-common-code-with-azure-bicep-user-defined-functions/?feed_id=5286&_unique_id=65fd96ec8cb0d