# Set up Azure Cosmos DB in the AppHost

<Image
  src={cosmosDbIcon}
  alt="Azure Cosmos DB logo"
  width={100}
  height={100}
  class:list={'float-inline-left icon'}
  data-zoom-off
/>

This article is the reference for the Aspire Azure Cosmos DB hosting integration. It enumerates the AppHost APIs — with examples for both `AppHost.cs` and `apphost.mts` — that you use to model a Cosmos DB account, databases, and containers in your [`AppHost`](/get-started/app-host/) project.

If you're new to the Azure Cosmos DB integration, start with the [Get started with Azure Cosmos DB integrations](/integrations/cloud/azure/azure-cosmos-db/azure-cosmos-db-get-started/) guide. For how consuming apps read the connection information this page exposes, see [Connect to Azure Cosmos DB](../azure-cosmos-db-connect/).

## Installation

To start building an Aspire app that uses Azure Cosmos DB, install the [📦 Aspire.Hosting.Azure.CosmosDB](https://www.nuget.org/packages/Aspire.Hosting.Azure.CosmosDB) NuGet package:

```bash title="Terminal"
aspire add azure-cosmosdb
```

<LearnMore>
  Learn more about [`aspire add`](/reference/cli/commands/aspire-add/) in the command reference.
</LearnMore>

Or, choose a manual installation approach:

```csharp title="C# — AppHost.cs"
#:package Aspire.Hosting.Azure.CosmosDB@*
```

```xml title="XML — AppHost.csproj"
<PackageReference Include="Aspire.Hosting.Azure.CosmosDB" Version="*" />
```

```bash title="Terminal"
aspire add azure-cosmosdb
```

<LearnMore>
  Learn more about [`aspire add`](/reference/cli/commands/aspire-add/) in the command reference.
</LearnMore>

This updates your `aspire.config.json` with the Azure Cosmos DB hosting integration package:

```json title="aspire.config.json" ins={3}
{
  "packages": {
    "Aspire.Hosting.Azure.CosmosDB": "13.3.0"
  }
}
```

## Add Azure Cosmos DB resource

Once you've installed the hosting integration in your AppHost project, you can add an Azure Cosmos DB resource as shown in the following examples:

```csharp title="C# — AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

var cosmos = builder.AddAzureCosmosDB("cosmos-db");

var exampleProject = builder.AddProject<Projects.ExampleProject>("apiservice")
    .WithReference(cosmos);

// After adding all resources, run the app...
```
```typescript title="TypeScript — apphost.mts"
import { createBuilder } from './.aspire/modules/aspire.mjs';

const builder = await createBuilder();

const cosmos = await builder.addAzureCosmosDB("cosmos-db");

await builder.addNodeApp("api", "./api", "index.js")
    .withReference(cosmos);

// After adding all resources, run the app...
```
**Caution:** When you call `AddAzureCosmosDB` (or `addAzureCosmosDB`), it implicitly calls `AddAzureProvisioning` — which adds support for generating Azure resources dynamically during app startup. The app must configure the appropriate subscription and location. For more information, see [Local provisioning: Configuration](/integrations/cloud/azure/local-provisioning/#configuration).
**Note:** When you reference an Azure Cosmos DB resource from the AppHost, Aspire makes several properties available to the consuming project, such as the endpoint URI, account key, and connection string. For a complete list of these properties and per-language connection examples, see [Connect to Azure Cosmos DB](../azure-cosmos-db-connect/).

## Run as emulator

For local development, use the Azure Cosmos DB Emulator instead of a live Azure account. Chain `RunAsEmulator` (or `runAsEmulator`) on the resource builder:

```csharp title="C# — AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

var cosmos = builder.AddAzureCosmosDB("cosmos-db")
    .RunAsEmulator();

// After adding all resources, run the app...
```
```typescript title="TypeScript — apphost.mts"
import { createBuilder } from './.aspire/modules/aspire.mjs';

const builder = await createBuilder();

const cosmos = await builder.addAzureCosmosDB("cosmos-db");
await cosmos.runAsEmulator();

// After adding all resources, run the app...
```
When you call `RunAsEmulator`, it configures the Cosmos DB resource to run locally using the [Azure Cosmos DB Emulator](https://learn.microsoft.com/azure/cosmos-db/local-emulator). The emulator is accessible to Aspire as a container image (`mcr.microsoft.com/cosmosdb/emulator`). Aspire creates and starts the container when the AppHost starts.

### Configure emulator gateway port

By default, the Cosmos DB emulator container exposes the following endpoint:

| Endpoint | Container port | Host port |
| -------- | -------------- | --------- |
| `https`  | 8081           | dynamic   |

To configure a fixed host port, call `WithGatewayPort` (or `withGatewayPort`) inside the emulator callback:

```csharp title="C# — AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

var cosmos = builder.AddAzureCosmosDB("cosmos-db")
    .RunAsEmulator(emulator =>
    {
        emulator.WithGatewayPort(7777);
    });

// After adding all resources, run the app...
```
```typescript title="TypeScript — apphost.mts"
import { createBuilder } from './.aspire/modules/aspire.mjs';

const builder = await createBuilder();

const cosmos = await builder.addAzureCosmosDB("cosmos-db");
await cosmos.runAsEmulator({
    configureContainer: async emulator => {
        await emulator.withGatewayPort({ port: 7777 });
    }
});

// After adding all resources, run the app...
```
The Cosmos DB emulator container's port is mapped to the host port as shown in the following table:

| Endpoint name | Port mapping (`container:host`) |
| ------------: | ------------------------------- |
|       `https` | `8081:7777`                     |

### Configure emulator partition count

To configure the partition count for the Cosmos DB emulator container, call `WithPartitionCount` (or `withPartitionCount`) inside the emulator callback:

```csharp title="C# — AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

var cosmos = builder.AddAzureCosmosDB("cosmos-db")
    .RunAsEmulator(emulator =>
    {
        emulator.WithPartitionCount(100); // Defaults to 25
    });

// After adding all resources, run the app...
```
```typescript title="TypeScript — apphost.mts"
import { createBuilder } from './.aspire/modules/aspire.mjs';

const builder = await createBuilder();

const cosmos = await builder.addAzureCosmosDB("cosmos-db");
await cosmos.runAsEmulator({
    configureContainer: async emulator => {
        await emulator.withPartitionCount(100); // Defaults to 25
    }
});

// After adding all resources, run the app...
```
This is a shorthand for setting the `AZURE_COSMOS_EMULATOR_PARTITION_COUNT` environment variable.

### Configure emulator data volume

To persist the emulator data across container restarts, attach a named volume:

```csharp title="C# — AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

var cosmos = builder.AddAzureCosmosDB("cosmos-db")
    .RunAsEmulator(emulator =>
    {
        emulator.WithDataVolume();
    });

// After adding all resources, run the app...
```
```typescript title="TypeScript — apphost.mts"
import { createBuilder } from './.aspire/modules/aspire.mjs';

const builder = await createBuilder();

const cosmos = await builder.addAzureCosmosDB("cosmos-db");
await cosmos.runAsEmulator({
    configureContainer: async emulator => {
        await emulator.withDataVolume();
    }
});

// After adding all resources, run the app...
```
The data volume is mounted at `/tmp/cosmos/appdata` in the emulator container. When a `name` parameter isn't provided, the name is generated. The `AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE` environment variable is automatically set to `true`. For more information on data volumes, see [Docker docs: Volumes](https://docs.docker.com/engine/storage/volumes).

### Configure emulator with persistent lifetime

To configure the Cosmos DB emulator container with a persistent lifetime, call the `WithLifetime` method with `ContainerLifetime.Persistent`:

```csharp title="C# — AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

var cosmos = builder.AddAzureCosmosDB("cosmos-db")
    .RunAsEmulator(emulator =>
    {
        emulator.WithLifetime(ContainerLifetime.Persistent);
    });

// After adding all resources, run the app...
```
**Note:** The TypeScript AppHost doesn't currently expose a `withLifetime` API for the Cosmos DB emulator container.

## Run as preview emulator (Linux-based)

The [next generation of the Azure Cosmos DB emulator](https://learn.microsoft.com/azure/cosmos-db/emulator-linux) is Linux-based, supports a wide variety of processors and operating systems, and includes a built-in **Data Explorer** web UI. To use it, call `RunAsPreviewEmulator` (or `runAsPreviewEmulator`).

Since the preview emulator is an experimental feature, you must suppress the `ASPIRECOSMOSDB001` diagnostic to opt in:

```csharp title="C# — AppHost.cs"
#pragma warning disable ASPIRECOSMOSDB001

var builder = DistributedApplication.CreateBuilder(args);

var cosmos = builder.AddAzureCosmosDB("cosmos-db")
    .RunAsPreviewEmulator(emulator =>
    {
        emulator.WithDataExplorer();
    });

// After adding all resources, run the app...
```

```typescript title="TypeScript — apphost.mts"
import { createBuilder } from './.aspire/modules/aspire.mjs';

const builder = await createBuilder();

const cosmos = await builder.addAzureCosmosDB("cosmos-db");
await cosmos.runAsPreviewEmulator({
    configureContainer: async emulator => {
        await emulator.withDataExplorer();
    }
});

// After adding all resources, run the app...
```

`WithDataExplorer` (or `withDataExplorer`) exposes the Data Explorer endpoint that lets you view and manage data stored in the emulator via a browser-based UI.

## Connect to an existing Azure Cosmos DB account

You might have an existing Azure Cosmos DB account you want to connect to. Chain a call to `AsExisting` (or `asExisting`) on the resource builder:

```csharp title="C# — AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

var existingCosmosName = builder.AddParameter("existingCosmosName");
var existingCosmosResourceGroup = builder.AddParameter("existingCosmosResourceGroup");

var cosmos = builder.AddAzureCosmosDB("cosmos-db")
    .AsExisting(existingCosmosName, existingCosmosResourceGroup);

builder.AddProject<Projects.ExampleProject>()
    .WithReference(cosmos);

// After adding all resources, run the app...
```
```typescript title="TypeScript — apphost.mts"
import { createBuilder } from './.aspire/modules/aspire.mjs';

const builder = await createBuilder();

const existingCosmosName = await builder.addParameter("existingCosmosName");
const existingCosmosRG = await builder.addParameter("existingCosmosResourceGroup");

const cosmos = await builder.addAzureCosmosDB("cosmos-db");
await cosmos.asExisting(existingCosmosName, { resourceGroup: existingCosmosRG });

await builder.addNodeApp("api", "./api", "index.js")
    .withReference(cosmos);

// After adding all resources, run the app...
```
For more information on treating Azure Cosmos DB resources as existing resources, see [Use existing Azure resources](/integrations/cloud/azure/overview/#use-existing-azure-resources).
**Note:** Alternatively, instead of representing an Azure Cosmos DB account resource, you can add a connection string to the AppHost. This approach is weakly-typed and doesn't work with role assignments or infrastructure customizations.

## Add Azure Cosmos DB database and container resources

Aspire models parent-child relationships between Azure Cosmos DB resources. An Azure Cosmos DB account (`AzureCosmosDBResource`) can have multiple databases (`AzureCosmosDBDatabaseResource`), and each database can have multiple containers (`AzureCosmosDBContainerResource`).

### Add a database

To add an Azure Cosmos DB database resource, call `AddCosmosDatabase` (or `addCosmosDatabase`) on the Cosmos DB account resource builder:

```csharp title="C# — AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

var cosmos = builder.AddAzureCosmosDB("cosmos-db");
var db = cosmos.AddCosmosDatabase("db");

// After adding all resources, run the app...
```
```typescript title="TypeScript — apphost.mts"
import { createBuilder } from './.aspire/modules/aspire.mjs';

const builder = await createBuilder();

const cosmos = await builder.addAzureCosmosDB("cosmos-db");
const db = await cosmos.addCosmosDatabase("db");

// After adding all resources, run the app...
```
The `AddCosmosDatabase` call adds a logical database named `db` to your Cosmos DB account. The database is a logical container for collections and users.

### Add a container

An Azure Cosmos DB container is where data is stored. When you create a container, you must supply a partition key path. To add an Azure Cosmos DB container resource, call `AddContainer` (or `addContainer`) on the database resource builder:

```csharp title="C# — AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

var cosmos = builder.AddAzureCosmosDB("cosmos-db");
var db = cosmos.AddCosmosDatabase("db");
var container = db.AddContainer("entries", "/id");

// After adding all resources, run the app...
```
```typescript title="TypeScript — apphost.mts"
import { createBuilder } from './.aspire/modules/aspire.mjs';

const builder = await createBuilder();

const cosmos = await builder.addAzureCosmosDB("cosmos-db");
const db = await cosmos.addCosmosDatabase("db");
const container = await db.addContainer("entries", "/id");

// After adding all resources, run the app...
```
The second argument to `AddContainer` (or `addContainer`) is the partition key path (for example, `"/id"`). In the TypeScript AppHost, you can also pass an array of paths for composite partition keys. For more information, see [Databases, containers, and items in Azure Cosmos DB](https://learn.microsoft.com/azure/cosmos-db/resource-model).

### Parent-child resource relationship example

The following example demonstrates a full parent-child hierarchy — a single Cosmos DB account with two databases, each containing multiple containers:

```csharp title="C# — AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

var cosmos = builder.AddAzureCosmosDB("cosmos");

var customers = cosmos.AddCosmosDatabase("customers");
var profiles = customers.AddContainer("profiles", "/id");

var orders = cosmos.AddCosmosDatabase("orders");
var details = orders.AddContainer("details", "/id");
var history = orders.AddContainer("history", "/id");

builder.AddProject<Projects.Api>("api")
    .WithReference(profiles)
    .WithReference(details)
    .WithReference(history);

builder.Build().Run();
```
```typescript title="TypeScript — apphost.mts"
import { createBuilder } from './.aspire/modules/aspire.mjs';

const builder = await createBuilder();

const cosmos = await builder.addAzureCosmosDB("cosmos");

const customers = await cosmos.addCosmosDatabase("customers");
const profiles = await customers.addContainer("profiles", "/id");

const orders = await cosmos.addCosmosDatabase("orders");
const details = await orders.addContainer("details", "/id");
const history = await orders.addContainer("history", "/id");

await builder.addNodeApp("api", "./api", "index.js")
    .withReference(profiles)
    .withReference(details)
    .withReference(history);

await builder.build().run();
```
The preceding code adds a Cosmos DB account named `cosmos` with two databases: `customers` and `orders`. The `customers` database has a single container named `profiles`, while the `orders` database has two containers: `details` and `history`. The partition key for each container is `/id`.

The following diagram illustrates the parent-child relationship between the Azure Cosmos DB resources:

<ThemeImage
  dark={cosmosResourceRelationships}
  light={cosmosResourceRelationshipsLight}
  label="Azure Cosmos DB resource relationships"
  alt="A diagram depicting Azure Cosmos DB resource parent child relationships."
/>

When your AppHost code expresses parent-child relationships, consuming apps can deep-link to these resources by name. For example, the `customers` database can be referenced by name in the client project, registering a `Microsoft.Azure.Cosmos.Database` instance that connects to the `customers` database. The same applies to named containers.

## Enable access key authentication

By default, the Azure Cosmos DB hosting integration uses Microsoft Entra ID (role-based access). To enable access key authentication instead, call `WithAccessKeyAuthentication` (or `withAccessKeyAuthentication`):

```csharp title="C# — AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

var cosmos = builder.AddAzureCosmosDB("cosmos-db")
    .WithAccessKeyAuthentication();

// After adding all resources, run the app...
```
```typescript title="TypeScript — apphost.mts"
import { createBuilder } from './.aspire/modules/aspire.mjs';

const builder = await createBuilder();

const cosmos = await builder.addAzureCosmosDB("cosmos-db");
await cosmos.withAccessKeyAuthentication();

// After adding all resources, run the app...
```
When access key authentication is enabled, Aspire injects additional `AccountKey` and `ConnectionString` connection properties into consuming apps. For a complete list of connection properties by authentication mode, see [Connect to Azure Cosmos DB](../azure-cosmos-db-connect/#connection-properties).

## Provisioning-generated Bicep

If you're new to [Bicep](https://learn.microsoft.com/azure/azure-resource-manager/bicep/overview), it's a domain-specific language for defining Azure resources. With Aspire, you don't need to write Bicep by hand — the provisioning APIs generate it for you. When you publish your app, the generated Bicep is output alongside the manifest file. When you add an Azure Cosmos DB resource, the following Bicep is generated:

```bicep title="Generated Bicep — cosmos.bicep"
@description('The location for the resource(s) to be deployed.')
param location string = resourceGroup().location

resource cosmos 'Microsoft.DocumentDB/databaseAccounts@2024-08-15' = {
  name: take('cosmos-${uniqueString(resourceGroup().id)}', 44)
  location: location
  properties: {
    locations: [
      {
        locationName: location
        failoverPriority: 0
      }
    ]
    capabilities: [
      {
        name: 'EnableServerless'
      }
    ]
    consistencyPolicy: {
      defaultConsistencyLevel: 'Session'
    }
    databaseAccountOfferType: 'Standard'
    disableLocalAuth: true
  }
  kind: 'GlobalDocumentDB'
  tags: {
    'aspire-resource-name': 'cosmos'
  }
}

output connectionString string = cosmos.properties.documentEndpoint

output name string = cosmos.name
```

The preceding Bicep provisions an Azure Cosmos DB account resource. Additionally, role assignments are created for the Azure resource in a separate module:

```bicep title="Generated Bicep — cosmos-roles.bicep"
@description('The location for the resource(s) to be deployed.')
param location string = resourceGroup().location

param cosmos_outputs_name string

param principalId string

resource cosmos 'Microsoft.DocumentDB/databaseAccounts@2024-08-15' existing = {
  name: cosmos_outputs_name
}

resource cosmos_roleDefinition 'Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions@2024-08-15' existing = {
  name: '00000000-0000-0000-0000-000000000002'
  parent: cosmos
}

resource cosmos_roleAssignment 'Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments@2024-08-15' = {
  name: guid(principalId, cosmos_roleDefinition.id, cosmos.id)
  properties: {
    principalId: principalId
    roleDefinitionId: cosmos_roleDefinition.id
    scope: cosmos.id
  }
  parent: cosmos
}
```

The generated Bicep is a starting point and is influenced by changes to the provisioning infrastructure in C#. Customizations to the Bicep file directly will be overwritten, so make changes through the C# provisioning APIs to ensure they are reflected in the generated files.

## Customize provisioning infrastructure

All Aspire Azure resources are subclasses of the `AzureProvisioningResource` type. This type enables fluent customization of the generated Bicep using the `ConfigureInfrastructure` (or `configureInfrastructure`) API. For example, you can configure the `kind`, `consistencyPolicy`, `locations`, and more:

```csharp title="C# — AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

builder.AddAzureCosmosDB("cosmos-db")
    .ConfigureInfrastructure(infra =>
    {
        var cosmosDbAccount = infra.GetProvisionableResources()
                                    .OfType<CosmosDBAccount>()
                                    .Single();

        cosmosDbAccount.Kind = CosmosDBAccountKind.MongoDB;
        cosmosDbAccount.ConsistencyPolicy = new()
        {
            DefaultConsistencyLevel = DefaultConsistencyLevel.Strong,
        };
        cosmosDbAccount.Tags.Add("ExampleKey", "Example value");
    });
```
```typescript title="TypeScript — apphost.mts"
import { createBuilder } from './.aspire/modules/aspire.mjs';

const builder = await createBuilder();

const cosmos = await builder.addAzureCosmosDB("cosmos-db");
await cosmos.configureInfrastructure(async infra => {
    const resources = await infra.getProvisionableResources();
    const account = resources.find(r => r.resourceType === 'Microsoft.DocumentDB/databaseAccounts');
    if (account) {
        account.tags = { ...account.tags, ExampleKey: 'Example value' };
    }
});
```
**Note:** The TypeScript `configureInfrastructure` API provides access to raw Bicep resource objects. Strongly-typed resource properties (such as `CosmosDBAccountKind`) are only available in the C# provisioning SDK.

## Hosting integration health checks

The Azure Cosmos DB hosting integration automatically adds a health check for the Cosmos DB resource. The health check verifies that the Cosmos DB is running and that a connection can be established to it.

The hosting integration relies on the [📦 AspNetCore.HealthChecks.CosmosDb](https://www.nuget.org/packages/AspNetCore.HealthChecks.CosmosDb) NuGet package.

## Connection properties

For the full reference of Azure Cosmos DB connection properties — and how consuming apps in C#, TypeScript, Python, and Go read them — see [Connect to Azure Cosmos DB](../azure-cosmos-db-connect/).