Skip to content
Docs Try Aspire
Docs Try

Set up Azure Table Storage in the AppHost

Azure Table Storage logo

This article is the reference for the Aspire Azure Table Storage hosting integration. It enumerates the AppHost APIs — with examples for both AppHost.cs and apphost.ts — that you use to model Azure Storage accounts and table resources in your AppHost project.

If you’re new to the Azure Table Storage integration, start with the Get started with Azure Table Storage integrations guide. For how consuming apps read the connection information this page exposes, see Connect to Azure Table Storage.

To start building an Aspire app that uses Azure Table Storage, install the 📦 Aspire.Hosting.Azure.Storage NuGet package:

Terminal
aspire add azure-storage

Learn more about aspire add in the command reference.

Or, choose a manual installation approach:

C# — AppHost.cs
#:package Aspire.Hosting.Azure.Storage@*
XML — AppHost.csproj
<PackageReference Include="Aspire.Hosting.Azure.Storage" Version="*" />

Once you’ve installed the hosting integration in your AppHost project, you can add an Azure Storage resource and then add a table resource to it:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var tables = builder.AddAzureStorage("storage")
.AddTables("tables");
builder.AddProject<Projects.ExampleProject>("apiservice")
.WithReference(tables)
.WaitFor(tables);
// After adding all resources, run the app...
builder.Build().Run();
  1. An Azure Storage resource named storage is added to the AppHost.

  2. A table storage resource named tables is added to the storage resource by chaining a call to AddTables (or addTables).

  3. The table storage resource is referenced from the consuming project with WithReference (or withReference), which injects connection properties as environment variables.

  4. WaitFor (or waitFor) ensures the consuming project waits until the table storage resource is ready before starting.

For local development, configure the storage resource to use the Azurite emulator instead of a real Azure Storage account. Call RunAsEmulator (or runAsEmulator) on the storage resource:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var storage = builder.AddAzureStorage("storage")
.RunAsEmulator();
var tables = storage.AddTables("tables");
builder.AddProject<Projects.ExampleProject>("apiservice")
.WithReference(tables)
.WaitFor(tables);
// After adding all resources, run the app...
builder.Build().Run();

When RunAsEmulator (or runAsEmulator) is called, the Aspire AppHost starts an Azurite container and routes all Azure Storage API calls to it during local development. No Azure subscription or credentials are required.

By default, when Aspire configures the Azurite container, it exposes the following endpoints:

EndpointContainer portHost port
blob10000dynamic
queue10001dynamic
table10002dynamic

The host port is dynamic by default. When the container starts, the ports are mapped to random ports on the host machine. To fix the endpoint ports, configure them inside the RunAsEmulator (or runAsEmulator) callback:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var storage = builder.AddAzureStorage("storage")
.RunAsEmulator(azurite =>
{
azurite.WithBlobPort(27000)
.WithQueuePort(27001)
.WithTablePort(27002);
});
// After adding all resources, run the app...
builder.Build().Run();

The preceding code configures the Azurite container ports as follows:

EndpointPort mapping (container:host)
blob10000:27000
queue10001:27001
table10002:27002

Configure Azurite container with persistent lifetime

Section titled “Configure Azurite container with persistent lifetime”

To configure the Azurite container with a persistent lifetime so it survives app restarts, call WithLifetime (or withLifetime) with ContainerLifetime.Persistent:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var storage = builder.AddAzureStorage("storage")
.RunAsEmulator(azurite =>
{
azurite.WithLifetime(ContainerLifetime.Persistent);
});
// After adding all resources, run the app...
builder.Build().Run();

Configure Azurite container with data volume

Section titled “Configure Azurite container with data volume”

To persist Azurite data across container restarts with a data volume, call WithDataVolume (or withDataVolume) on the emulator resource:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var storage = builder.AddAzureStorage("storage")
.RunAsEmulator(azurite =>
{
azurite.WithDataVolume();
});
// After adding all resources, run the app...
builder.Build().Run();

The data volume is mounted at the /data path in the Azurite container and when a name parameter isn’t provided, the name is formatted as .azurite/{resource name}. For more information on data volumes and details on why they’re preferred over bind mounts, see Docker docs: Volumes.

Configure Azurite container with data bind mount

Section titled “Configure Azurite container with data bind mount”

To add a data bind mount to the Azurite container instead of a named volume, call WithDataBindMount (or withDataBindMount):

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var storage = builder.AddAzureStorage("storage")
.RunAsEmulator(azurite =>
{
azurite.WithDataBindMount("../azurite/data");
});
// After adding all resources, run the app...
builder.Build().Run();

Data bind mounts rely on the host machine’s filesystem to persist Azurite data across container restarts. The bind mount path ../azurite/data is relative to the AppHost directory. For more information, see Docker docs: Bind mounts.

When the Aspire AppHost runs, storage resources can be accessed by external tools such as the Azure Storage Explorer. If your storage resource is running locally using Azurite, it’s automatically discovered by the Azure Storage Explorer.

To connect to the storage resource from Azure Storage Explorer, follow these steps:

  1. Run the Aspire AppHost.

  2. Open the Azure Storage Explorer.

  3. View the Explorer pane.

  4. Select the Refresh all link to refresh the list of storage accounts.

  5. Expand the Emulator & Attached node.

  6. Expand the Storage Accounts node.

  7. You should see a storage account with your resource’s name as a prefix:

    Azure Storage Explorer: Azurite storage resource discovered.

For more information on using the Azure Storage Explorer, see Get started with Storage Explorer.

Connect to an existing Azure Storage account

Section titled “Connect to an existing Azure Storage account”

If you have an existing Azure Storage account, you can connect to it using the AsExisting (or asExisting) method instead of provisioning a new one:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var existingStorageName = builder.AddParameter("existingStorageName");
var existingStorageResourceGroup = builder.AddParameter("existingStorageResourceGroup");
var storageAccount = builder.AddAzureStorage("storage")
.AsExisting(existingStorageName, existingStorageResourceGroup);
var tables = storageAccount.AddTables("tables");
builder.AddProject<Projects.ExampleProject>("apiservice")
.WithReference(tables);
// After adding all resources, run the app...
builder.Build().Run();

When you call RunAsExisting, PublishAsExisting, or AsExisting methods to work with resources that are already present in your Azure subscription, you must add certain configuration values to your AppHost to ensure that Aspire can locate them. The necessary configuration values include SubscriptionId, AllowResourceGroupCreation, ResourceGroup, and Location. If you don’t set them, “Missing configuration” errors appear in the Aspire dashboard. For more information, see Use existing Azure resources.

When you reference an Azure Table Storage resource using WithReference (or withReference), Aspire injects the following connection properties into the consuming app:

Property NameEnvironment variableDescription
ConnectionString{RESOURCE}_CONNECTIONSTRINGThe full Azure Storage connection string. Available in emulator mode and when configured for key-based access.
TableEndpoint{RESOURCE}_TABLEENDPOINTThe URI of the Table Storage service endpoint, with the format https://{accountname}.table.core.windows.net/. Available when using Azure Managed Identity or token-based access.

For example, for a resource named tables, the environment variables are TABLES_CONNECTIONSTRING and TABLES_TABLEENDPOINT.

For per-language connection examples and client library setup, see Connect to Azure Table Storage.