Tutorial: Add modules to Azure Resource Manager Bicep file
In the previous tutorial, you learned how to use a parameter file to deploy your Bicep file. In this tutorial, you learn how to use Bicep modules to encapsulate complex details of the raw resource declaration. The modules can be shared and reused within your solution. It takes about 12 minutes to complete.
Note
This article contains Bicep examples. Bicep is currently in preview. For more information, see Project Bicep.
Prerequisites
We recommend that you complete the tutorial about parameter file, but it's not required.
You must have Visual Studio Code with the Bicep extension, and either Azure PowerShell or Azure CLI. For more information, see Bicep tools.
Review Bicep file
At the end of the previous tutorial, your Bicep file had the following contents:
@minLength(3)
@maxLength(11)
param storagePrefix string
@allowed([
'Standard_LRS'
'Standard_GRS'
'Standard_RAGRS'
'Premium_LRS'
])
param storageSKU string = 'Standard_LRS'
param location string = resourceGroup().location
param appServicePlanName string = 'exampleplan'
@minLength(2)
@description('Base name of the resource such as web app name and app service plan.')
param webAppName string
@description('The Runtime stack of current web app.')
param linuxFxVersion string = 'php|7.0'
param resourceTags object = {
Environment: 'Dev'
Project: 'Tutorial'
}
var uniqueStorageName = '${storagePrefix}${uniqueString(resourceGroup().id)}'
var webAppPortalName = '${webAppName}${uniqueString(resourceGroup().id)}'
resource stg 'Microsoft.Storage/storageAccounts@2019-04-01' = {
name: uniqueStorageName
location: location
tags: resourceTags
sku: {
name: storageSKU
}
kind: 'StorageV2'
properties: {
supportsHttpsTrafficOnly: true
}
}
resource appPlan 'Microsoft.Web/serverfarms@2016-09-01' = {
name: appServicePlanName
location: location
tags: resourceTags
sku: {
name: 'B1'
tier: 'Basic'
size: 'B1'
family: 'B'
capacity: 1
}
kind: 'linux'
properties: {
perSiteScaling: false
reserved: true
targetWorkerCount: 0
targetWorkerSizeId: 0
}
}
resource site 'Microsoft.Web/sites@2016-08-01' = {
name: webAppPortalName
location: location
tags: resourceTags
kind: 'app'
properties: {
serverFarmId: appPlan.id
siteConfig: {
linuxFxVersion: linuxFxVersion
}
}
}
output storageEndpoint object = stg.properties.primaryEndpoints
This Bicep file works well. But for larger solutions, you want to break your Bicep file into many related modules so you can share and reuse these modules. The current Bicep file deploys a storage account, an app service plan, and a website. Let's separate the storage account into a module.
Create Bicep module
Every Bicep file can be consumed as a module, so there is no specific syntax for defining a module. Create a storage.bicep file with the following contents:
@minLength(3)
@maxLength(11)
param storagePrefix string
@allowed([
'Standard_LRS'
'Standard_GRS'
'Standard_RAGRS'
'Premium_LRS'
])
param storageSKU string = 'Standard_LRS'
param location string
param resourceTags object
var uniqueStorageName = '${storagePrefix}${uniqueString(resourceGroup().id)}'
resource stg 'Microsoft.Storage/storageAccounts@2019-04-01' = {
name: uniqueStorageName
location: location
tags: resourceTags
sku: {
name: storageSKU
}
kind: 'StorageV2'
properties: {
supportsHttpsTrafficOnly: true
}
}
output storageEndpoint object = stg.properties.primaryEndpoints
This module contains the storage account resource and the related parameters and variables. The values for the location parameter and the resourceTags parameters have been removed. These values will be passed from the main Bicep file.
Consume Bicep module
Replace the storage account resource definition in the existing azuredeploy.bicep with the following Bicep contents:
module stg './storage.bicep' = {
name: 'storageDeploy'
params: {
storagePrefix: storagePrefix
location: location
resourceTags: resourceTags
}
}
- module: Keyword.
- symbolic name (stg): This is an identifier for the module.
- module file: The path to the module in this example is specified using a relative path (./storage.bicep). All paths in Bicep must be specified using the forward slash (/) directory separator to ensure consistent compilation cross-platform. The Windows backslash () character is unsupported.
To retrieve storage endpoint, update the output in azuredeploy.bicep to the following Bicep:
output storageEndpoint object = stg.outputs.storageEndpoint
The completed azuredeploy.bicep has the following contents:
@minLength(3)
@maxLength(11)
param storagePrefix string
@allowed([
'Standard_LRS'
'Standard_GRS'
'Standard_RAGRS'
'Premium_LRS'
])
param storageSKU string = 'Standard_LRS'
param location string = resourceGroup().location
param appServicePlanName string = 'exampleplan'
param webAppName string {
minLength: 2
metadata: {
description: 'Base name of the resource such as web app name and app service plan '
}
}
param linuxFxVersion string {
metadata: {
description: 'The Runtime stack of current web app'
}
default: 'php|7.0'
}
param resourceTags object = {
Environment: 'Dev'
Project: 'Tutorial'
}
var uniqueStorageName = '${storagePrefix}${uniqueString(resourceGroup().id)}'
var webAppPortalName = '${webAppName}${uniqueString(resourceGroup().id)}'
module stg './storage.bicep' = {
name: 'storageDeploy'
params: {
storagePrefix: storagePrefix
location: location
resourceTags: resourceTags
}
}
resource appPlan 'Microsoft.Web/serverfarms@2016-09-01' = {
name: appServicePlanName
location: location
tags: resourceTags
sku: {
name: 'B1'
tier: 'Basic'
size: 'B1'
family: 'B'
capacity: 1
}
kind: 'linux'
properties: {
perSiteScaling: false
reserved: true
targetWorkerCount: 0
targetWorkerSizeId: 0
}
}
resource site 'Microsoft.Web/sites@2016-08-01' = {
name: webAppPortalName
location: location
tags: resourceTags
kind: 'app'
properties: {
serverFarmId: appPlan.id
siteConfig: {
linuxFxVersion: linuxFxVersion
}
}
}
output storageEndpoint object = stg.outputs.storageEndpoint
Deploy template
Use either Azure CLI or Azure PowerShell to deploy the template.
If you haven't created the resource group, see Create resource group. The example assumes you've set the bicepFile
variable to the path to the Bicep file, as shown in the first tutorial.
To run this deployment cmdlet, you must have the latest version of Azure PowerShell.
New-AzResourceGroupDeployment `
-Name addmodule `
-ResourceGroupName myResourceGroup `
-TemplateFile $bicepFile `
-storagePrefix "store" `
-storageSKU Standard_LRS `
-webAppName demoapp
Note
If the deployment failed, use the verbose
switch to get information about the resources being created. Use the debug
switch to get more information for debugging.
Verify deployment
You can verify the deployment by exploring the resource groups from the Azure portal.
- Sign in to the Azure portal.
- From the left menu, select Resource groups.
- You will see the new resource group you deployed in this tutorial.
- Select the resource group and view the deployed resources. Notice that they match the values you specified in your template file.
Clean up resources
- From the Azure portal, select Resource group from the left menu.
- Enter the resource group name in the Filter by name field. If you've completed this series, you have three resource groups to delete - myResourceGroup, myResourceGroupDev, and myResourceGroupProd.
- Select the resource group name.
- Select Delete resource group from the top menu.
Next steps
Congratulations, you've finished this introduction to deploying Bicep files to Azure. Let us know if you have any comments and suggestions in the feedback section. Thanks!
The next tutorial series goes into more detail about deploying templates.