Cosmos DB
Introduction
Section titled “Introduction”Azure Cosmos DB is a globally distributed, multi-model NoSQL database service designed for high availability and low latency. It supports multiple APIs including SQL (NoSQL), MongoDB, Cassandra, Gremlin, and Table, enabling teams to choose the data model that best fits their application. Cosmos DB is commonly used for real-time applications, globally replicated datasets, and multi-tenant SaaS platforms that require predictable performance at any scale. For more information, see Introduction to Azure Cosmos DB.
LocalStack for Azure provides a local environment for building and testing applications that make use of Azure Cosmos DB. The supported APIs are available on our API Coverage section, which provides information on the extent of Cosmos DB’s integration with LocalStack.
Getting started
Section titled “Getting started”This guide walks you through creating Cosmos DB accounts, databases, and containers using the SQL and MongoDB APIs.
Launch LocalStack using your preferred method. For more information, see Introduction to LocalStack for Azure. Once the container is running, enable Azure CLI interception by running:
lstk az start-interceptionThis command points the az CLI away from the public Azure management REST API and toward the LocalStack for Azure emulator API.
To revert this configuration, run:
lstk az stop-interceptionThis reconfigures the az CLI to send commands to the official Azure management REST API.
SQL (NoSQL) API
Section titled “SQL (NoSQL) API”This section walks through creating a Cosmos DB account with the SQL API, creating a database and a container, and listing resources.
Create a resource group
Section titled “Create a resource group”Create a resource group to hold all resources created in this guide:
az group create --name rg-cosmos-demo --location eastus{ "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-cosmos-demo", "location": "eastus", "name": "rg-cosmos-demo", "properties": { "provisioningState": "Succeeded" }, "type": "Microsoft.Resources/resourceGroups"}Create a Cosmos DB account
Section titled “Create a Cosmos DB account”Create a Cosmos DB account configured for the SQL API. Tags and capabilities are stored and returned, so tools that compare the response with their configuration, such as Terraform and Bicep, do not report drift:
az cosmosdb create \ --name mycosmosaccount \ --resource-group rg-cosmos-demo \ --locations regionName=eastus \ --tags env=dev{ "databaseAccountOfferType": "Standard", "documentEndpoint": "https://mycosmosaccount.cosmos.documents.localhost.localstack.cloud:4511/", "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-cosmos-demo/providers/Microsoft.DocumentDB/databaseAccounts/mycosmosaccount", "instanceId": "7f34833d-901c-429f-ae09-da2e48417e21", "kind": "GlobalDocumentDB", "location": "East US", "name": "mycosmosaccount", "provisioningState": "Succeeded", "resourceGroup": "rg-cosmos-demo", "tags": { "env": "dev" }, "type": "Microsoft.DocumentDB/databaseAccounts", ...}The documentEndpoint points at the emulated account. Applications use it exactly as they would use the Azure endpoint; see Connect with an SDK for the certificate setup.
The account uses provisioned throughput, because later sections set throughput on its database. Azure does not allow that on a serverless account (--capabilities EnableServerless).
Running the same az cosmosdb create again updates the existing account in place: it keeps its instanceId, its keys and its databases, and only the properties you pass change. Real Azure rejects an account name that is already taken elsewhere, and so does LocalStack.
Update an account
Section titled “Update an account”Change properties of an existing account with az cosmosdb update, which sends a PATCH request. Only the properties you pass change:
az cosmosdb update \ --name mycosmosaccount \ --resource-group rg-cosmos-demo \ --tags env=test \ --query "{name:name, tags:tags, instanceId:instanceId}"{ "instanceId": "7f34833d-901c-429f-ae09-da2e48417e21", "name": "mycosmosaccount", "tags": { "env": "test" }}List account keys
Section titled “List account keys”Retrieve the primary and secondary access keys for the account:
az cosmosdb keys list \ --name mycosmosaccount \ --resource-group rg-cosmos-demo{ "primaryMasterKey": "C2y6yDjf5/R+ob0N8A7C...", "primaryReadonlyMasterKey": "C2y6yDjf5/R+ob0N8A7C...", "secondaryMasterKey": "C2y6yDjf5/R+ob0N8A7C...", "secondaryReadonlyMasterKey": "C2y6yDjf5/R+ob0N8A7C..."}Retrieve the connection string for the account:
az cosmosdb keys list \ --type connection-strings \ --name mycosmosaccount \ --resource-group rg-cosmos-demo \ --query "connectionStrings[0].connectionString""AccountEndpoint=https://mycosmosaccount.cosmos.documents.localhost.localstack.cloud:4511/;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==;"Create a SQL database
Section titled “Create a SQL database”Create a SQL API database within the Cosmos DB account, with dedicated throughput:
az cosmosdb sql database create \ --account-name mycosmosaccount \ --resource-group rg-cosmos-demo \ --name mydb \ --throughput 400{ "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-cosmos-demo/providers/Microsoft.DocumentDB/databaseAccounts/mycosmosaccount/sqlDatabases/mydb", "name": "mydb", "resourceGroup": "rg-cosmos-demo", "type": "Microsoft.DocumentDB/databaseAccounts/sqlDatabases"...}Create a SQL container
Section titled “Create a SQL container”Create a SQL container with a partition key path of /id and a default time to live. The partition key, the indexing policy, the default TTL and unique key policies you pass are applied to the container and returned:
az cosmosdb sql container create \ --account-name mycosmosaccount \ --resource-group rg-cosmos-demo \ --database-name mydb \ --name mycontainer \ --partition-key-path /id \ --ttl 3600{ "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-cosmos-demo/providers/Microsoft.DocumentDB/databaseAccounts/mycosmosaccount/sqlDatabases/mydb/containers/mycontainer", "name": "mycontainer", "resource": { "defaultTtl": 3600, "id": "mycontainer", "partitionKey": { "kind": "Hash", "paths": [ "/id" ] }, ... }, "resourceGroup": "rg-cosmos-demo", "type": "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers"}Running az cosmosdb sql database create or az cosmosdb sql container create again for an existing resource updates it in place, which is what a Bicep or Terraform re-deployment does. Mutable properties such as the TTL and the indexing policy are replaced; a changed partition key is rejected, as on Azure:
az cosmosdb sql container create \ --account-name mycosmosaccount \ --resource-group rg-cosmos-demo \ --database-name mydb \ --name mycontainer \ --partition-key-path /id \ --ttl 7200 \ --query "{name:name, defaultTtl:resource.defaultTtl}"{ "defaultTtl": 7200, "name": "mycontainer"}Manage throughput
Section titled “Manage throughput”Read and change the throughput of a database or container. A resource created without dedicated throughput has no throughput settings, and reading them returns NotFound, as on Azure:
az cosmosdb sql database throughput show \ --account-name mycosmosaccount \ --resource-group rg-cosmos-demo \ --name mydb{ "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-cosmos-demo/providers/Microsoft.DocumentDB/databaseAccounts/mycosmosaccount/sqlDatabases/mydb/throughputSettings/default", "resource": { "instantMaximumThroughput": "10000", "minimumThroughput": "400", "softAllowedMaximumThroughput": "1000000", "throughput": 400, ... }, "resourceGroup": "rg-cosmos-demo", "type": "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/throughputSettings"}az cosmosdb sql database throughput update \ --account-name mycosmosaccount \ --resource-group rg-cosmos-demo \ --name mydb \ --throughput 1000 \ --query "resource.throughput"1000The same commands exist for containers (az cosmosdb sql container throughput show|update) and for MongoDB databases and collections (az cosmosdb mongodb database|collection throughput show|update). Autoscale settings (--max-throughput) are stored and reported too. Throughput is recorded and returned, but request units are not metered or enforced.
List databases and containers
Section titled “List databases and containers”List all SQL databases in the account and all containers within the database:
az cosmosdb sql database list \ --account-name mycosmosaccount \ --resource-group rg-cosmos-demo[ { "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-cosmos-demo/providers/Microsoft.DocumentDB/databaseAccounts/mycosmosaccount/sqlDatabases/mydb", "name": "mydb", "resourceGroup": "rg-cosmos-demo", "type": "Microsoft.DocumentDB/databaseAccounts/sqlDatabases" }]Then list all containers in the database:
az cosmosdb sql container list \ --account-name mycosmosaccount \ --resource-group rg-cosmos-demo \ --database-name mydb[ { "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-cosmos-demo/providers/Microsoft.DocumentDB/databaseAccounts/mycosmosaccount/sqlDatabases/mydb/containers/mycontainer", "name": "mycontainer", "resourceGroup": "rg-cosmos-demo", "type": "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers" }]Reading a resource that does not exist returns the same NotFound error as Azure, and deleting one that does not exist succeeds, so tools that read before they create, or retry a delete, behave as they do against Azure:
az cosmosdb sql container show \ --account-name mycosmosaccount \ --resource-group rg-cosmos-demo \ --database-name mydb \ --name missingERROR: (NotFound) Message: {"code":"NotFound","message":"Message: {\"Errors\":[\"Resource Not Found. Learn more: https://aka.ms/cosmosdb-tsg-not-found\"]}..."}Code: NotFoundConnect with an SDK
Section titled “Connect with an SDK”The emulated account speaks the Cosmos DB REST protocol, so the official SDKs work against it unchanged. The endpoint uses a certificate issued by the LocalStack root CA. Download it from the running emulator and make it trusted by your SDK, for example through REQUESTS_CA_BUNDLE for the Python SDK or NODE_EXTRA_CA_CERTS for the Node.js SDK:
curl -s -o ls-root-ca.crt http://localhost:4566/_localstack/certs/ca/LocalStack_LOCAL_Root_CA.crtexport REQUESTS_CA_BUNDLE=$PWD/ls-root-ca.crtExport the account endpoint and primary key for the SDK to read:
COSMOS_ENDPOINT=$(az cosmosdb show \ --name mycosmosaccount \ --resource-group rg-cosmos-demo \ --query "documentEndpoint" \ --output tsv)
COSMOS_KEY=$(az cosmosdb keys list \ --name mycosmosaccount \ --resource-group rg-cosmos-demo \ --query "primaryMasterKey" \ --output tsv)
export COSMOS_ENDPOINT COSMOS_KEYCreate a database, a container and an item with the Python SDK, reading the endpoint and key from those variables:
import os
from azure.cosmos import CosmosClient, PartitionKey
client = CosmosClient(os.environ["COSMOS_ENDPOINT"], os.environ["COSMOS_KEY"])database = client.create_database_if_not_exists("appdb")container = database.create_container_if_not_exists("orders", partition_key=PartitionKey(path="/customerId"))container.upsert_item({"id": "order-1", "customerId": "c-42", "total": 19.99})Resources created through the data plane are visible to the management plane, so an application can create its own databases and containers and az, Bicep or Terraform still see them:
az cosmosdb sql database list \ --account-name mycosmosaccount \ --resource-group rg-cosmos-demo \ --query "[].name"[ "mydb", "appdb"]MongoDB API
Section titled “MongoDB API”This section walks through creating a Cosmos DB account with the MongoDB API, creating a database, and connecting with a MongoDB client.
Create a MongoDB Cosmos DB account
Section titled “Create a MongoDB Cosmos DB account”Create a second Cosmos DB account configured for the MongoDB API. The requested server version is stored and returned, but it does not change the version of the backing MongoDB server. Use a driver compatible with the backing server.
az cosmosdb create \ --name mymongoaccount \ --resource-group rg-cosmos-demo \ --locations regionName=eastus \ --kind MongoDB \ --server-version 7.0{ "apiProperties": { "serverVersion": "7.0" }, "capabilities": [ { "name": "EnableMongo" } ], "databaseAccountOfferType": "Standard", "documentEndpoint": "https://mymongoaccount.documents.azure.com:443/", "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-cosmos-demo/providers/Microsoft.DocumentDB/databaseAccounts/mymongoaccount", "kind": "MongoDB", "location": "East US", "name": "mymongoaccount", "provisioningState": "Succeeded", "resourceGroup": "rg-cosmos-demo", "type": "Microsoft.DocumentDB/databaseAccounts", ...}Retrieve connection string
Section titled “Retrieve connection string”Retrieve the MongoDB-compatible connection string for the account:
az cosmosdb keys list \ --name mymongoaccount \ --resource-group rg-cosmos-demo \ --type connection-strings \ --query "connectionStrings[0].connectionString" \ --output tsvmongodb://primary:<key>@mymongoaccount.mongo.cosmos.localhost.localstack.cloud:4512/The host name resolves to the emulator and the port is assigned per account, so use the connection string exactly as returned.
Create a MongoDB database
Section titled “Create a MongoDB database”Create a MongoDB database within the account:
az cosmosdb mongodb database create \ --account-name mymongoaccount \ --resource-group rg-cosmos-demo \ --name mymongodb{ "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-cosmos-demo/providers/Microsoft.DocumentDB/databaseAccounts/mymongoaccount/mongodbDatabases/mymongodb", "name": "mymongodb", "resourceGroup": "rg-cosmos-demo", "type": "Microsoft.DocumentDB/databaseAccounts/mongodbDatabases"...}Create a MongoDB collection
Section titled “Create a MongoDB collection”Create a MongoDB collection inside the database with a shard key, a unique index and dedicated throughput. The shard key and the index options are applied to the collection and returned:
az cosmosdb mongodb collection create \ --account-name mymongoaccount \ --resource-group rg-cosmos-demo \ --database-name mymongodb \ --name mycollection \ --shard userId \ --idx '[{"key":{"keys":["_id"]}},{"key":{"keys":["userId"]},"options":{"unique":true}}]' \ --throughput 400{ "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-cosmos-demo/providers/Microsoft.DocumentDB/databaseAccounts/mymongoaccount/mongodbDatabases/mymongodb/collections/mycollection", "name": "mycollection", "resource": { "id": "mycollection", "indexes": [ { "key": { "keys": [ "_id" ] }, "options": null }, { "key": { "keys": [ "userId" ] }, "options": { "expireAfterSeconds": null, "unique": true } } ], "shardKey": { "userId": "Hash" }, ... }, "resourceGroup": "rg-cosmos-demo", "type": "Microsoft.DocumentDB/databaseAccounts/mongodbDatabases/collections"}Collections that an application creates through the MongoDB driver are listed by az cosmosdb mongodb collection list as well.
Connect with the MongoDB client
Section titled “Connect with the MongoDB client”Extract the connection string and connect to the MongoDB database using mongosh:
CONN_STR=$(az cosmosdb keys list \ --name mymongoaccount \ --resource-group rg-cosmos-demo \ --type connection-strings \ --query "connectionStrings[0].connectionString" \ --output tsv)
mongosh "$CONN_STR"Delete and verify
Section titled “Delete and verify”Delete the Cosmos DB account and confirm it no longer appears in the list:
az cosmosdb delete \ --name mycosmosaccount \ --resource-group rg-cosmos-demo \ --yes
az cosmosdb list --resource-group rg-cosmos-demo[ { "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-cosmos-demo/providers/Microsoft.DocumentDB/databaseAccounts/mymongoaccount", "kind": "MongoDB", "name": "mymongoaccount", "provisioningState": "Succeeded", "resourceGroup": "rg-cosmos-demo", "type": "Microsoft.DocumentDB/databaseAccounts" }]Delete the second Cosmos DB account configured for the MongoDB API:
az cosmosdb delete \ --name mymongoaccount \ --resource-group rg-cosmos-demo \ --yesThen list all Cosmos DB accounts to confirm the resource group is now empty:
az cosmosdb list --resource-group rg-cosmos-demo[]Features
Section titled “Features”- Account lifecycle: Create, read, update (PUT and PATCH), list, and delete Cosmos DB accounts for both SQL and MongoDB API kinds. Re-deploying an existing account updates it in place and keeps its keys and data.
- Account properties: Tags, capabilities, the MongoDB server version, consistency policy, failover priorities and properties such as
enableFreeTier,publicNetworkAccessandminimalTlsVersionare stored and returned. - Account key management: Retrieve primary and secondary master keys and read-only keys.
- Connection strings: Retrieve connection strings for the API for NoSQL (SQL) and for MongoDB via
az cosmosdb keys list --type connection-strings. - Name availability check: Validate account name uniqueness; a taken name cannot be claimed from another resource group or subscription.
- SQL databases: Create, read, update, list, and delete SQL (NoSQL) databases within an account.
- SQL containers: Create, read, update, list, and delete SQL containers with partition key (including hierarchical keys), indexing policy, default TTL, unique key policy and conflict resolution policy.
- Throughput settings: Read and update manual or autoscale throughput of SQL databases and containers and of MongoDB databases and collections.
- MongoDB databases: Create, read, list, and delete MongoDB databases within an account; re-deploying an existing database keeps it and its collections.
- MongoDB collections: Create, read, update, list, and delete MongoDB collections with shard key, indexes (including
uniqueandexpireAfterSecondsoptions) and throughput settings. - Data plane integration: Databases, containers and collections created through the Cosmos DB SDKs or a MongoDB driver are visible to the management plane, and vice versa.
- Native MongoDB access: Connect directly to the local MongoDB backend using a standard MongoDB client.
- Cosmos DB for PostgreSQL: Create, start, stop, restart and delete clusters (
Microsoft.DBforPostgreSQL/serverGroupsv2) with firewall rules, backed by a local PostgreSQL server.
Limitations
Section titled “Limitations”- Table API not supported: The Cosmos DB Table API is not emulated.
- Cassandra API not supported: The Cosmos DB Cassandra API is not emulated.
- Gremlin API not supported: The Cosmos DB Gremlin (graph) API is not emulated.
- Cosmos DB for PostgreSQL: The backing server is a plain PostgreSQL instance without the Citus extension, so distributed tables are not available. Worker nodes exist as metadata only. Azure has retired this service for new clusters.
- Global distribution not emulated: Multi-region replication and conflict resolution are accepted at the model level but not executed.
- Change feed and triggers: Change feed processing and Cosmos DB triggers for Azure Functions are not emulated.
- Throughput and RU metering: Throughput settings are stored and returned, but request unit (RU) consumption is not tracked or enforced. Migrating between manual and autoscale throughput is not supported. A serverless account (
EnableServerless) accepts throughput settings, which Azure rejects. - RBAC for data plane: Cosmos DB SQL role definitions and role assignments are not implemented, and data plane requests are not authorized: any key or Microsoft Entra token is accepted, and
disableLocalAuthis not enforced. - Key regeneration and failover: Regenerating account keys and changing failover priorities of an existing account are not supported.
- Stored procedures, triggers and user-defined functions: Not supported through the management plane.
Samples
Section titled “Samples”The following samples demonstrate how to use Azure Cosmos DB with LocalStack for Azure. Each comes in a Python and a .NET version:
- Web App and Cosmos DB for NoSQL API (Python, .NET)
- Web App and Cosmos DB for MongoDB API (Python, .NET)
- AKS workload and Cosmos DB for NoSQL API (Python, .NET)
- AKS workload and Cosmos DB for MongoDB API (Python, .NET)
API Coverage
Section titled “API Coverage”50 of 310 operations implemented
| Operation ▲ | Implemented ▼ |
|---|