Azure Bicep is a powerful tool that helps simplify cloud resource management by providing a declarative syntax for infrastructure as code. It's a game-changer for anyone who wants to manage their Azure resources efficiently.
With Bicep, you can define your infrastructure as code, making it easier to version, reuse, and manage your resources. This approach reduces errors and increases consistency.
Azure Bicep is an open-source framework that's part of the Azure SDK, which means it's tightly integrated with Azure services. This integration enables features like resource dependencies and parameterization.
By using Bicep, you can create templates that are easy to read, write, and maintain, making it a great choice for teams and individuals alike.
What Is Azure Bicep?
Azure Bicep is a domain-specific language (DSL) for deploying Azure resources declaratively. It's designed to simplify the authoring experience with a cleaner syntax and improved type safety.
Bicep is a transparent abstraction over ARM and ARM templates, meaning anything that can be done in an ARM Template can be done in Bicep.
Azure Bicep has better support for modularity and code re-use, making it a great tool for managing infrastructure as code.
Bicep code is transpiled to standard ARM Template JSON files, effectively treating the ARM Template as an Intermediate Language (IL).
You won't be able to use Bicep to deploy non-Azure resources or work in other cloud providers like AWS or GCP.
Azure Bicep is OpenSource, with its source code freely available on GitHub, which has contributed to its growing development community.
Bicep's simplified syntax makes it easier to learn and use compared to Microsoft Azure Resource Manager (ARM) templates.
Getting Started
To begin with Azure Bicep, you need to install the tooling on your local system. Microsoft has several options for installing this tooling across Windows, Linux, and macOS.
You can find a rich library of examples in the azure-quickstart-templates repo to help you get started. This is a great resource to explore and learn from.
Here are the basic steps to get started with Bicep:
- Start by installing the tooling.
- Complete the Bicep Learning Path
By following these simple steps, you'll be well on your way to using Azure Bicep for your infrastructure-as-code needs.
Benefits of
Azure Bicep is a game-changer for infrastructure-as-code, and its benefits are numerous.
With a fast-growing online community and Microsoft's support, Bicep is becoming the go-to choice for developers.
Its simplified syntax makes it a breeze to use, especially compared to ARM templates.
Developers can divide their code into manageable modules, each deploying a set of related resources.
This modularity simplifies the development process and speeds up code reuse.
Azure Bicep also provides a rich authoring experience with Visual Studio Code (VS Code), offering features like intellisense and syntax validation.
The tool is idempotent, meaning you can deploy the same file multiple times without worrying about updates.
No state or state files are needed, making collaboration a breeze for multiple users.
Azure Bicep's Resource Manager simplifies the deployment process, allowing you to deploy resources in the correct order and even in parallel for a faster finish.
Here are the key benefits of Azure Bicep:
- Support for all resource types and API versions
- Simplified syntax
- Modularity
- 1st class authoring experience with Visual Studio Code (VS Code)
- Idempotent files
- No state or state files to manage
- Resource Manager
- Open-source, with Microsoft support
Get Started
To get started with Azure Bicep, you'll want to install the tooling on your local system. You can find installers for Windows, Linux, and macOS on the project's GitHub page.
The first step is to complete the Bicep Learning Path, which will give you a solid understanding of how to use Azure Bicep. This will help you learn the basics of infrastructure-as-code and how to deploy resources on Azure.
There's also a rich library of examples in the azure-quickstart-templates repo that can help you get started with Azure Bicep. These examples will give you a head start on learning how to use Azure Bicep and will help you understand how to deploy resources on Azure.
To install Azure Bicep, you can use the Bicep CLI, which is available for Windows, Linux, and macOS. The Bicep CLI allows you to compile Bicep files into ARM JSON templates and also decompile ARM JSON templates into Bicep files.
Here are the steps to install the Bicep CLI:
- Download the installer from the project's GitHub page
- Run the installer on your local system
- Add the install location to your PATH environment variable
Alternatively, you can use the installation scripts provided by Microsoft, which will automatically download and install the Bicep CLI for you.
Conditional Assignment
Conditional Assignment is a powerful feature in Bicep that allows you to set a value based on different conditions. This is done using the ternary operator, which is similar to an if-then-else statement.
You can use the ternary operator to determine the sku of a storage account, for example. If the boolean parameter 'useSSD' is set to true, the storage account uses the Premium_LRS SKU; otherwise, it uses the Standard_LRS SKU.
Here's an example of how you can use the ternary operator:
```html
sku: { name: useSSD ? 'Premium_LRS' : 'Standard_LRS' }
```
This will set the sku to Premium_LRS if useSSD is true, and Standard_LRS otherwise.
Conditional assignments can also be used to set the name of a resource, for example:
```html
var stgAcctName = '${name}2468'
resource stgAcct 'Microsoft.Storage/storageAccounts@2021-02-01' = {
name: stgAcctName
...
}
```
In this example, the name of the resource is set to the value of the variable stgAcctName, which is constructed using the ternary operator.
Conditional assignments are a key feature of Bicep that allows you to create flexible and dynamic templates. By using the ternary operator, you can set values based on different conditions, making it easier to create reusable and maintainable templates.
Target Scope Subscription
So, you're getting started with Bicep and you want to know about target scope subscription. Deployment target scopes are a crucial aspect of Bicep, and understanding them will help you deploy resources efficiently.
The target scope for a Bicep file is set implicitly or explicitly, and it's used to perform validation and checks on the resources in the template. This scope can be one of four possible values: resourceGroup, subscription, managementGroup, or tenant.
To deploy a resource group, your target scope is likely to be subscription or higher. This is because setting the target scope to resourceGroup doesn't make sense when creating a resource group in a template.
Let's take a look at the possible values for target scope:
- resourceGroup (default)
- subscription
- managementGroup
- tenant
Now, let's talk about deploying resources at the subscription target scope. Resource group resources have to be deployed at the subscription scope, so you can simply deploy them in the main file. Storage account resources, on the other hand, need to be deployed at the resourceGroup scope, so you'll need to use modules to deploy them at a different scope.
How It Works
To author Bicep code, you use the Bicep language service as part of the Bicep VS Code extension.
You can also write Bicep code in Az CLI (version 2.20.0+) or the PowerShell Az module (version 5.6.0+), which will transpile the code and send it to ARM on your behalf.
To deploy a Bicep file, you can use a standard deployment command, such as az deployment group create, and point it to your *.bicep file.
How It Works
Bicep works by authoring your code using the Bicep language service as part of the Bicep VS Code extension.
You can use the standard deployment commands with your *.bicep files and the tooling will transpile the code and send it to ARM on your behalf.
Az CLI (2.20.0+) and the PowerShell Az module (v5.6.0+) have Bicep support built-in.
To deploy main.bicep to a resource group, you can use the CLI command you're already used to: az deploy -f main.bicep -g my-rg.
For more detail on taking advantage of new Bicep constructs, you can read the moving from ARM => Bicep doc.
Resource Declaration
A Bicep template's primary component is its resource declaration, which is used to define the Azure resource you want to deploy. The resource declaration follows a basic framework.
The framework starts with the resource declaration line, which includes the symbolic name, type, and API version. This line is crucial as it tells Bicep what type of resource you want to deploy and which version of the API to use.
The symbolic name is used to reference the resource within the template, while the type and API version ensure compatibility and accuracy. For example, the symbolic name is 'stgAcct' in the storage account template.
The remaining properties are defined within the curly brackets, including required properties like name and location. These properties are specific to the type of resource being deployed.
The example of a storage account template shows how to declare a resource with its properties. The template defines the resource type as 'Microsoft.Storage/storageAccounts@2021-02-01' and its properties, including name, location, kind, and SKU.
Here's a breakdown of the required properties:
- name: The name of the resource.
- location: The Azure region where the resource will be deployed.
These properties are essential in defining the resource and its deployment location.
The remaining resource-specific properties are defined within the curly brackets, such as kind and SKU in the storage account template. These properties are specific to the type of resource being deployed and are used to configure it according to your needs.
String Interpolation
String Interpolation is a powerful feature in Bicep templates that allows you to define strings using parameter or variable names, and Bicep will evaluate the final string using the actual values.
You can use string interpolation instead of concatenation functions like concat() to create a single string. For example, instead of using the concat() function in the variable declaration, you can surround the parameter name with ${ }.
This means you can simply write var stgAcctName = '${name}2468' to achieve the same result as the concat() function.
String interpolation is a more elegant and readable way to create strings in Bicep templates.
It's worth noting that string interpolation is just one of the many features that makes Bicep templates more efficient and easier to work with than ARM templates.
Arm Api Stage
The Arm Api Stage is a crucial part of the Azure Bicep deployment flow. It involves the deployment of the generated Arm template, along with a parameters file, to the Azure Resource Manager API for processing.
During this stage, the Arm API first runs a template validation, which checks the template for syntactical correctness, parameter types, and required parameters.
If the template is invalid, the Arm API executes internal procedures to fail the deployment.
Deployment-time constants are values that can be determined before the start of this phase and are used to determine what the template will look like.
These constants can include parameters passed to the deployment, which are used to determine which resources and how many will be deployed.
The Arm Api Stage is a critical step in the Azure Bicep deployment flow, and understanding its intricacies is essential for successful deployments.
Here are the key components of the Arm Api Stage:
- Template validation: checking the template for syntactical correctness and required parameters
- Deployment-time constants: values determined before the start of this phase, used to determine the template's structure
- Parameters: values passed to the deployment, used to determine which resources and how many will be deployed
The Arm API stage is where the generated Arm template is uploaded to the Azure Resource Manager API for processing. This stage is critical for successful deployments, and understanding its intricacies is essential for Azure Bicep developers.
Parameters vs Variables
Parameters and variables are essential components of Bicep templates, allowing you to make your templates more dynamic and reusable.
You declare parameters using the `param` keyword, specifying the parameter name, type, and optionally a default value. For example, the `name` and `location` parameters in the storageAccount.bicep template have string types and default values, respectively.
Parameters can also be annotated to set constraints, such as secure strings or allowed values, and can include descriptions to clarify their purpose. This makes it easier to reuse a Bicep file for different environments.
Variables, on the other hand, are used to simplify your Bicep file development by containing complicated expressions that can be dropped in as needed. The `stgAcctName` variable in the storageAccount.bicep template performs a string concatenation of the `name` parameter and some numbers.
Variables do not require a specified data type, as it is implied by the expression and value they contain. This allows you to write more concise and readable code.
Here are some key differences between parameters and variables:
By using parameters and variables effectively, you can make your Bicep templates more dynamic and reusable, and simplify your code development process.
Load Content Functions
The LoadTextContent and LoadJsonContent functions are specific to Bicep and can make a big difference when working with ARM templates.
These functions are compile-time functions, meaning they're run during the compilation phase on your local machine.
The LoadTextContent function was introduced in Bicep v0.4, and LoadJsonContent is available from version 0.7 onwards.
You can use these functions to load the content of files into your template, which can be really helpful for resources that require JSON, XML, or script files as properties.
The most common use-cases for these functions are Azure Policies, Deployment Scripts, and API-Management APIs that can take openAPI specifications.
You can't use parameters to specify which file to load into an ARM template, so you'll need to use compile-time arguments.
The LoadTextContent function has a serious limitation - the length of a string in an ARM template can't be more than 131,072 characters, or about 9 KB binary file size.
Migrations and Desired States
State-based solutions like Bicep or ARM templates try to take the current state of infrastructure and compare it to the desired state, but this isn't always possible.
You can't always split one data blob into two new ones and remove the old in a single template, as deploying in complete mode will remove the old blob before the data is copied. A single script can do the create, copy, and then delete operations.
Both Azure PowerShell and Azure CLI commands are idempotent, so they can be re-run as needed. However, a real migration solution usually needs some kind of journal ability, like a journal table, to know which scripts have run and only needs to run new scripts.
Migrations vs Desired States
Migrations allow for incremental change, which is important where a state-based solution can't handle the desired change.
State-based solutions like Bicep or ARM templates try to take the current state of infrastructure and compare it to the desired state, but this isn't always possible.
You can't split one data blob into two new ones in a single template, as deploying in complete mode will remove the old blob before the data is copied.
A script can do the create, copy, and then delete operations, which is a more flexible approach.
Some properties can only be set at creation, so changing them in a template has no effect or generates an error.
A script can create a brand new resource, copy across all the settings, change any references, and then remove the old.
Azure PowerShell and Azure CLI commands are idempotent, so they can be re-run as needed.
A real migration solution usually needs some kind of journal ability, so it knows which scripts have run and only needs to run any new scripts.
Converting Templates
You can manually convert a Bicep template to an ARM template using the bicep build command. This command is specified with the path to the Bicep template file. For example, to convert the storageAccount.bicep Bicep template to an ARM template, use the command bicep build storageAccount.bicep.
With the converted ARM template, you can deploy it using the Azure PowerShell New-AzResourceGroupDeployment command or the Azure CLI az deployment command.
Bicep also provides a way to convert existing ARM JSON templates to Bicep templates. This can be done using the bicep decompile command, like so: bicep decompile storageAccount.json. However, keep in mind that the decompilation process is a best-effort process, and Microsoft does not guarantee a direct mapping from ARM JSON to Bicep.
If you encounter an issue decompiling, you can report an issue or inaccuracy on the Bicep GitHub Issues page.
Target Scopes: ManagementGroup and Tenant
You can deploy a resource group at a target scope other than subscription, such as managementGroup or tenant, but it requires some extra steps.
To deploy a resource group at a scope other than subscription, you need to use Bicep modules to specify the right scope.
The target scope possible values for managementGroup and tenant are: managementGrouptenant
You need to specify the correct scope for the module, which should be subscription for a resource group.
Deploying at the tenant scope is almost identical to deploying at the management group scope, the only difference being the targetScope of the file.
You need permissions at the tenant level to be able to deploy at the tenant scope.
Frequently Asked Questions
Is Azure Bicep production ready?
Yes, Azure Bicep is production ready. Learn more about its capabilities and best practices for implementation.
What is the alternative to Bicep in Azure?
For Azure, Terraform is a popular alternative to Bicep, offering cloud-agnostic infrastructure as code management. This open-source tool provides flexibility and scalability for managing Azure resources.
Featured Images: pexels.com