Bicep Outputs
Outputs in Bicep return information from a completed deployment. After Azure creates or updates resources, outputs expose important details — like resource IDs, endpoint URLs, and connection strings — so other systems, scripts, or Bicep files can use them.
Think of outputs like a receipt after placing an order online. The order confirmation number, estimated delivery date, and tracking link all appear on the receipt. Bicep outputs work the same way: the deployment finishes, and the outputs provide the details needed to work with the newly created resources.
Output Syntax
output <outputName> <dataType> = <value>
// Example: Return the ID of a storage account output storageAccountId string = storageAccount.id
Every output has three parts:
| Part | Description | Example |
|---|---|---|
| Output Name | The label for the returned value | storageAccountId |
| Data Type | The type of value being returned | string, int, bool, object, array |
| Value | The actual value to return | storageAccount.id |
Why Outputs Matter
Deployment Flow with Outputs
Bicep File
──────────
resource storageAccount = { ... }
output blobEndpoint = storageAccount.properties.primaryEndpoints.blob
│
▼
Azure Deployment Runs
│
▼
Azure Creates the Storage Account
│
▼
Outputs Become Available
┌─────────────────────────────────────────┐
│ blobEndpoint: "https://mystorage. │
│ blob.core.windows.net/" │
└─────────────────────────────────────────┘
│
├──► CI/CD Pipeline reads endpoint and sets app config
├──► Calling Bicep module receives the value
└──► Developer copies the value from Azure CLI output
Output Data Types
Outputs support the same data types as parameters:
// String output output storageAccountName string = storageAccount.name // Integer output output replicaCount int = 3 // Boolean output output isHttpsOnly bool = storageAccount.properties.supportsHttpsTrafficOnly // Object output output storageEndpoints object = storageAccount.properties.primaryEndpoints // Array output output subnetIds array = [ subnet1.id subnet2.id ]
Common Outputs and What They Return
| Output Expression | What It Returns |
|---|---|
| storageAccount.id | Full Azure resource ID of the storage account |
| storageAccount.name | Name of the storage account |
| storageAccount.properties.primaryEndpoints.blob | Blob storage endpoint URL |
| webApp.properties.defaultHostName | Default hostname of the web app |
| webApp.identity.principalId | Managed identity principal ID |
| keyVault.properties.vaultUri | Key Vault URI for secret access |
| sqlServer.properties.fullyQualifiedDomainName | SQL Server connection hostname |
| resourceGroup().id | ID of the resource group |
Viewing Outputs After Deployment
When deploying with Azure CLI, outputs display automatically at the end of a successful deployment. The output section appears in the terminal like this:
az deployment group create \
--resource-group myRG \
--template-file main.bicep
# Example terminal output:
{
"outputs": {
"storageAccountName": {
"type": "String",
"value": "mystorage2024xkpq"
},
"blobEndpoint": {
"type": "String",
"value": "https://mystorage2024xkpq.blob.core.windows.net/"
}
}
}
To retrieve only the output value from a previous deployment:
az deployment group show \ --resource-group myRG \ --name main \ --query "properties.outputs.storageAccountName.value" \ --output tsv
Complete Example – Outputs for a Web App Deployment
param location string = 'eastus'
param appName string = 'mywebapp'
resource appServicePlan 'Microsoft.Web/serverfarms@2023-01-01' = {
name: 'asp-${appName}'
location: location
sku: {
name: 'B1'
}
}
resource webApp 'Microsoft.Web/sites@2023-01-01' = {
name: 'app-${appName}'
location: location
kind: 'app'
identity: {
type: 'SystemAssigned'
}
properties: {
serverFarmId: appServicePlan.id
siteConfig: {
alwaysOn: true
}
}
}
// Outputs
output webAppName string = webApp.name
output webAppId string = webApp.id
output webAppUrl string = 'https://${webApp.properties.defaultHostName}'
output webAppManagedIdentityId string = webApp.identity.principalId
output appServicePlanId string = appServicePlan.id
After deployment, all five values appear in the CLI output. A CI/CD pipeline can capture webAppUrl and run smoke tests against it. Another Bicep file can take webAppManagedIdentityId and assign it Key Vault access.
Outputs in Modules
Outputs are especially important when using Bicep modules (covered in the Bicep Modules topic). A module outputs values and the calling file reads those values to use in other resources.
Bicep Module Communication via Outputs
main.bicep
│
├── module networkModule = { ... }
│ └── output subnetId string = subnet.id
│ │
│ └──────────────────────────┐
│ ▼
└── resource webApp = {
properties: {
virtualNetworkSubnetId: networkModule.outputs.subnetId ◄── used here
}
}
// main.bicep – reading a module output
module networkModule './network.bicep' = {
name: 'deploy-network'
params: {
location: location
vnetName: 'vnet-myapp'
}
}
resource webApp 'Microsoft.Web/sites@2023-01-01' = {
name: 'app-myapp'
location: location
properties: {
serverFarmId: appServicePlan.id
virtualNetworkSubnetId: networkModule.outputs.subnetId // module output used here
}
}
Secure Outputs
Some outputs contain sensitive information like connection strings or keys. Mark them with the @secure() decorator to prevent them from appearing in deployment logs.
@secure()
output storageConnectionString string = 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};AccountKey=${storageAccount.listKeys().keys[0].value};EndpointSuffix=core.windows.net'
However, the preferred approach is to store sensitive values in Azure Key Vault and output only the Key Vault secret reference, never the raw secret value.
Computed Outputs – Building Values from Multiple Sources
param appName string = 'myapp'
resource webApp 'Microsoft.Web/sites@2023-01-01' = {
name: 'app-${appName}'
location: 'eastus'
kind: 'app'
properties: {
serverFarmId: appServicePlan.id
}
}
// Build the full URL from the hostname
output applicationUrl string = 'https://${webApp.properties.defaultHostName}'
// Build a custom domain label
output appFriendlyName string = 'Application: ${toUpper(appName)}'
Summary
Outputs expose important information after a Bicep deployment completes. They support all standard data types, appear in CLI output automatically, and play a critical role when Bicep modules communicate with each other. Sensitive outputs use the @secure() decorator to prevent logging. Well-designed outputs make automation, integration, and post-deployment configuration straightforward.
