top of page

A Practical Guide to Azure Bicep Modules for Beginners

gs9074

Updated: May 12, 2023

Introduction


Have you read my 5 essential bicep tips and tricks for beginners? If not go read that now, if not all then at least the first tip which is learn about Bicep modules. So to help, I've put together this post to teach about using Bicep Modules, including how to create, reference, and manage them.

1. What are Bicep Modules?


Bicep modules are reusable components that simplify the process of deploying Azure resources. A module represents a collection of Azure resources with configurable parameters, allowing you to package and reuse complex infrastructure designs. This modularity promotes code reusability and maintainability, making it easier to manage large-scale deployments.


2. Creating a Bicep Module


To create a Bicep module, you'll need to define a separate Bicep file with the desired resources and parameters. For example, let's create a module for deploying an Azure Storage Account:



// storageAccount.bicep
param accountName string
param location string = resourceGroup().location
param skuName string = 'Standard_LRS'

resource storageAccount 'Microsoft.Storage/storageAccounts@2021-04-01' = {
  name: accountName
  location: location
  sku: {
    name: skuName
  }
  kind: 'StorageV2'
}
  

In this example, we've created a Bicep file called `storageAccount.bicep` that defines a Storage Account resource with configurable parameters like accountName, location, and skuName.


3. Referencing a Bicep Module


Once you've created a Bicep module, you can reference it in another Bicep file using the `module` keyword:



// main.bicep
module storageAccount './storageAccount.bicep' = {
  name: 'myStorageAccountModule'
  params: {
    accountName: 'myuniquestorageaccount'
  }
}
  

Here, we're using the `module` keyword to reference the `storageAccount.bicep` file, providing a name for the module instance ('myStorageAccountModule') and passing the required parameters.


4. Managing Bicep Module Outputs


Bicep modules can also return outputs, which allow you to retrieve values from the module and use them in other parts of your Bicep file. To define an output in a module, use the `output` keyword:


// storageAccount.bicep (updated)
...
output storageAccountId string = storageAccount.id

To access the output value in another Bicep file, simply reference the module's output property:



// main.bicep (updated)
...
output deployedStorageAccountId string = storageAccount.outputs.storageAccountId

5. Using ARM Templates as Bicep Modules


While Bicep provides a more readable and maintainable way to define Azure resources, you might still have existing ARM templates that you want to reuse in your Bicep files. Fortunately, Bicep allows you to reference ARM templates directly as modules, making it easy to incorporate your existing infrastructure code.


To use an ARM template as a Bicep module, follow these steps:


1. Firs



t, ensure that your ARM template has defined its input parameters and outputs. For example, let's consider an ARM template for deploying an Azure Storage Account:



// storageAccount.json
{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
      "accountName": {
        "type": "string"
      },
      "location": {
        "type": "string",
        "defaultValue": "[resourceGroup().location]"
      },
      "skuName": {
        "type": "string",
        "defaultValue": "Standard_LRS"
      }
    },
    "resources": [
      {
        "type": "Microsoft.Storage/storageAccounts",
        "apiVersion": "2021-04-01",
        "name": "[parameters('accountName')]",
        "location": "[parameters('location')]",
        "sku": {
          "name": "[parameters('skuName')]"
        },
        "kind": "StorageV2"
      }
    ],
    "outputs": {
      "storageAccountId": {
        "type": "string",
        "value": "[resourceId('Microsoft.Storage/storageAccounts', parameters('accountName'))]"
      }
    }
  }
  

2. In your Bicep file, use the `module` keyword to reference the ARM template, providing the required input parameters:


// main.bicep
module storageAccount './storageAccount.json' = {
  name: 'myStorageAccountModule'
  params: {
    accountName: 'myuniquestorageaccount'
  }
}

3. Access the output values from the ARM template module in the same way you would with a Bicep module:


// main.bicep (updated)
...
output deployedStorageAccountId string = storageAccount.outputs.storageAccountId

By following these steps, you can seamlessly integrate your existing ARM templates into your Bicep deployments, allowing you to gradually transition your infrastructure code to Bicep while still leveraging your previous work.


6. Bicep Module Best Practices


Follow these best practices when working with Bicep modules:


- Keep module scope limited to a specific resource type or closely related resources.

- Use descriptive names for modules and module parameters to make them easy to understand and use.

- Leverage default values for optional parameters to simplify module usage.

- Validate module inputs using the `@allowed` decorator to ensure correct usage and prevent configuration errors.

- Write clear documentation for your modules, including explanations of parameters, dependencies, and any limitations.



Conclusion


Azure Bicep modules offer a powerful way to manage and deploy Azure resources by simplifying code reusability and maintainability. With the ability to create, reference, and manage Bicep modules, as well as integrate existing ARM templates as modules, you'll be well-equipped to build scalable and maintainable infrastructure on Azure.

10 views0 comments

Recent Posts

See All

Comments


Bagh Co Logo

Bagh Co Ltd

  • LinkedIn
  • X
  • Threads

©2024 by Bagh Co Ltd.

bottom of page