.NET Aspire provides first-class support for deploying to Azure Container Apps, a fully managed serverless container platform that handles infrastructure, scaling, and monitoring.
Prerequisites
Azure subscription
Azure CLI installed and authenticated
.NET Aspire application with AppHost project
Aspire CLI installed (dotnet tool install -g aspire)
Azure Container Apps Deployment
Azure Container Apps is the recommended deployment target for Aspire applications, offering:
Automatic scaling based on HTTP traffic, events, or CPU/memory
Built-in ingress and load balancing
Managed identity and Azure service integration
Container registry integration
Observability with Azure Monitor
Setting Up Container App Environment
Add an Azure Container Apps environment to your AppHost:
var builder = DistributedApplication . CreateBuilder ( args );
// Add Container Apps environment
var containerAppEnv = builder . AddAzureContainerAppEnvironment ( "myenv" );
// Add your services
var cache = builder . AddRedis ( "cache" );
var apiService = builder . AddProject < Projects . ApiService >( "apiservice" )
. WithReference ( cache );
builder . Build (). Run ();
The environment automatically provisions:
Container App Environment : The managed environment for your containers
Container Registry : Azure Container Registry for storing images
Log Analytics Workspace : For logs and metrics
Managed Identity : For secure Azure resource access
Customizing the Environment
Using Azure Naming Conventions
Configure resources to use azd-compatible naming:
var containerAppEnv = builder . AddAzureContainerAppEnvironment ( "myenv" )
. WithAzdResourceNaming ();
This generates resource names like:
cae-{uniqueString} - Container App Environment
acr-{uniqueString} - Container Registry
law-{uniqueString} - Log Analytics Workspace
mi-{uniqueString} - Managed Identity
Compact Resource Naming
For length-constrained resources (like storage accounts), use compact naming:
var containerAppEnv = builder . AddAzureContainerAppEnvironment ( "myenv" )
. WithCompactResourceNaming ();
This is an experimental feature marked with ASPIREACANAMING001. Use with caution in production.
Configuring the Aspire Dashboard
Control whether the Aspire Dashboard is deployed:
var containerAppEnv = builder . AddAzureContainerAppEnvironment ( "myenv" )
. WithDashboard ( enable : true ); // Default is true
Using Custom Log Analytics Workspace
Reference an existing Log Analytics workspace:
var logAnalytics = builder . AddAzureLogAnalyticsWorkspace ( "myworkspace" );
var containerAppEnv = builder . AddAzureContainerAppEnvironment ( "myenv" )
. WithAzureLogAnalyticsWorkspace ( logAnalytics );
HTTPS Endpoint Upgrade
By default, HTTP endpoints are upgraded to HTTPS for security:
// Disable HTTPS upgrade (not recommended)
var containerAppEnv = builder . AddAzureContainerAppEnvironment ( "myenv" )
. WithHttpsUpgrade ( upgrade : false );
Deploying the Application
Deploy your application using the Aspire CLI:
# Generate deployment artifacts
aspire deploy --output-path ./deployment
# The command generates:
# - aspire-manifest.json
# - Bicep files for Azure resources
The deployment process:
Builds container images for all project resources
Pushes images to the provisioned Azure Container Registry
Generates Bicep/ARM templates for infrastructure
Deploys resources to Azure
Understanding Deployment Targets
When you add an Azure Container Apps environment, Aspire automatically annotates compute resources with deployment target information:
// Internally, this is added to each compute resource:
// src/Aspire.Hosting.Azure.AppContainers/AzureContainerAppsInfrastructure.cs:60
r . Annotations . Add ( new DeploymentTargetAnnotation ( containerApp )
{
ContainerRegistry = environment ,
ComputeEnvironment = environment
});
This annotation tells the deployment pipeline:
Which container registry to push images to
Which Container App Environment to deploy to
How to configure the container app
Manifest Generation for Azure
When deploying to Azure Container Apps, the manifest includes deployment metadata:
{
"apiservice" : {
"type" : "project.v1" ,
"path" : "../ApiService/ApiService.csproj" ,
"deployment" : {
"container" : {
"image" : "{apiservice.image}" ,
"registry" : "{myenv.outputs.AZURE_CONTAINER_REGISTRY_ENDPOINT}"
},
"environment" : {
"id" : "{myenv.outputs.AZURE_CONTAINER_APPS_ENVIRONMENT_ID}"
}
},
"env" : { },
"bindings" : { }
}
}
Azure Resource Integration
Aspire provides seamless integration with Azure services:
Azure Storage
var storage = builder . AddAzureStorage ( "storage" );
var blobs = storage . AddBlobs ( "blobs" );
var queues = storage . AddQueues ( "queues" );
var tables = storage . AddTables ( "tables" );
builder . AddProject < Projects . ApiService >( "api" )
. WithReference ( blobs );
Azure Cosmos DB
var cosmos = builder . AddAzureCosmosDB ( "cosmos" )
. AddDatabase ( "mydb" );
builder . AddProject < Projects . DataService >( "dataservice" )
. WithReference ( cosmos );
Azure Service Bus
var serviceBus = builder . AddAzureServiceBus ( "messaging" )
. AddQueue ( "orders" )
. AddTopic ( "events" );
builder . AddProject < Projects . MessageProcessor >( "processor" )
. WithReference ( serviceBus );
Azure SQL Database
var sql = builder . AddAzureSqlServer ( "sql" )
. AddDatabase ( "catalogdb" );
builder . AddProject < Projects . CatalogService >( "catalog" )
. WithReference ( sql );
Infrastructure as Code
Aspire uses Azure Bicep for infrastructure provisioning. The infrastructure code is generated from your app model.
Custom Infrastructure
Customize the generated infrastructure:
var containerAppEnv = builder . AddAzureContainerAppEnvironment ( "myenv" )
. ConfigureInfrastructure ( infra =>
{
// Access the AzureResourceInfrastructure to customize
// Add custom Bicep resources, modify existing ones, etc.
});
Azure Provisioning Options
Configure global Azure provisioning settings:
builder . Services . Configure < AzureProvisioningOptions >( options =>
{
// Configure whether resources support targeted role assignments
options . SupportsTargetedRoleAssignments = true ;
});
Deployment Best Practices
Avoid storing credentials by using Azure Managed Identity: var storage = builder . AddAzureStorage ( "storage" )
. RunAsEmulator () // Local development
. AddBlobs ( "blobs" );
In production, managed identity is used automatically.
Use different environments for dev, staging, and production: aspire deploy --environment Staging --output-path ./staging
aspire deploy --environment Production --output-path ./prod
Use Azure Monitor and Application Insights: var appInsights = builder . AddAzureApplicationInsights ( "insights" );
builder . AddProject < Projects . ApiService >( "api" )
. WithReference ( appInsights );
Troubleshooting
Common Issues
Error : No container registry associated with environmentSolution : Ensure the Container Apps environment is properly configured:var containerAppEnv = builder . AddAzureContainerAppEnvironment ( "myenv" );
The registry is created automatically. Error : Unable to authenticate to AzureSolution : Login with Azure CLI:az login
az account set --subscription < subscription-i d >
Error : Resource names already existSolution : Use unique naming or clear deployment cache:aspire deploy --clear-cache --output-path ./deployment
Next Steps
Azure Hosting Integrations Explore all available Azure service integrations
Kubernetes Deployment Learn about deploying to Kubernetes clusters
CLI Deploy Command Full reference for the aspire deploy command
App Model Understand the Aspire application model