šŸ’ŖAzure Bicep: working with Parameters ā€” Best practices

Dave R - Microsoft Azure MVPā˜ļø
CodeX
Published in
6 min readSep 22, 2021

--

When and how should you use parameters in your Azure Bicep templates.

In Azure Bicep, the new domain-specific language (DSL) to declarative deploy Azure resources, we define parameters just as we did in ARM templates. There are a few differences in the syntax we should consider.

Azure Bicep ā€” Parameters

Parameters in Azure Bicep

Parameters are input values we define in the Bicep template. These values can be passed on either inline during the deployment operation or referenced from a Parameters file.

Declaring parameters in Azure Bicep

You need to provide a name and type for each parameter in your Bicep template. The code below shows how to declare parameters:

param demoString string
param demoInt int
param demoBool bool
param demoObject object
param demoArray array

A parameter canā€™t have the same name as a variable, module, or resource. Donā€™t overuse parameters. Parameters are often utilized when we need to pass on values that need to vary for different deployments.

For example, when you create a storage account, you need to provide the SKU and type; you could leverage parameters.

If you need to define a virtual network and subnets, you could leverage a parameter object for the virtual network and the subnet definition.

Try to provide descriptions for your parameters as much as you can. Your team and colleagues will appreciate it.

Resource Manager resolves parameter values before starting the deployment operations. Now letā€™s take a quick look at the supported data types.

Azure Bicep ā€” parameter data types

Azure Bicep supports the following parameter data types:

  • array
  • bool
  • int
  • object
  • secureObject and secureString ā€” indicated by @secure() decorator
  • string

If youā€™re wondering what decorators are, decorators in Bicep can be used to specify constraints and metadata for a parameter.

Hereā€™s a list of decorators available in Bicep:

  • allowed
  • secure
  • minLength & maxLength
  • minValue & maxValue
  • description
  • metadata

When should you use decorators?

Hereā€™s an example, if you want to deploy a virtual machine, you can use a parameter with the @secure() decorator to pass on the password for the username. The password is not logged nor stored in the deployment history.

The following article explains how you can use the @secure() decorator: https://blog.azinsider.net/azure-bicep-secure-secrets-in-parameters-secure-decorator-ce6317cc0c23

The code below shows a few examples of parameters and the @secure() decorator:

// Username for the Virtual Machine.
param adminUsername string
// Type of authentication to use on the Virtual Machine. SSH key is recommended.
param authenticationType string = 'sshPublicKey'
// SSH Key or password for the Virtual Machine. SSH key is recommended.
@secure()
param adminPasswordOrKey string

In the above code, we defined string type parameters and a third parameter for the password or key with the @secure() decorator.

Try to add comments to provide more context or information about the parameter.

Hereā€™s another example, it shows the use of the ā€˜minLength and maxLengthā€™ decorators:

@minLength(3) 
@maxLength(11)
param storagePrefix string

You can add one or more decorators for each parameter. You can define parameters in any place of your Bicep template; they will compile into the parameters section in the ARM template.

Hereā€™s another best practice: To minimize potential errors during deployment, remember to specify the minimum and maximum character length for parameters that control naming, like storage accounts.

Similar to ARM templates, you can use arrays, objects, string, int, and bool values:

param myArr array = [
'one'
'two'
'three'
]
param myObj object = {
name: 'Mike'
age: 32
}
param myString string = 'string'
param myInt int = 100

You can also use parameters as a form factor to create another parameter:

param storageNamePrefix string = ''
param storageAccountName string = '${storageNamePrefix}storage'

In the above code, we are interpolating the ā€˜storageNamePrefixā€™ to create the storage account name.

What about functions?

You can also leverage functions to create parameter values, just as in ARM templates. The code below shows how to define the location of the resources.

// Location for all resources.
param location string = resourceGroup().location

In Bicep, you can use multiline parameters. I havenā€™t used that much, but you can try yourself:

param myParam string = '''
This is the first line
this is the second line
third line'''

The above code will result in the following JSON:

"parameters": {
"myParam": {
"type": "string",
"defaultValue": "This is the first line\nthis is the second line\nthird line"
}
},

As you already notice, working with parameters in Bicep is pretty flexible and straightforward.

Now that we have reviewed some basics about parameters is time to get into the deployment operation.

At the beginning of this article, I mentioned two options for passing parameters: inline and using a parameters file.

Inline parameters

Using this approach, you can define the parameters at deployment time. The default value is used when a value isnā€™t provided during deployment.

The code below shows an example of a few parameters to create a virtual machine.

// The name of your Virtual Machine.
param vmName string = 'flowmonVm'
// Username for the Virtual Machine.
param adminUsername string
// Type of authentication to use on the Virtual Machine. SSH key is recommended.
param authenticationType string = 'sshPublicKey'
// SSH Key or password for the Virtual Machine. SSH key is recommended.
@secure()
param adminPasswordOrKey string
// Unique DNS Name for the Public IP used to access the Virtual Machine.
param dnsLabelPrefix string = toLower('flowmon-${uniqueString(resourceGroup().id)}')
// Location for all resources.
param location string = resourceGroup().location
// The size of the VM.
param vmSize string = 'Standard_B4ms'
// Name of the VNET.
param virtualNetworkName string = 'vNet'
// Name of the subnet in the virtual network.
param subnetName string = 'Subnet'
// Name of the Network Security Group.
param networkSecurityGroupName string = 'SecGroupNet'

To reference the value for a parameter, you need to use the parameter name. In the code below, we are passing on the parameter ā€˜locationā€™:

resource nic 'Microsoft.Network/networkInterfaces@2020-06-01' = {
name: networkInterfaceName
location: location
properties: {
ipConfigurations: [

Parameters can be passed on during the deployment operation as shown in the code below:

New-AzResourceGroupDeployment `
-Name BicepTemplateDeployment `
-ResourceGroupName az-insider`
-TemplateFile ./main.bicep `
-storageAccountName azinsiderstgacc

Now letā€™s look at the second option to pass on parameters: using a parameter file.

Deploy Bicep file using a parameter file

Instead of passing the inline values for the parameters, you can create a parameters file with the parameter values. This parameters file is a JSON file with the actual parameter values.

Like ARM templates, you can have the Bicep template ā€˜main.bicepā€™ and a parameters file called ā€˜main.parameters.jsonā€™.

The code below shows an example of a parameters file:

{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"<first-parameter-name>": {
"value": "<first-value>"
},
"<second-parameter-name>": {
"value": "<second-value>"
}
}
}

Be aware that the parameter types in your parameter file must use the same types as your Bicep file.

Then, you can deploy your Bicep template using Azure PowerShell or Azure CLI. The code below shows how you deploy the Bicep template with a parameters file using Azure PowerShell:

New-AzResourceGroupDeployment -Name BicepDeployment -ResourceGroupName MyResourceGroup `
-TemplateFile C:\MyTemplates\storage.bicep `
-TemplateParameterFile C:\MyTemplates\storage.parameters.json

In the above code, we use the -TemplateFile and -TemplateParameterFile to reference the Bicep template and the parameters file.

Lastly, it is worth mentioning that Bicep allows you to use a local parameters file and inline parameters for your deployment. It is also possible to reference an external file; however, if you use this approach, you will not be able to use a local file or pass on inline values.

I hope this gives you a better understanding of how parameters work in Azure Bicep.

Join the AzInsider email list here.

-Dave R.

--

--