Azure Bicep parameters
Parameters are essential when authoring Bicep configuration files. They make your template reusable and polyvalent. In this blog post, I will explore ways to manage parameters in Bicep. This is an introduction post but some complex notions are presented. A parameter defines what Bicep can accept as external values to perform a deployment. Declaring parameters in the Bicep language is simple. param DataType ParameterName You can also define a default value for a parameter. param DataType ParameterName = DefaultValue In this case, you can omit this parameter during the deployment, Bicep will use the default value instead. You can declare parameters wherever you want in the Bicep file. But the best practice is to declare them at the beginning of the file or just before the resource where they are used. Data Type You need to provide a data type for each parameter you create. Array An array is a multivalued type, where value can be acceded by an index (starting from 0) To use an array as a parameter. param arrayParam array You can use PowerShell to pass a PowerShell array to bicep -arrayParam @(1,2) But if you make an error and use a single value -arrayParam 1, Bicep will transform the value into an array with a single value. Boolean Boolean is a type that accepts only two values, true or false. They are very useful in Bicep when you need to use a condition to deploy or not something. param isDevEnvironment bool Integer The integer type in a 64-bit unsigned integer (value between -9,223,372,036,854,775,808 and 9,223,372,036,854,775,807). param numberOfInstance int But if you use PowerShell and for some reason you need this kind of high number you may have an error because PowerShell uses 32bit integer. But there is a way to avoid that. Cannot convert value "922337200685477580" to type "System.Int32". Error: "Value was either too large or too small for an Int32." Object Objects can be very useful to represent data in Bicep. An object is a collection key/value enclosed by a {}. They are similar to HashMap in PowerShell. param tags object = { environment: 'dev' department: 'IT' } You can access values from an object by using its key Tags. environment String A string is a value enclosed by a single quote. It can use Unicode values between 0 and 10FFF (But you will use Latin characters most of the time). You can escape reserved characters by using a backslash \ User-defined type You can use a user-defined type for your parameter. A user-defined type is a datatype defined in a Bicep project that allows better control. See type vmConfiguration = { OSVersion: '2022-datacenter-azure-edition' | '2022-datacenter-azure-edition-core' name: string size: 'Standard_D2s_v3' imageOffer: 'WindowsServer' imagePublisher: 'MicrosoftWindowsServer' } param vmParams vmConfiguration Decorators Now that we have seen the Bicep parameter's basics, let's see how we can do with the parameters. You can add controls, a description, or change the behavior of a parameter by using decorators. A decorator is an expression starting with an @ . There are informational decorators that give information about the parameters, secure decorators, to secure data, constraint decorators to limit the input, and user-defined type related decorators. Informational decorator You can add a description to a parameter by using @descritption or @sys.description (if you have a parameter called description in your file). You can give a short text or a multiline markdown formatted text. It can be a description or a text to help the user with the parameter. @description('The name length should be between 3 and 24 car in lowercase letters or number') param storageAccountName string @description(''' Storage account name restrictions: - The lenght should be between 3 and 24. - lowercase letters or numbers only ''') param storageAccountName string The other informational decorator is @metadata. It allows you to add some information about the parameter. Azure Resource Manager ignores this decorator. You can use an object composed of one to several key/value pairs that describe the parameter. @description('Configuration of the storage account') @metadata({ kind: 'Storage account kind' accessTier: 'Storage account accessTier' }) param storageConfiguration object Informational decorators are crucial to give more context to expected data for a parameter. It helps detect deployment errors and can help build accurate documentation and code completion in the AI age. Secure decorator The @secure operator applies to string and object only. It should be used on parameters containing a password, a secret, or a key. Using this decorator, you ensure the value is not logged or stored in the deployment history (but only if the value is used in Azure for a password, a key,
Parameters are essential when authoring Bicep configuration files. They make your template reusable and polyvalent.
In this blog post, I will explore ways to manage parameters in Bicep. This is an introduction post but some complex notions are presented.
A parameter defines what Bicep can accept as external values to perform a deployment.
Declaring parameters in the Bicep language is simple.
param DataType ParameterName
You can also define a default value for a parameter.
param DataType ParameterName = DefaultValue
In this case, you can omit this parameter during the deployment, Bicep will use the default value instead.
You can declare parameters wherever you want in the Bicep file. But the best practice is to declare them at the beginning of the file or just before the resource where they are used.
Data Type
You need to provide a data type for each parameter you create.
Array
An array is a multivalued type, where value can be acceded by an index (starting from 0)
To use an array as a parameter.
param arrayParam array
You can use PowerShell to pass a PowerShell array to bicep -arrayParam @(1,2)
But if you make an error and use a single value -arrayParam 1, Bicep will transform the value into an array with a single value.
Boolean
Boolean is a type that accepts only two values, true or false. They are very useful in Bicep when you need to use a condition to deploy or not something.
param isDevEnvironment bool
Integer
The integer type in a 64-bit unsigned integer (value between -9,223,372,036,854,775,808 and 9,223,372,036,854,775,807).
param numberOfInstance int
But if you use PowerShell and for some reason you need this kind of high number you may have an error because PowerShell uses 32bit integer. But there is a way to avoid that.
Cannot convert value "922337200685477580" to type "System.Int32". Error: "Value was either too large or too small for an Int32."
Object
Objects can be very useful to represent data in Bicep. An object is a collection key/value enclosed by a {}. They are similar to HashMap in PowerShell.
param tags object = {
environment: 'dev'
department: 'IT'
}
You can access values from an object by using its key
Tags. environment
String
A string is a value enclosed by a single quote. It can use Unicode values between 0 and 10FFF (But you will use Latin characters most of the time).
You can escape reserved characters by using a backslash \
User-defined type
You can use a user-defined type for your parameter. A user-defined type is a datatype defined in a Bicep project that allows better control. See
type vmConfiguration = {
OSVersion: '2022-datacenter-azure-edition' | '2022-datacenter-azure-edition-core'
name: string
size: 'Standard_D2s_v3'
imageOffer: 'WindowsServer'
imagePublisher: 'MicrosoftWindowsServer'
}
param vmParams vmConfiguration
Decorators
Now that we have seen the Bicep parameter's basics, let's see how we can do with the parameters.
You can add controls, a description, or change the behavior of a parameter by using decorators.
A decorator is an expression starting with an @ . There are informational decorators that give information about the parameters, secure decorators, to secure data, constraint decorators to limit the input, and user-defined type related decorators.
Informational decorator
You can add a description to a parameter by using @descritption or @sys.description (if you have a parameter called description in your file). You can give a short text or a multiline markdown formatted text.
It can be a description or a text to help the user with the parameter.
@description('The name length should be between 3 and 24 car in lowercase letters or number')
param storageAccountName string
@description('''
Storage account name restrictions:
- The lenght should be between 3 and 24.
- lowercase letters or numbers only
''')
param storageAccountName string
The other informational decorator is @metadata. It allows you to add some information about the parameter. Azure Resource Manager ignores this decorator. You can use an object composed of one to several key/value pairs that describe the parameter.
@description('Configuration of the storage account')
@metadata({
kind: 'Storage account kind'
accessTier: 'Storage account accessTier'
})
param storageConfiguration object
Informational decorators are crucial to give more context to expected data for a parameter. It helps detect deployment errors and can help build accurate documentation and code completion in the AI age.
Secure decorator
The @secure operator applies to string and object only. It should be used on parameters containing a password, a secret, or a key. Using this decorator, you ensure the value is not logged or stored in the deployment history (but only if the value is used in Azure for a password, a key, or a secret).
constraint decorators
You need to use constraint decorators to apply some controls on a parameter. Bicep will trigger an error if the value is not what you expected. This is the case for allowed, maxValue, maxLenght, minValue, and maxLenght decorators.
The allowed decorator works on all types; it takes an array as an argument representing the only value permitted for the parameter.
@allowed([
'LRS'
'GRS'
'ZRS'
'GZRS'
])
param storageRundancy string
The maxValue and the minValue decorators only work on integer type. They define the maximum value and the minimum value of an integer parameter.
@maxValue(1224)
@minValue(24)
param diskSize int
Here, the disk size must be between 24 (included) and 1224 (included)
The maxLenght and the minLenght decorator are applied to strings and arrays. It takes an integer as an argument representing the string size or the number of items in the array.
@minLength(3)
@maxLength(24)
param storageAccountName string
user-defined type decorators
The last two decorators are related to user-defined type, discriminator, and sealed. They are linked to the object type and custom data type. They are more complex to understand and explain in a few lines.
If you create a custom data type in Bicep, you may misuse an optional property in a param like this (the ? at the end of the string indicates that surname is an optional property)
type myObject = {
name: string
surname: string?
}
param oneParama myObject = {
name: 'value'
surnqme: 'value'
}
If you use it like this, you only have a warning (but you will have an error if surname isn’t optional). The sealed decorator changes the behavior and raises an error instead of a warning.
The discriminator decorator is also used in the context of user-defined data type for the second decorator. Imagine you have a resource that can have different types of configuration depending on one parameter, it can be useful to have two kinds of objects to manage the two configurations. For example, for the Azure function, you have to choose a runtime stack, a version, and an operating system. You can use a custom type to manage these choices.
type azPWSHFunction = {
stack: 'PWSH'
version: '7.4'
}
type azPythonFunction = {
stack: 'PYTHON'
version: (['3.11', '3.10', '3.9'])
OS: 'Linux'
}
@discriminator('stack')
param azFunctionRunttime azPWSHFunction | azPythonFunction
Deploying with parameters
Now we see how to define parameters and use decorators to fine-tune their behavior, let's see how to use them.
The first thing you can use is to use either Azure PowerShell or Azure CLI to deploy the Bicep template and use parameter values in the command line.
new-azresourceGroupDeployment -Name demoSubDeployment -ResourceGroupName lab-routing -TemplateFile ./discriminator.bicep -parameterName “paramValue”
However, there are a few limits to this approach. First, as we have seen, PowerShell uses int32 while bicep uses int64, which limits the numbers you can use.
But this approach is error-prone when the number of parameters grows up.
In this case, you may want to use a parameter file instead of inline parameters. Bicep introduced the bicepparam file. This file must contain two types of information, the bicep template to be used, and the parameter and their value
using './param.bicep'
param storageAccountName = 'jdustorage887'
But you can also generate the bicepparam file from the template you want to use by using Azure CLI and Bicep.
az bicep generate-params --file param.bicep --output-format bicepparam --include-params all
This command will create a param.bicepparam file in the same location as the param.bicep file with all the parameters present in the bicep file. If a param has a default value, the value will be present in the bicepparam file.
To use the bicepparam file, you have to file all the values and then deploy the template using this PowerShell command.
New-AzResourceGroupDeployment -Name ParamDeployment -ResourceGroupName demoBicep -TemplateFile ./param.bicep -TemplateParameterFile ./param.bicepparam
You can mix biccepparm file and inline parameters (giving parameter values at the command line or in PowerShell). But if a parameter is present in both, only the inline value will be used.
As you see many things can be done with parameters. You can control what users will input to a template, you can raise an error and play with user-defined type to have a complete solution.
What's Your Reaction?