Skip to main content
.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:
  1. Builds container images for all project resources
  2. Pushes images to the provisioned Azure Container Registry
  3. Generates Bicep/ARM templates for infrastructure
  4. 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);
Container Apps automatically scale, but you can customize:
builder.AddProject<Projects.ApiService>("api")
    .PublishAsAzureContainerApp((module, app) =>
    {
        // Customize container app settings
        // Note: This is an advanced scenario
    });

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.

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

Build docs developers (and LLMs) love