Organizing Resource Deployments Using Bicep

In the realm of cloud infrastructure management, efficient organization and deployment of resources are paramount. With Bicep modules, we can take resource deployment to the next level by organizing and simplifying our deployments. In this article, we will explore how Bicep modules can improve the readability, reusability, and maintainability of our infrastructure as code.

When working with Bicep, we often come across complex deployment scenarios that require multiple resources to be provisioned together. Bicep modules allow us to encapsulate these deployment details into reusable components, making our code more modular and easier to understand.

This is a new series of articles about ‘BiCep’ technology by Microsoft – it is a game changer for resource management in the cloud – well worth investigating if you are a cloud builder!

Key Takeaways:

  • Bicep modules enable the organization and encapsulation of deployment details.
  • Modules can be easily reused for different deployments.
  • Modules can be shared with others through template specs or registries.
  • Dependent modules can be defined using the dependsOn property.
  • Modules can be deployed conditionally and iteratively for more flexibility.

Creating Bicep Modules

In Bicep, modules are a powerful way to organize and encapsulate deployment details, making your resource deployments more manageable and reusable. Let’s explore the syntax, path, and parameters involved in creating Bicep modules.

Module Syntax

When defining a Bicep module, you use the module syntax, which includes the symbolic name, module path, and optional parameters. The module syntax looks like this:

module symbolicName = {
path =

The symbolicName is a symbolic representation of the module and will be used to reference the module in other parts of your Bicep file. The modulePath specifies the location of the module file, which can be a local file or a file in a module registry. Let’s explore the module path in more detail.

Module Path

The module path represents the location of the module file. It can be specified as a local file or a file in a registry, such as the public module registry or a private registry. Here’s how you can define the module path:

  1. If the module file is a local file, you can use a relative path. For example:

path = “./modules/myModule.bicep”

  1. If the module file is in the public module registry, you can use the predefined alias ‘br/public’. For example:

path = “br/public/myModule”

  1. If the module file is in a private module registry, you can use the following syntax:

path = “”

Replace registryName with the name of your private registry. Now that you understand how to define the module path, let’s explore module parameters.

Module Parameters

Parameters in a Bicep module allow you to pass values from the parent Bicep file to the module. They help customize and configure the behavior of the module based on your requirements. To define parameters in a Bicep module, you can use the following syntax:

param parameterName type = defaultValue

The parameterName represents the name of the parameter, the type defines the data type for the parameter, and the defaultValue sets the default value if no value is provided from the parent Bicep file.

With module syntax, module paths, and parameters, you have the building blocks to create and reference Bicep modules effectively. By leveraging modules, you can simplify your deployments and promote reusability across different projects.

Benefit Description
Modularity Break down complex deployments into manageable modules, improving readability and maintainability.
Reusability Easily reuse modules across different deployments, saving time and effort.
Parameterization Customize module behavior by passing parameters from the parent Bicep file.

Now that we have a clear understanding of module creation, let’s move on to Section 3 to explore module deployment and configuration.

Module Deployment and Configuration

When deploying modules in Bicep, there are various configuration options available to ensure smooth and efficient deployment of resources. Let’s explore some of these options:

Parallel Deployment and Dependencies

By default, modules are deployed in parallel, optimizing the deployment process and reducing overall deployment time. However, if a module has dependencies on other modules or resources, these dependencies can be explicitly defined using the dependsOn property in the module definition. This ensures that the dependent modules or resources are deployed before the current module.

Conditional Deployment

In some cases, you may want to deploy a module conditionally based on certain criteria. Bicep allows for conditional deployment using the if expression. By utilizing this expression, you can control whether a module gets deployed based on specific conditions, such as environment variables or parameters.

Iterative Deployment with Batch Size

In certain scenarios, you may need to deploy multiple instances of a module, such as when deploying resources across different regions or environments. Bicep provides the for expression with the batchSize decorator, allowing you to specify the number of instances to be deployed at once. This iterative deployment approach gives you greater flexibility and control over the deployment process.

Scope of Modules

The scope of a module refers to its deployment scope, which can be different from the main Bicep file’s scope. By adding the scope property to the module definition, you can specify where the module should be deployed. This allows you to deploy modules to different scopes within your Azure environment, providing a more granular and targeted deployment strategy.

Module deployment in Bicep offers flexibility and control over how resources are deployed. By utilizing these configuration options, you can optimize your deployment process, manage dependencies effectively, and ensure smooth resource provisioning in Azure.

Path to Module

In Bicep, a module can be sourced from different locations, depending on the specific deployment requirements and preferences. These locations include:

  • Local File: A module can be stored as a local file, allowing for easy access and management within the same directory as the main Bicep file. To reference a local module, the module path is specified using a relative path, indicating the file’s location on the local filesystem.
  • Public Module Registry: Bicep provides a public module registry, which serves as a centralized repository for storing and sharing modules. Modules hosted in the public registry can be accessed by specifying the predefined alias ‘br/public’ as the module path. This allows users to easily leverage community-contributed modules and maintain consistency across multiple deployments.
  • Private Module Registry: For organizations that require greater control and privacy over their modules, Bicep supports private module registries. These registries can be hosted on Azure Container Registry (ACR) or other private repositories. To reference modules from a private registry, the module path is specified using the ‘’ scheme, allowing for secure and controlled access to modules.
  • Template Spec: Bicep also provides integration with Azure Template Specs, which define a specific versioned template and its associated artifacts. Template specs are referenced using the ‘ts://:’ syntax, providing a way to source modules directly from a template spec and ensuring consistent and controlled deployment across environments.

“Bicep offers flexibility in sourcing modules from various locations, allowing users to choose the most suitable approach based on their deployment needs and organizational requirements.”

The table below summarizes the different paths to modules and their corresponding specifications:

Module Location Module Path Format
Local File Relative path to the module file
Public Module Registry br/public
Private Module Registry br:<registry-name>
Template Spec ts:<sub-id>/<rg-name>/<template-spec-name>:<version>

By leveraging these different module sourcing options, Bicep provides a flexible and efficient approach to building modular and reusable infrastructure deployments.


Bicep modules provide a powerful and efficient solution for organizing and simplifying resource deployments in Azure. By encapsulating deployment details and promoting reusability, these modules greatly enhance the maintainability and organization of infrastructure as code.

Whether you choose to utilize the module registry or template specs, Bicep modules offer a seamless deployment experience, contributing to a more efficient and scalable workflow. With Bicep modules, managing and deploying Azure resources becomes streamlined and easily manageable, allowing you to focus on other critical aspects of your projects.

By leveraging Bicep modules, your organization can achieve enhanced organization and maintainability, leading to improved collaboration among development teams. The modularity and encapsulation provided by Bicep modules enable different teams to work on specific modules, reducing the chances of conflicts and errors in resource deployment.

Overall, Bicep modules are a game-changer for resource deployment in Azure. With their ability to organize deployments, improve maintainability, and promote collaboration within your organization, Bicep modules are an indispensable tool for any organization seeking to optimize their infrastructure as code.


Right then, enough learning, go get cloud-lifting with Bicep 😀


Using Variables in Bicep

Variables in Bicep are a crucial feature for enhancing the readability, maintainability, and flexibility of your Azure Resource Manager (ARM) templates. They allow you to store and reuse values, making your code more concise and easier to manage. In this guide, we’ll explore the various aspects of using variables in Bicep, including how to define them, use them in resource definitions, expressions, outputs, and configuration settings.

This is a new series of articles about ‘BiCep’ technology by Microsoft – it is a game changer for resource management in the cloud – well worth investigating if you are a cloud builder!

Key Takeaways:

  • Variables in Bicep enable the definition of reusable expressions.
  • Using variables simplifies the development process.
  • W word of caution! … there is a limit of 256 variables per Bicep file., so don’t exceed this limit.
  • Variables can be used in various contexts, such as resource properties, output values, and iterative loops.

Defining Variables in Bicep

In Bicep, you can define variables using the ‘var‘ keyword followed by the variable name and its value. Here’s the syntax to define a variable in Bicep:

<variable-name> = <variable-value>


Syntax of Bicep Variable

Bicep infers the data type of the variable from its assigned value. This saves you time and effort by removing the need to explicitly declare the data type. For example, when setting a variable to a string value, you can use the following syntax:

var stringVar = ‘example value’

Using Variables in Resource Properties

One of the key benefits of variables is their ability to be used within the properties of Azure resources defined in your Bicep file. By referencing variables in resource properties, you can dynamically set values based on your defined variables. For example, you can use a variable to set the name of a storage account or the location of a resource, enabling more flexibility in your Azure resource configurations.

Heres a simple example:

Using Variables in Resource Definitions in Bicep

Using Variables in Iterative Loops

Variables can also be used within iterative loops in Bicep. This is useful when you need to create arrays of objects. Using the “for” keyword with the “range” function, you can iterate a specified number of times and define the properties of each object using the loop index. This enables you to generate arrays with consistent and predictable data structures.

For example, you can use iterative loops and variables in Bicep to create an array of data disks. Each object in the array can have properties such as disk name, disk size, and disk index, making it easy to manage and maintain the array’s data structure.

Bicep Variables in Iterative Loops

Leveraging Configuration Variables for Environment Settings

Bicep provides a powerful feature called configuration variables that enables you to manage environment-specific values for your Azure deployments. These variables are defined as objects with key-value pairs, with each key representing an environment name and each value representing the configuration settings for that specific environment.

For instance, you can define a configuration variable that holds values for both the “test” and “prod” environments.

Configuration Variables in Bicep

Constructing Variables with Expressions

Variables can be constructed using expressions, allowing for dynamic value generation. This is particularly useful when creating resource names or constructing values based on other parameters or variables.


Mastering Bicep Variables – Tips and Best Practices

When it comes to working with variables in Bicep, there are several best practices that can help you write more efficient and maintainable infrastructure as code. By following these guidelines, you can unlock the full potential of Bicep variables and ensure efficient coding practices.

Best Practice Description
Use Descriptive Variable Names Choose meaningful names that clearly convey the purpose of each variable.
Avoid Naming Conflicts Ensure that variable names do not overlap with parameters, modules, or resources in your Bicep file.
Leverage Functions and Expressions Take advantage of Bicep’s built-in functions to create dynamic and reusable variable values.
Organize Variables Logically Group related variables together and provide clear documentation for each variable.
Test and Validate Variables Verify that variables are resolving as expected and providing the correct values.
Documentation Document the purpose and usage of each variable to facilitate understanding and future maintenance.


Remember, variables in Bicep offer a powerful mechanism for simplifying template development by abstracting complex expressions and values. By utilizing variables effectively, you can enhance the readability, maintainability, and flexibility of your ARM templates, making them more efficient and easier to manage.

Happy cloud building!


ps: if you need a deeper dive, check out this documentation:

Bicep Data Types Explained

Bicep is a Domain-Specific Language (DSL) for defining Azure Resource Manager (ARM) templates. It provides a concise and readable way to describe Azure resources and their properties. Understanding data types is crucial in Bicep, as they define the structure and behavior of resources.

This is a new series of articles about ‘BiCep’ technology by Microsoft – it is a game changer for resource management in the cloud – well worth investigating if you are a cloud builder!

Basic Data Types in Bicep


Strings in Bicep are sequences of characters enclosed in single or double quotes. They are used to represent text values. Strings in Bicep support interpolation, enabling dynamic content insertion.


param storageAccountName string = ‘myStorageAccount’

Multi-line Strings

Bicep supports multi-line strings using triple quotes ”’ ”’. This is useful when defining long text values. The characters entered within the opening and closing sequence are read exactly as they are, and there is no need for escaping characters.


var longText = ”’

This is a



Integers are whole numbers without a decimal point. In Bicep, integers are represented as 64-bit integers. However, the range of values may be constrained by the SDK or command-line tool used for deployment when passed as inline parameters. For instance, when deploying a Bicep template using PowerShell, integer types typically range from -2147483648 to 2147483647.

To work around this limitation, it is advisable to specify large integer values in a parameter file. Additionally, it is worth noting that resource types may impose their own restrictions on integer properties.


Note: Bicep does not currently support floating-point, decimal, or binary formats.


param numberOfInstances int = 3


Boolean values represent true or false. These data types are useful for logical decisions and conditions in your code.

Note: Avoid enclosing the value in quotation marks.


param useSSLEncryption bool = true

Complex Data Types


Objects in Bicep are collections of key-value pairs enclosed in curly braces {}. They are used to represent complex data structures and are commonly used to define properties of Azure resources. Each key in an object is a property name, and the corresponding value is the property value.

Objects allow you to group related properties together, which can improve the readability and maintainability of your Bicep code. They also enable you to pass structured data to resources or modules, making your templates more flexible and reusable.


var storageAccountConfig =
name: ‘myStorageAccount’,
type: ‘Standard_LRS’,
environment: ‘production’,
department: ‘finance’

You can access properties of an object using dot notation (.). For example, to access the name property of storageAccountConfig’, you would use ‘’.


Arrays in Bicep are ordered collections of values enclosed in square brackets []. They are used to represent lists of items. Arrays can be declared in a single line or multiple lines, providing flexibility in coding.

Use commas (,) to separate values in single-line declarations, while in multiple-line declarations, they are not required.


var instanceTypes = [

Secure Objects

Bicep has introduced secure objects to enhance security by protecting sensitive information. These objects are encrypted and provide an extra layer of protection for confidential data. Thus, to enhance the security of a string or object, apply the @secure() decorator to it.


param mySuperSecretObject object

Secure Strings

Similar to secure objects, secure strings provide additional security for sensitive information. These strings are encrypted and are designed to prevent unauthorized access to critical data.


param intAsString string
var num = int(intAsString)

Now that we have covered the supported data types in Bicep, let’s explore how user-defined data types can further enhance your Bicep code in the next section.

User-Defined Data Types in Bicep

Bicep extends its supported data types by enabling the definition of user-defined types using the `type` statement. This feature enhances code reusability and simplifies Bicep projects by allowing developers to define custom types based on primitive literals, arrays, and objects.

User-defined types can be utilized across a Bicep file, including in `param` statements and object type properties, making it easy to encapsulate complex data structures and reuse them throughout your code.

This capability empowers developers to create efficient and maintainable infrastructure as code solutions. Whether representing tagged union types or importing types from external sources, Bicep’s user-defined data types provide the flexibility and expressiveness needed for robust Azure deployments.


type SkuType = ‘Standard_LRS’ | ‘Standard_GRS’
type StorageAccountConfig = {
name: string
sku: SkuType



So then, we have learned that mastering data types in Bicep is essential for creating concise and effective Azure Resource Manager templates. By understanding and utilizing the various data types available, you can accurately define the structure and behavior of your Azure resources, leading to more efficient deployments.

Happy cloud building!

Bicep Resources: What They Are and How to Use Them

When deploying resources to Azure, developers often need to manage a variety of resource types, such as virtual machines, storage accounts, and networks. Bicep, a domain-specific language for deploying Azure resources, simplifies this process by providing a declarative syntax that abstracts away the complexities of Azure Resource Manager (ARM) templates. In this article, we’ll explore what Bicep resources are and how to use them effectively.

This is a new series of articles about ‘BiCep’ technology by Microsoft – it is a game changer for resource management in the cloud – well worth investigating if you are a cloud builder!

Understanding Bicep Resources

In Bicep, a resource is a unit of deployment that represents a single Azure resource, such as a virtual machine or a storage account. Resources are defined using the resource keyword, followed by the resource type and name. Here’s a basic example of defining a resource in Bicep:

Bicep Resource Simple Example

In this example, myStorageAccount is the name of the resource, Microsoft.Storage/storageAccounts@2021-06-01 is the resource type, and the object following the = sign contains the properties of the resource.

Using Bicep Resources


The declaration of a resource in Bicep includes the resource type, name, and properties. Here’s an example of declaring a virtual network resource:

Res Declaration

In this example, virtualNetwork is the name of the resource, Microsoft.Network/virtualNetworks@2021-02-01 is the resource type, and the properties object contains the address space of the virtual network.

Resource Name

The resource name is specified as the first argument in the resource declaration. It provides a unique identifier for the resource within the Bicep file.


The location property specifies the Azure region where the resource will be deployed. It ensures that the resource is deployed to a specific geographic location.


Tags are key-value pairs that can be used to categorize resources in Azure. They can be used for organizing deployed resources, cost management, and other purposes.

Managed Identities for Azure Resources

Managed identities for Azure resources provide an identity for applications to use when accessing Azure resources. You can enable managed identities for a resource using the identity property.


In this example, myAKSCluster is the name of the resource, eastus is the location, and { environment: ‘dev’ } are the tags. The identity is set to SystemAssigned.

Resource-Specific Properties

Resource-specific properties vary depending on the type of resource being deployed. For example, a virtual machine resource may have properties related to its size, operating system image, and networking configuration. These properties are specified within the properties object of the resource declaration.

The following example sets the access tier property for a storage account to “Cool” using the Bicep syntax:

Referencing an Existing Resource

Sometimes, you may need to reference an existing resource in your Bicep template. You can do this using the existing keyword. Here’s an example of referencing an existing storage account:

Creating a Child Resource

Child resources are resources that are created as part of another parent resource. You can define child resources using the child keyword. Here’s how you can create a child resource:

In this example, childResource is a child resource of parentResource.

Using Scope Extension Resources

Scope extension resources allow you to define resources that are scoped to a specific resource group or subscription. Here’s an example of using a scope extension resource:

Managing Resource Dependencies

When deploying resources, it’s essential to ensure that certain resources are deployed before others. For instance, you must have a logical SQL server in place before deploying a database. This relationship is established by specifying one resource as dependent on another. The order of resource deployment is determined by implicit and explicit dependencies.

Azure Resource Manager assesses these dependencies and deploys resources in the order of their dependencies. When resources are not dependent on each other, Resource Manager deploys them concurrently. Dependency definitions are only necessary for resources deployed within the same Bicep file.


The above code depicts dependency by referencing the nameServers property of the uniqueDnsZone resource in the customResource declaration. This means that the customResource depends on the uniqueDnsZone resource, as it needs the nameServers information from the DNS zone to function correctly. This dependency ensures that the DNS zone is created before the custom resource, fulfilling any prerequisites for the custom resource’s configuration.


Bicep resources are a powerful feature that simplify the deployment of Azure resources. By defining resources in a declarative manner, you can easily create, manage, and reference Azure resources in your Bicep templates. With the examples provided, you should now have a better understanding of how to use Bicep resources in your own deployments.

Happy cloud buildiong 😀

Want to know more? … get your fill-up here 🙂


Bicep: A Muscle or Part of Azure?

When you hear the word “bicep,” your mind probably conjures up images of a strong, well-defined muscle. However, in the world of Azure, “bicep” takes on a whole new meaning. Bicep is actually a domain-specific language (DSL) that is used for deploying Azure resources. If you’re unfamiliar with Bicep, don’t worry – we’re here to explain what it is and why it’s an essential tool for Azure deployments.

This is a new series of articles about ‘BiCep’ technology by Microsoft – it is a game changer for resource management in the cloud – well worth investigating if you are a cloud builder!

What is Bicep?

Bicep is a DSL that simplifies the authoring and management of ARM templates. ARM templates are JSON files that describe the resources you want to deploy in Azure, such as virtual machines, storage accounts, and databases. While ARM templates are powerful, they can be verbose and complex to write and maintain, especially for large deployments.

Bicep aims to address these challenges by providing a more concise and readable way to define Azure resources. It uses a syntax that is similar to other programming languages, making it easier for developers and infrastructure engineers to understand and work with.

Benefits of Bicep

Bicep provides several benefits:

  • Support for all resource types and API versions: With Bicep, you can leverage the latest Azure services immediately, as it offers comprehensive support for all resource types and API versions.
  • First-class authoring experience: Bicep enhances your authoring process with type-safety, intellisense, and syntax validation, ensuring error-free deployments and improving productivity.
  • Consistent results: By deploying your infrastructure repeatedly with Bicep throughout the development lifecycle, you can have confidence in consistent and predictable results.


  • Efficient orchestration and modularity: Bicep handles the ordering of operations, simplifying the orchestration of resources. It also supports modularity through the use of modules, enabling code reuse and maintainability.
  • Integration with Azure services: Bicep seamlessly integrates with various Azure services, enabling you to leverage additional features like preview changes and eliminating the need for state management.
  • Open source and free: Bicep is an open-source project that is completely free to use, making it accessible to everyone.

Getting Started with Bicep

To begin your Bicep journey, you’ll first need to install the some bits that are available in the Bicep GitHub repository.
It has pretty good instructions to get started.

Creating Bicep Files

Once you have the tools installed, it’s time to create some Bicep files. You can choose to use either the Bicep Extension for VS Code or the Bicep extension for Visual Studio, depending on your preference. These extensions provide an enhanced authoring experience with features like type-safety and intellisense, allowing you to write Bicep code effectively.

Learning Resources

To get started with Bicep, complete the quickstart and learn modules for an in-depth understanding. You can easily convert existing Azure Resource Manager (ARM) templates to Bicep using provided tools, simplifying migration while leveraging Bicep’s benefits.

For a deeper dive, use the Bicep Playground for interactive coding and refer to the resource reference for syntax and usage guidance. Keep in mind that Bicep is designed for Azure resource declaration, not general application development.

More about Bicep

For a deeper dive, check out the following links:


  • Bicep GitHub Repo: Access examples and documentation to understand and utilize Bicep effectively. The repo serves as a comprehensive guide to its syntax, capabilities, and best practices.
  • Bicep Documentation: Offers detailed guidance on Bicep’s features, covering advanced concepts, usage patterns, and integration with other Azure services. It’s a valuable reference for enhancing your Bicep skills.
  • Bicep Community: Join this community to connect with like-minded individuals, share experiences, and learn from others using Bicep. Gain insights and tips from experienced practitioners.


Full details:


Happy cloud building friends 🙂