Resource declaration in Bicep

This article describes the syntax you use to add a resource to your Bicep file. You're limited to 800 resources in a Bicep file. For more information, see Template limits.

Define resources

Add a resource declaration by using the resource keyword. You set a symbolic name for the resource. The symbolic name isn't the same as the resource name. You use the symbolic name to reference the resource in other parts of your Bicep file.

@<decorator>(<argument>)
resource <symbolic-name> '<full-type-name>@<api-version>' = {
  <resource-properties>
}

So, a declaration for a storage account can start with:

resource stg 'Microsoft.Storage/storageAccounts@2023-04-01' = {
  ...
}

Symbolic names are case-sensitive. They may contain letters, numbers, and underscores (_). They can't start with a number. A resource can't have the same name as a parameter, variable, or module.

For the available resource types and version, see Bicep resource reference. Bicep doesn't support apiProfile, which is available in Azure Resource Manager templates (ARM templates) JSON. You can also define Bicep extensibility provider resources. For more information, see Bicep extensibility Kubernetes provider.

To conditionally deploy a resource, use the if syntax. For more information, see Conditional deployment in Bicep.

resource <symbolic-name> '<full-type-name>@<api-version>' = if (condition) {
  <resource-properties>
}

To deploy more than one instance of a resource, use the for syntax. You can use the batchSize decorator to specify whether the instances are deployed serially or in parallel. For more information, see Iterative loops in Bicep.

@batchSize(int) // optional decorator for serial deployment
resource <symbolic-name> '<full-type-name>@<api-version>' = [for <item> in <collection>: {
  <properties-to-repeat>
}]

You can also use the for syntax on the resource properties to create an array.

resource <symbolic-name> '<full-type-name>@<api-version>' = {
  properties: {
    <array-property>: [for <item> in <collection>: <value-to-repeat>]
  }
}

Use decorators

Decorators are written in the format @expression and are placed above resource declarations. The following table shows the available decorators for resources.

Decorator Argument Description
batchSize none Set up instances to deploy sequentially.
description string Provide descriptions for the resource.

Decorators are in the sys namespace. If you need to differentiate a decorator from another item with the same name, preface the decorator with sys. For example, if your Bicep file includes a parameter named description, you must add the sys namespace when using the description decorator.

BatchSize

You can only apply @batchSize() to a resource or module definition that uses a for expression.

By default, resources are deployed in parallel. When you add the batchSize(int) decorator, you deploy instances serially.

@batchSize(3)
resource storageAccountResources 'Microsoft.Storage/storageAccounts@2023-04-01' = [for storageName in storageAccounts: {
  ...
}]

For more information, see Deploy in batches.

Description

To add explanation, add a description to resource declarations. For example:

@description('Create a number of storage accounts')
resource storageAccountResources 'Microsoft.Storage/storageAccounts@2023-04-01' = [for storageName in storageAccounts: {
  ...
}]

Markdown-formatted text can be used for the description text.

Resource name

Each resource has a name. When setting the resource name, pay attention to the rules and restrictions for resource names.

resource stg 'Microsoft.Storage/storageAccounts@2023-04-01' = {
  name: 'examplestorage'
  ...
}

Typically, you'd set the name to a parameter so you can pass in different values during deployment.

@minLength(3)
@maxLength(24)
param storageAccountName string

resource stg 'Microsoft.Storage/storageAccounts@2023-04-01' = {
  name: storageAccountName
  ...
}

Resource location

Many resources require a location. You can determine if the resource needs a location either through intellisense or template reference. The following example adds a location parameter that is used for the storage account.

resource stg 'Microsoft.Storage/storageAccounts@2023-04-01' = {
  name: 'examplestorage'
  location: 'eastus'
  ...
}

Typically, you'd set location to a parameter so you can deploy to different locations.

param location string = resourceGroup().location

resource stg 'Microsoft.Storage/storageAccounts@2023-04-01' = {
  name: 'examplestorage'
  location: location
  ...
}

Different resource types are supported in different locations. To get the supported locations for an Azure service, See Products available by region. To get the supported locations for a resource type, use Azure PowerShell or Azure CLI.

((Get-AzResourceProvider -ProviderNamespace Microsoft.Batch).ResourceTypes `
  | Where-Object ResourceTypeName -eq batchAccounts).Locations

Resource tags

You can apply tags to a resource during deployment. Tags help you logically organize your deployed resources. For examples of the different ways you can specify the tags, see ARM template tags.

Managed identities for resources

Some resources support managed identities for Azure resources. Those resources have an identity object at the root level of the resource declaration.

You can use either system-assigned or user-assigned identities.

The following example shows how to configure a system-assigned identity for an Azure Kubernetes Service cluster.

resource aks 'Microsoft.ContainerService/managedClusters@2024-02-01' = {
  name: clusterName
  location: location
  tags: tags
  identity: {
    type: 'SystemAssigned'
  }

The next example shows how to configure a user-assigned identity for a virtual machine.

param userAssignedIdentity string

resource vm 'Microsoft.Compute/virtualMachines@2024-03-01' = {
  name: vmName
  location: location
  identity: {
    type: 'UserAssigned'
    userAssignedIdentities: {
      '${userAssignedIdentity}': {}
    }
  }

Resource-specific properties

The preceding properties are generic to most resource types. After setting those values, you need to set the properties that are specific to the resource type you're deploying.

Use intellisense or Bicep resource reference to determine which properties are available and which ones are required. The following example sets the remaining properties for a storage account.

resource stg 'Microsoft.Storage/storageAccounts@2023-04-01' = {
  name: 'examplestorage'
  location: 'eastus'
  sku: {
    name: 'Standard_LRS'
    tier: 'Standard'
  }
  kind: 'StorageV2'
  properties: {
    accessTier: 'Hot'
  }
}

Next steps