Automate Your Cloud with Azure Bicep
Azure Bicep is a great way to implement Infrastructure as a Code to automate the provisioning of Azure resources. It is a transparent abstraction of ARM templates and can be considered the “next generation” of these templates. In this post, I’ll get you started by describing how Bicep language works as well as key differences and similarities between Bicep and ARM Templates, which you may already use today in your Azure environment. We will also look at how to convert existing ARM Templates to Bicep lang.
Under the hood, whenever you deploy a Bicep file, it is converted to an ARM template first, so any resource that can be deployed via an ARM template can be altered through Bicep. After writing the Bicep code, you run Bicep build, and it converts it to an ARM template. When you deploy it, you don’t need to convert and deploy the ARM template. You can deploy the Bicep file directly via the Azure Resource Manager.
It has a much simpler syntax with no JSON noise. JSON was meant to be a language that machines understand, whereas a Bicep is meant to be readable to humans. It has a much smaller footprint when it comes to the creation of configuration files. It is a modular approach to building ARM templates and configuring your resources. Any Bicep file is a module by itself – and it is a reusable module. This reusability is the key feature of Bicep lang. There is no need to create anything extra, as any Bicep file can be treated as a module out of the box that you can deploy directly.
Basic Setup for Azure Bicep
When installing Bicep tools, there will be very little overhead. You only need to run the Bicep-related command lines. If you have Azure Command Line Interface (CLI) or Azure PowerShell already installed, they can be leveraged to deploy the Bicep files.
The recommended tool to develop your Bicep files is the Visual Studio Code. There is a lot of development going into the Bicep extension, which enables you to provide tab completion or code snippets directly out of the box in VS Code. Just have the Bicep extension installed and you are good to go.
Constructing Your First Bicep File
A Bicep file consists of four key parts: parameters, variables, resources, and output. Let’s take a closer look at each one.
You will want to create a parameter for any input that you want end users to provide during deployment. A parameter structure usually starts with the keyword ‘param’, followed by an identifier i.e. a name for the parameter, and the type (ex. String, Boolean, etc.). Finally, you’d provide an optional default value as such:
If you don’t provide a default value, you have to provide a value for this parameter during the deployment. If you have an optional default value provided, that value will be used and the end-user will not be prompted(they can optionally provide a value, but they will not be prompted for this parameter.)
You can also have descriptors for the variables.
The “@description” provides a user friendly description for the parameter. The “@allowed” defines all the allowed values that can be provided as an input for the parameter value.
Parameters and variables intermingle with each other. Both of these are reusable components that you can use in multiple locations in your Bicep file to create resources that will refer back to them when providing output data to end-users, etc. Basically, any input that you want the end-user to provide during the deployment should become a parameter and any value that is used or referenced multiple times (but not required as an input from the end-user during deployment) will instead be a variable.
A variable follows the same structure in that it begins with a keyword (var). Your variable is any value that is used or referenced multiple times. It is typically not required as an input from the end-user during deployment.
The Resource is the key section of your code that deploys everything. When writing the Resource, always start with the keyword ‘resource’ followed by a symbolic name for the resource.
Your symbolic name must be different from the name of the resource and should reference a specific resource within the Bicep project.
For every resource, you will have a type. You will also have multiple properties and they differ by the resource types.
E.g. Below is a public IP address resource. The definition starts with the keyword “resource”. Then “pip” is the symbolic name for this resource that you can reference in other resources. Then we have the type and API version defined in the quotes. This resource has a name, location, and other properties.
Also, note in the example above, how you can reference the name variable and the location variable directly, without using any complex syntax.
Your Output is any value you want to show after the deployment is successful. If you want to show a value to the end-user after the deployment, then you would include it in the Output.
You can add multiple comments to your Bicep files. These add readability to different sections. There are different types of comments, including single line, inline, and multi-line comments.
Single line comments start with “//”. These are not interpreted. Multi-line comments start with “/*” and end with “*/”.
How Does Bicep Compare to ARM Templates?
While Bicep and ARM Templates share the same purpose and are deployed similarly, Bicep does have several key differences. Ultimately the goal is to provide a more powerful way to implement Infrastructure as Code that is also more user-friendly.
Bicep files have a very small footprint. They feature less text than an ARM template and are much easier to reference anything as you address parameters by their name instead of typing all the below syntax in ARM Templates:
Bicep files use variables directly by their name and reference other resources using their symbolic names directly as below:
Another key distinction is different scope definitions. You can deploy the resources defined in a Bicep file in different scopes at the same time. Each individual resource can have a scope. By default, the scope is your resource group.
If you are going to create a resource group with your Bicep file, then the scope for that resource group has to be something higher than the resource group within your subscription. If you are performing deployments or changes at the subscription level using your Bicep file, then you can even define a scope as a management group, which would be a combination of multiple subscriptions.
There are two scope levels for a Bicep file. One is for the whole Bicep file, the other is defined at each individual resource level. E.g. if you have four resources in a Bicep file; three can get deployed in the same resource group which is the default scope for the whole Bicep file, while the fourth can have a scope that would be entirely different from the first three.
Finally, there is a new string interpolation syntax for Bicep which is much simpler, utilizing a dollar sign, then the variables directly within the quote symbols when formulating the syntax string.
The underlying API for ARM templates and Bicep files is the same. When you are executing the deployment, it translates any Bicep file into an ARM template, then it leverages the ARM APIs to perform the deployment. If you are using a parameter file structure, nothing has changed. You leverage thesame parameter file structure as you do with an ARM template. The parameter file structure, even with the ARM template is still very simple (parameter name= value that you want to provide).
Any valid ARM template function is therefore still a valid Bicep function. All the ARM template functions you may rely on can still apply in the Bicep world.
Converting ARM Templates to Bicep
Converting ARM templates to Bicep is called decompiling ARM templates. Compiling a Bicep file would mean converting a Bicep file into an ARM template. The command is very simple:
bicep decompile “path to json file”
This decompiling process is a best effort process. You still need to understand the different Bicep components are and how Bicep works to confirm the conversion.
If you have a complex operation and the Bicep decompile command is not able to perform the conversion, another option you have is Bicep Playground. It’s a web app you upload your JSON files to, and it shows you the corresponding Bicep file.
You can find Bicep Playground here: https://aka.ms/bicepdemo
Finally, if you know how to construct a Bicep file utilizing parameters, variables, resources, and outputs, you can perform a manual conversion.
While Bicep syntax is relatively simple to get started with, there are many advanced concepts that can provide additional functionality and automate additional resources within your Azure environment. Some of these include:
- Symbolic reference names
- Referencing existing resources
- Modules and nested deployments
Part of the fun of automation is combining these elements to see how you can improve your overall process! You can learn more about Bicep on the Azure documentation portal. Lunavi is also ready and able to help you implement Infrastructure as Code to optimize your cloud operations. Contact us today if you’re ready to take the next step with Azure Bicep but need a little help getting there.