Output iteration in Bicep

This article shows you how to create more than one value for an output in your Bicep file. You can add a loop to the file's output section and dynamically return several items during deployment.

You can also use a loop with modules, resources, properties in a resource, and variables.

Syntax

Loops can be used to return items during deployment by:

  • Using a loop index.

    output <output-name> array = [for <index> in range(<start>, <stop>): {
        <properties>
    }]
    

    For more information, see Loop index.

  • Iterating over an array.

    output <output-name> array = [for <item> in <collection>: {
        <properties>
    }]
    
    
  • Iterating over an array and index.

    output <output-name> array = [for <item>, <index> in <collection>: {
        <properties>
    }]
    

    For more information, see Loop array and index.

Loop limits

The Bicep file's loop iterations can't be a negative number or exceed 800 iterations.

Loop index

The following example creates a variable number of storage accounts and returns an endpoint for each storage account.

param rgLocation string = resourceGroup().location
param storageCount int = 2

var baseNameVar = 'storage${uniqueString(resourceGroup().id)}'

resource stg 'Microsoft.Storage/storageAccounts@2021-02-01' = [for i in range(0, storageCount): {
  name: '${i}${baseNameVar}'
  location: rgLocation
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'Storage'
}]

output storageEndpoints array = [for i in range(0, storageCount): stg[i].properties.primaryEndpoints.blob]

The output returns an array with the following values:

[
  "https://0storagecfrbqnnmpeudi.blob.core.chinacloudapi.cn/",
  "https://1storagecfrbqnnmpeudi.blob.core.chinacloudapi.cn/"
]

The next example returns three properties from the new storage accounts.

param rgLocation string = resourceGroup().location
param storageCount int = 2

var baseNameVar = 'storage${uniqueString(resourceGroup().id)}'

resource stg 'Microsoft.Storage/storageAccounts@2021-02-01' = [for i in range(0, storageCount): {
  name: '${i}${baseNameVar}'
  location: rgLocation
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'Storage'
}]

output storageInfo array = [for i in range(0, storageCount): {
  id: stg[i].id
  blobEndpoint: stg[i].properties.primaryEndpoints.blob
  status: stg[i].properties.statusOfPrimary
}]

The output returns an array with the following values:

[
  {
    "id": "/subscriptions/{sub-id}/resourceGroups/{rg-name}/providers/Microsoft.Storage/storageAccounts/0storagecfrbqnnmpeudi",
    "blobEndpoint": "https://0storagecfrbqnnmpeudi.blob.core.chinacloudapi.cn/",
    "status": "available"
  },
  {
    "id": "/subscriptions/{sub-id}/resourceGroups/{rg-name}/providers/Microsoft.Storage/storageAccounts/1storagecfrbqnnmpeudi",
    "blobEndpoint": "https://1storagecfrbqnnmpeudi.blob.core.chinacloudapi.cn/",
    "status": "available"
  }
]

Loop array and index

This example uses both the elements of an array and an index.

param rgLocation string = resourceGroup().location

var stgNames = [
  'demostg1'
  'demostg2'
  'demostg3'
]

resource stg 'Microsoft.Storage/storageAccounts@2021-02-01' = [for name in stgNames: {
  name: name
  location: rgLocation
  kind: 'Storage'
  sku: {
    name: 'Standard_LRS'
    tier: 'Standard'
  }
}]

output stgOutput array = [for (name, i) in stgNames: {
  name: stg[i].name
  resourceId: stg[i].id
}]

The output returns an array with the following values:

[
  {
    "name": "demostg1",
    "resourceId": "/subscriptions/{sub-id}/resourceGroups/{rg-name}/providers/Microsoft.Storage/storageAccounts/demostg1"
  },
  {
    "name": "demostg2",
    "resourceId": "/subscriptions/{sub-id}/resourceGroups/{rg-name}/providers/Microsoft.Storage/storageAccounts/demostg2"
  },
  {
    "name": "demostg3",
    "resourceId": "/subscriptions/{sub-id}/resourceGroups/{rg-name}/providers/Microsoft.Storage/storageAccounts/demostg3"
  }
]

Next steps