Outputs in Bicep

This article describes how to define output values in a Bicep file. You use outputs when you need to return values from the deployed resources. You're limited to 64 outputs in a Bicep file. For more information, see Template limits.

Define outputs

The syntax for defining an output value is:

output <name> <data-type or type-expression> = <value>

An output can have the same name as a parameter, variable, module, or resource. Each output value must resolve to one of the data types, or user-defined data type expression.

The following example shows how to return a property from a deployed resource. In the example, publicIP is the symbolic name for a public IP address that is deployed in the Bicep file. The output value gets the fully qualified domain name for the public IP address.

output hostname string = publicIP.properties.dnsSettings.fqdn

The next example shows how to return outputs of different types.

output stringOutput string = deployment().name
output integerOutput int = length(environment().authentication.audiences)
output booleanOutput bool = contains(deployment().name, 'demo')
output arrayOutput array = environment().authentication.audiences
output objectOutput object = subscription()

If you need to output a property that has a hyphen in the name, use brackets around the name instead of dot notation. For example, use ['property-name'] instead of .property-name.

var user = {
  'user-name': 'Test Person'
}

output stringOutput string = user['user-name']

The following example shows how to use type expression:

param foo 'a' | 'b' = 'a'

output out 'a' | 'b' = foo

For more information, see User-defined data types.

Use decorators

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

Decorator Apply to Argument Description
description all string Provide descriptions for the output.
discriminator object string Use this decorator to ensure the correct subclass is identified and managed. For more information, see Custom-tagged union data type.
maxLength array, string int The maximum length for string and array outputs. The value is inclusive.
maxValue int int The maximum value for the integer output. This value is inclusive.
metadata all object Custom properties to apply to the output. Can include a description property that is equivalent to the description decorator.
minLength array, string int The minimum length for string and array outputs. The value is inclusive.
minValue int int The minimum value for the integer output. This value is inclusive.
sealed object none Elevate BCP089 from a warning to an error when a property name of a use-define data type is likely a typo. For more information, see Elevate error level.

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.

@sys.description('The name of the instance.')
param name string
@sys.description('The description of the instance to display.')
param description string

Description

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

@description('Conditionally output the endpoint.')
output endpoint string = deployStorage ? myStorageAccount.properties.primaryEndpoints.blob : ''

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

Discriminator

See Custom-tagged union data type.

Integer constraints

You can set minimum and maximum values for integer outputs. You can set one or both constraints.

var thisMonth = 3

@minValue(1)
@maxValue(12)
output month int = thisMonth

Length constraints

You can specify minimum and maximum lengths for string and array outputs. You can set one or both constraints. For strings, the length indicates the number of characters. For arrays, the length indicates the number of items in the array.

The following example declares two outputs. One output is for a storage account name that must have 3-24 characters. The other output is an array that must have from 1-5 items.

var accountName = uniqueString(resourceGroup().id)
var appNames = [
  'SyncSphere'
  'DataWhiz'
  'FlowMatrix'
]

@minLength(3)
@maxLength(24)
output storageAccountName string = accountName

@minLength(1)
@maxLength(5)
output applicationNames array = appNames

Metadata

If you have custom properties that you want to apply to an output, add a metadata decorator. Within the metadata, define an object with the custom names and values. The object you define for the metadata can contain properties of any name and type.

You might use this decorator to track information about the output that doesn't make sense to add to the description.

var obj = {}
@description('Configuration values that are applied when the application starts.')
@metadata({
  source: 'database'
  contact: 'Web team'
})
output settings object = obj

When you provide a @metadata() decorator with a property that conflicts with another decorator, that decorator always takes precedence over anything in the @metadata() decorator. So, the conflicting property within the @metadata() value is redundant and will be replaced. For more information, see No conflicting metadata.

Sealed

See Elevate error level.

Conditional output

When the value to return depends on a condition in the deployment, use the ? operator.

output <name> <data-type> = <condition> ? <true-value> : <false-value>

Typically, you use a conditional output when you've conditionally deployed a resource. The following example shows how to conditionally return the resource ID for a public IP address based on whether a new one was deployed.

To specify a conditional output in Bicep, use the ? operator. The following example either returns an endpoint URL or an empty string depending on a condition.

param deployStorage bool = true
param storageName string
param location string = resourceGroup().location

resource myStorageAccount 'Microsoft.Storage/storageAccounts@2023-04-01' = if (deployStorage) {
  name: storageName
  location: location
  kind: 'StorageV2'
  sku:{
    name:'Standard_LRS'
    tier: 'Standard'
  }
  properties: {
    accessTier: 'Hot'
  }
}

output endpoint string = deployStorage ? myStorageAccount.properties.primaryEndpoints.blob : ''

Dynamic number of outputs

In some scenarios, you don't know the number of instances of a value you need to return when creating the template. You can return a variable number of values by using the for expression.

output <name> <data-type> = [for <item> in <collection>: {
  ...
}]

The following example iterates over an array.

param nsgLocation string = resourceGroup().location
param orgNames array = [
  'Contoso'
  'Fabrikam'
  'Coho'
]

resource nsg 'Microsoft.Network/networkSecurityGroups@2023-11-01' = [for name in orgNames: {
  name: 'nsg-${name}'
  location: nsgLocation
}]

output deployedNSGs array = [for (name, i) in orgNames: {
  orgName: name
  nsgName: nsg[i].name
  resourceId: nsg[i].id
}]

For more information about loops, see Iterative loops in Bicep.

Outputs from modules

To get an output value from a module, use the following syntax:

<module-name>.outputs.<property-name>

The following example shows how to set the IP address on a load balancer by retrieving a value from a module.

module publicIP 'modules/public-ip-address.bicep' = {
  name: 'public-ip-address-module'
}

resource loadBalancer 'Microsoft.Network/loadBalancers@2023-11-01' = {
  name: loadBalancerName
  location: location
  properties: {
    frontendIPConfigurations: [
      {
        name: 'name'
        properties: {
          publicIPAddress: {
            id: publicIP.outputs.resourceId
          }
        }
      }
    ]
    // ...
  }
}

Get output values

When the deployment succeeds, the output values are automatically returned in the results of the deployment.

To get output values from the deployment history, you can use Azure CLI or Azure PowerShell script.

(Get-AzResourceGroupDeployment `
  -ResourceGroupName <resource-group-name> `
  -Name <deployment-name>).Outputs.resourceID.value

Object sorting in outputs

In JSON, an object is an unordered collection of zero or more key/value pairs. The ordering can be different depending on the implementations. For example, the Bicep items() function sorts the objects in the alphabetical order. In other places, the original ordering can be preserved. Because of this non-determinism, avoid making any assumptions about the ordering of object keys when writing code, which interacts with deployments parameters & outputs.

Next steps