When you work with Infra structure as code, you want flexibility. It wouldn’t make sense to make templates for every resource(group) you need. Instead, you can make templates reusable by using parameters. But what methods can you use? There are several options which all have their own use case. In this post, I will show you different ways to work with parameters in Bicep and what choice you can make.
Example template
To illustrate this post, I have created an example template which I want to deploy with parameters. It’s the following file:
I will show how I would add the different types of parameters to this template using a few different methods.
Add inline parameters to deployment cmdlet
The simplest way to use parameters is to do this in the New-AzResourceGroupDeployment
cmdlet. When you define a template you want to deploy, in PowerShell the possible parameters will be automatically available through tab complete. This method can be combined with all the other options in this post. It will always overrule the parameters defined. This can be useful if you have a few parameters that are often the same and just want to change one or two.
This looks like this:
New-AzResourceGroupDeployment -ResourceGroupName example -TemplateFile .\main.bicep -staPrefix 'ps' -isPremiumSKU $true -tagsValues @{'parameterkind' = 'powershelldirect' } -Verbose
Pro’s
- Very quick to set up, no separate file needed
- Autocomplete in PowerShell makes it easier to deal with
- Can be changed easily
Con’s
- This becomes messy and unreadable pretty quickly, as you can see. Especially with non-string parameters. You can solve this with Parameter splatting, but then you use the autocomplete option.
- This isn’t that auditable. If you have templates with multiple parameterfiles, you can get an overview in your repository of what parameters are send to what file. You lose that ability with this method. Especially when you don’t work interactively, it’s easy to get confused.
Use case
- Quick deployment and testing
- Overrule set parameters, for example in a pipeline.
PowerShell hash tables in PowerShell
In PowerShell you can create hash tables. These can be used as a parameterobject. The New-AzResourceGroupDeployment
cmldet has the parameter TemplateParameterObject
for it. If you use this in a full script with PowerShell parameters, you can create a deployment script to deploy by calling it.
You would use it like this:
$Date = Get-Date -Format 'yyyy-MM-dd' $DeploymentParameters = @{ staPrefix = 'psobject' isPremiumSKU = $true tagsValues = @{ 'parameterkind' = 'powershellobject' 'deploymentTime' = $Date } } $Parameters = @{ ResourceGroupName = 'example' TemplateFile = '.\main.bicep' TemplateParameterObject = $DeploymentParameters } New-AzResourceGroupDeployment @Parameters -Verbose
(I have used splatting to keep the Parameters readable)
Pro’s
- This method is more readable than using just the deployment cmdlet
- The parameters are a hash table. You can use PowerShell logic to change it dynamically before passing it to the deployment cmdlet
Con’s
- When you create dynamic parameters, it could be hard to see what would be deployed just based on the files in the repository
Use case
- When you want to use PowerShell logic to set up the parameters
A Parameter file
Just like with ARM templates, you are able to use a parameter-file to store your parameters. At this point in time, you will use the same files as you use with ARM templates. So that would be a file called something like main.parameters.json.
The format is json. Let’s look at how that would look for the example templates.
You will deploy the template with PowerShell or the Az Cli, by using the -TemplateParameterFile
parameter.
Pro’s
- The parameters will be saved in the same repo as the template. This makes the resulting deployment very clear just by reading the code
- The parameter files can be copied and adjusted for similar environments
- You have some extra options, like refering a key vault (although I recommend using getSecret in the Bicep file itself)
Con’s
- The format is JSON (JSONC) and there are rules for the formatting
- You are not allowed to use comments in JSON files. For ARM templates, they are officially accepted. The deployment will not fail if you do, but to me it always feels iffy. That means you can’t give any guidance on the parameters in the parameterfiles.
- You are not able to use secret values directly in the file.
Use case
- When you are creating environments you want to redeploy literally
- When you want to keep the parameters that you used in the repo as part of the code.
LoadTextContent with a JSON config file
This option is the only one in the bunch that is specific for Bicep (although you could work with a JSON config from a PowerShell script).
When using this option, you create a JSON file with the config that fits your needs. In this case, you don’t have to stick to formatting rules, you can structure it to your own needs. This method works very well when you combine it with one of the other parameter options. Let’s take a look at a possible solution for our template.
I created a JSON file like this:
( the namesetting
level isn’t really needed for this example, I added it to show you are able to create your own categories)
Now you do need to change the template to make use of this. In this case I have added all parameters through the JSON config file as an example.
Pro’s
- You are able to structure your JSON file as you want, making it more readable.
- You are able to combine this method with other parameter options
Con’s
- This method is relatively new and you might need to educate your team
- The template file needs to be changed to start using this method, it isn’t really a stand alone solution
Use case
- For parameters that are the same for multiple Bicep files, like NSG rules
Conclusion
So that is how you work with parameters in Bicep. I hope this has helped as a bit of an overview. If you want to know more about each method, you can follow the links below for the Microsoft Docs. If you have any questions, leave them in the comments.
Add inline parameters to deployment cmdlet
PowerShell objects in PowerShell
You are officially allowed to use comments in JSON parameters file and template files since it’s JSONC (JSON with comments).
In JSON, they are officially not allowed and all documentation considers ARM templates to be JSON. But they are allowed in ARM templates, so I have reworded the line to make that a bit more clear. Doesn’t change that it feels iffy to me 🙂
Pingback:Azure Top 5 for December 27, 2021 | Jeff Brown Tech