Aspire incorrectly merges Azurite emulator bindings into production manifest, causing Bicep failure
- Dominant language
- C#
- Stars
- 6.3k
- Forks
- 991
- Avg merge
- 2d 15h
- Merged PRs (30d)
- 196
Description
### Is there an existing issue for this?
- [x] I have searched the existing issues
### Describe the bug
Environment:
- **Aspire Version**: 9.0.0 (tested on 1/30/2025)
- **.NET Version**: .NET 9.0.102 SDK
- **Azure Dev CLI (azd)**: 1.11.1
- **OS**: macOS (Apple Silicon)
When using Aspire with **Azurite in development (`RunAsEmulator`)** and **Azure Storage in production (`azd provision`)**, Aspire **incorrectly merges emulator bindings into the production manifest and Bicep templates**.
This results in an **invalid connection string** containing `bindings.blob.host`, causing Bicep generation to fail with:
`ERROR: generating bicep from manifest: evaluating value for ConnectionStrings__blobs:
evaluating connection string for blobs: unsupported property referenced in binding expression: bindings.blob.host for azure.bicep.v0`
### **What I Expected**
- In **development**, Aspire should correctly use Azurite.
- In **production**, Aspire should generate a valid Azure Storage endpoint.
- The **production manifest/Bicep should not reference** `bindings.blob.host`.
### **What Actually Happens**
- The **emulator binding is incorrectly merged into the production manifest**, causing `bindings.blob.host` to be present in production.
- This results in **Bicep generation failure**, blocking deployment.
I have thoroughly reviewed my setup and compared it with other Aspire projects that use a similar configuration without issues. Despite my efforts, I have been unable to find any relevant documentation or discussions about this specific error. Given the lack of available solutions and my unsuccessful attempts at resolving the issue, I am unsure if this is a misconfiguration on my part or a potential bug. Any guidance or clarification would be greatly appreciated.
Below is the generated Aspire.NET manifest and Bicep file produced when running `dotnet run --launch-profile manifest`.
[aspire-manifest.json](https://github.com/user-attachments/files/18602166/aspire-manifest.json)
```bicep
@description('The location for the resource(s) to be deployed.')
param location string = resourceGroup().location
param principalId string
param principalType string
resource storage 'Microsoft.Storage/storageAccounts@2024-01-01' = {
name: take('storage${uniqueString(resourceGroup().id)}', 24)
kind: 'StorageV2'
location: location
sku: {
name: 'Standard_GRS'
}
properties: {
accessTier: 'Hot'
allowSharedKeyAccess: false
minimumTlsVersion: 'TLS1_2'
networkAcls: {
defaultAction: 'Allow'
}
}
tags: {
'aspire-resource-name': 'storage'
}
}
resource blobs 'Microsoft.Storage/storageAccounts/blobServices@2024-01-01' = {
name: 'default'
parent: storage
}
resource storage_StorageBlobDataContributor 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(storage.id, principalId, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ba92f5b4-2d11-453d-a403-e96b0029c9fe'))
properties: {
principalId: principalId
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ba92f5b4-2d11-453d-a403-e96b0029c9fe')
principalType: principalType
}
scope: storage
}
resource storage_StorageTableDataContributor 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(storage.id, principalId, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3'))
properties: {
principalId: principalId
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3')
principalType: principalType
}
scope: storage
}
resource storage_StorageQueueDataContributor 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(storage.id, principalId, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '974c5e8b-45b9-4653-ba55-5f855dd0fb88'))
properties: {
principalId: principalId
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '974c5e8b-45b9-4653-ba55-5f855dd0fb88')
principalType: principalType
}
scope: storage
}
output blobEndpoint string = storage.properties.primaryEndpoints.blob
output queueEndpoint string = storage.properties.primaryEndpoints.queue
output tableEndpoint string = storage.properties.primaryEndpoints.table
```
### Expected Behavior
- In **production**, Aspire should not include any emulator host/port references.
- The generated manifest/Bicep for production should only contain a valid Azure Blob Storage endpoint or connection string, **not** `bindings.blob.host`.
## **Actual Behavior**
- Aspire merges the emulator binding into the Bicep for production, causing the `bindings.blob.host` reference and resulting deployment failures.
## **Workarounds Attempted**
1. **Separate resource names** for dev vs. prod.
2. **Manual cleanup** of old artifacts and caches.
3. **Explicit environment checks** to ensure CI is not recognized
### Steps To Reproduce
My setup is extremely simple. I simply did the following:
1. Create a `.NET Aspire` project with the following code in AppHost:
```csharp
var builder = DistributedApplication.CreateBuilder(args);
var storage = builder
.AddAzureStorage("storage")
.RunAsEmulator(resourceBuilder =>
{
resourceBuilder.WithDataVolume("omics-studio-storage-data");
resourceBuilder.WithBlobPort(10000);
resourceBuilder.WithLifetime(ContainerLifetime.Persistent);
})
.WithAnnotation(
new ContainerImageAnnotation
{
Registry = "mcr.microsoft.com",
Image = "azure-storage/azurite",
Tag = "latest",
}
)
.AddBlobs("blobs");
await builder.Build().RunAsync();
```
2. Ran `azd init` and `azd provision`
And that gave me the following error:
`generating bicep from manifest: evaluating value for ConnectionStrings__blobs: evaluating connection string for blobs: unsupported property referenced in binding expression: bindings.blob.host for azure.bicep.v0`
### Exceptions (if any)
`generating bicep from manifest: evaluating value for ConnectionStrings__blobs: evaluating connection string for blobs: unsupported property referenced in binding expression: bindings.blob.host for azure.bicep.v0`
### .NET Version info
.NET SDK:
Version: 9.0.102
Commit: cb83cd4923
Workload version: 9.0.100-manifests.43af17c7
MSBuild version: 17.12.18+ed8c6aec5
Runtime Environment:
OS Name: Mac OS X
OS Version: 15.2
OS Platform: Darwin
RID: osx-arm64
Base Path: /usr/local/share/dotnet/sdk/9.0.102/
.NET workloads installed:
There are no installed workloads to display.
Configured to use loose manifests when installing new manifests.
Host:
Version: 9.0.1
Architecture: arm64
Commit: c8acea2262
.NET SDKs installed:
9.0.102 [/usr/local/share/dotnet/sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 9.0.1 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 9.0.1 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Other architectures found:
None
Environment variables:
Not set
global.json file:
Not found
### Anything else?
_No response_
Contributor guide
Assessment
This issue has not been assessed yet.