azure-resource-manager-cosmosdb-dotnet
Azure Resource Manager SDK for Cosmos DB in .NET. Use for MANAGEMENT PLANE operations: creating/managing Cosmos DB accounts, databases, containers, throughput settings, and RBAC via Azure Resource Manager. NOT for data plane operations (CRUD on documents) - use Microsoft.Azure.Co
Install
npx skills add https://github.com/microsoft/skills/tree/main/.github/plugins/azure-sdk-dotnet/skills/azure-resource-manager-cosmosdb-dotnet
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install microsoft-skills@llmmart
git clone https://github.com/microsoft/skills.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole microsoft/skills collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Azure.ResourceManager.CosmosDB (.NET)
Management plane SDK for provisioning and managing Azure Cosmos DB resources via Azure Resource Manager.
⚠️ Management vs Data Plane
- This SDK (Azure.ResourceManager.CosmosDB): Create accounts, databases, containers, configure throughput, manage RBAC
- Data Plane SDK (Microsoft.Azure.Cosmos): CRUD operations on documents, queries, stored procedures execution
Installation
dotnet add package Azure.ResourceManager.CosmosDB
dotnet add package Azure.Identity
Current Versions: Stable v1.4.0, Preview v1.4.0-beta.13
Environment Variables
AZURE_SUBSCRIPTION_ID=<your-subscription-id> # Required: Azure subscription ID
AZURE_TOKEN_CREDENTIALS=prod # Required only if DefaultAzureCredential is used in production
AZURE_TENANT_ID=<tenant-id> # For service principal auth (optional)
AZURE_CLIENT_ID=<client-id> # For service principal auth (optional)
AZURE_CLIENT_SECRET=<client-secret> # For service principal auth (optional)
Authentication
using Azure.Identity;
using Azure.ResourceManager;
using Azure.ResourceManager.CosmosDB;
// Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential>
var credential = new DefaultAzureCredential(
DefaultAzureCredential.DefaultEnvironmentVariableName
);
// Or use a specific credential directly in production:
// See https://learn.microsoft.com/dotnet/api/overview/azure/identity-readme?view=azure-dotnet#credential-classes
// var credential = new ManagedIdentityCredential();
var armClient = new ArmClient(credential);
// Get subscription
var subscriptionId = Environment.GetEnvironmentVariable("AZURE_SUBSCRIPTION_ID");
var subscription = armClient.GetSubscriptionResource(
new ResourceIdentifier($"/subscriptions/{subscriptionId}"));
Resource Hierarchy
ArmClient
└── SubscriptionResource
└── ResourceGroupResource
└── CosmosDBAccountResource
├── CosmosDBSqlDatabaseResource
│ └── CosmosDBSqlContainerResource
│ ├── CosmosDBSqlStoredProcedureResource
│ ├── CosmosDBSqlTriggerResource
│ └── CosmosDBSqlUserDefinedFunctionResource
├── CassandraKeyspaceResource
├── GremlinDatabaseResource
├── MongoDBDatabaseResource
└── CosmosDBTableResource
Core Workflow
1. Create Cosmos DB Account
using Azure.ResourceManager.CosmosDB;
using Azure.ResourceManager.CosmosDB.Models;
// Get resource group
var resourceGroup = await subscription
.GetResourceGroupAsync("my-resource-group");
// Define account
var accountData = new CosmosDBAccountCreateOrUpdateContent(
location: AzureLocation.EastUS,
locations: new[]
{
new CosmosDBAccountLocation
{
LocationName = AzureLocation.EastUS,
FailoverPriority = 0,
IsZoneRedundant = false
}
})
{
Kind = CosmosDBAccountKind.GlobalDocumentDB,
ConsistencyPolicy = new ConsistencyPolicy(DefaultConsistencyLevel.Session),
EnableAutomaticFailover = true
};
// Create account (long-running operation)
var accountCollection = resourceGroup.Value.GetCosmosDBAccounts();
var operation = await accountCollection.CreateOrUpdateAsync(
WaitUntil.Completed,
"my-cosmos-account",
accountData);
CosmosDBAccountResource account = operation.Value;
2. Create SQL Database
var databaseData = new CosmosDBSqlDatabaseCreateOrUpdateContent(
new CosmosDBSqlDatabaseResourceInfo("my-database"));
var databaseCollection = account.GetCosmosDBSqlDatabases();
var dbOperation = await databaseCollection.CreateOrUpdateAsync(
WaitUntil.Completed,
"my-database",
databaseData);
CosmosDBSqlDatabaseResource database = dbOperation.Value;
3. Create SQL Container
var containerData = new CosmosDBSqlContainerCreateOrUpdateContent(
new CosmosDBSqlContainerResourceInfo("my-container")
{
PartitionKey = new CosmosDBContainerPartitionKey
{
Paths = { "/partitionKey" },
Kind = CosmosDBPartitionKind.Hash
},
IndexingPolicy = new CosmosDBIndexingPolicy
{
Automatic = true,
IndexingMode = CosmosDBIndexingMode.Consistent
},
DefaultTtl = 86400 // 24 hours
});
var containerCollection = database.GetCosmosDBSqlContainers();
var containerOperation = await containerCollection.CreateOrUpdateAsync(
WaitUntil.Completed,
"my-container",
containerData);
CosmosDBSqlContainerResource container = containerOperation.Value;
4. Configure Throughput
// Manual throughput
var throughputData = new ThroughputSettingsUpdateData(
new ThroughputSettingsResourceInfo
{
Throughput = 400
});
// Autoscale throughput
var autoscaleData = new ThroughputSettingsUpdateData(
new ThroughputSettingsResourceInfo
{
AutoscaleSettings = new AutoscaleSettingsResourceInfo
{
MaxThroughput = 4000
}
});
// Apply to database
await database.CreateOrUpdateCosmosDBSqlDatabaseThroughputAsync(
WaitUntil.Completed,
throughputData);
5. Get Connection Information
// Get keys
var keys = await account.GetKeysAsync();
Console.WriteLine($"Primary Key: {keys.Value.PrimaryMasterKey}");
// Get connection strings
var connectionStrings = await account.GetConnectionStringsAsync();
foreach (var cs in connectionStrings.Value.ConnectionStrings)
{
Console.WriteLine($"{cs.Description}: {cs.ConnectionString}");
}
Key Types Reference
| Type | Purpose |
|---|---|
ArmClient |
Entry point for all ARM operations |
CosmosDBAccountResource |
Represents a Cosmos DB account |
CosmosDBAccountCollection |
Collection for account CRUD |
CosmosDBSqlDatabaseResource |
SQL API database |
CosmosDBSqlContainerResource |
SQL API container |
CosmosDBAccountCreateOrUpdateContent |
Account creation payload |
CosmosDBSqlDatabaseCreateOrUpdateContent |
Database creation payload |
CosmosDBSqlContainerCreateOrUpdateContent |
Container creation payload |
ThroughputSettingsUpdateData |
Throughput configuration |
Best Practices
- Use
WaitUntil.Completedfor operations that must finish before proceeding - Use
WaitUntil.Startedwhen you want to poll manually or run operations in parallel - Use
DefaultAzureCredential— never hardcode keys - Handle
RequestFailedExceptionfor ARM API errors - Use
CreateOrUpdateAsyncfor idempotent operations - Navigate hierarchy via
Get*methods (e.g.,account.GetCosmosDBSqlDatabases())
Error Handling
using Azure;
try
{
var operation = await accountCollection.CreateOrUpdateAsync(
WaitUntil.Completed, accountName, accountData);
}
catch (RequestFailedException ex) when (ex.Status == 409)
{
Console.WriteLine("Account already exists");
}
catch (RequestFailedException ex)
{
Console.WriteLine($"ARM Error: {ex.Status} - {ex.ErrorCode}: {ex.Message}");
}
Reference Files
| File | When to Read |
|---|---|
| references/account-management.md | Account CRUD, failover, keys, connection strings, networking |
| references/sql-resources.md | SQL databases, containers, stored procedures, triggers, UDFs |
| references/throughput.md | Manual/autoscale throughput, migration between modes |
Related SDKs
| SDK | Purpose | Install |
|---|---|---|
Microsoft.Azure.Cosmos |
Data plane (document CRUD, queries) | dotnet add package Microsoft.Azure.Cosmos |
Azure.ResourceManager.CosmosDB |
Management plane (this SDK) | dotnet add package Azure.ResourceManager.CosmosDB |
Files (skills)
-
references
-
account-management.md 7.3 KB
# Account Management Detailed patterns for managing Cosmos DB accounts via Azure Resource Manager. ## Create Account with Full Configuration ```csharp using Azure.ResourceManager.CosmosDB; using Azure.ResourceManager.CosmosDB.Models; using Azure.Core; var accountData = new CosmosDBAccountCreateOrUpdateContent( location: AzureLocation.EastUS, locations: new[] { new CosmosDBAccountLocation { LocationName = AzureLocation.EastUS, FailoverPriority = 0, IsZoneRedundant = true }, new CosmosDBAccountLocation { LocationName = AzureLocation.WestUS, FailoverPriority = 1, IsZoneRedundant = false } }) { Kind = CosmosDBAccountKind.GlobalDocumentDB, // Consistency ConsistencyPolicy = new ConsistencyPolicy(DefaultConsistencyLevel.BoundedStaleness) { MaxStalenessPrefix = 100000, MaxIntervalInSeconds = 300 }, // High availability EnableAutomaticFailover = true, EnableMultipleWriteLocations = false, // Backup BackupPolicy = new ContinuousModeBackupPolicy { ContinuousModeTier = ContinuousModeTier.Continuous7Days }, // Networking PublicNetworkAccess = CosmosDBPublicNetworkAccess.Enabled, IsVirtualNetworkFilterEnabled = false, // Features EnableFreeTier = false, EnableAnalyticalStorage = true, AnalyticalStorageSchemaType = AnalyticalStorageSchemaType.WellDefined, // Tags Tags = { ["Environment"] = "Production", ["CostCenter"] = "Engineering" } }; var operation = await accountCollection.CreateOrUpdateAsync( WaitUntil.Completed, "my-cosmos-account", accountData); ``` ## Get Existing Account ```csharp // By name from resource group var account = await resourceGroup.GetCosmosDBAccountAsync("my-cosmos-account"); // By resource ID var accountId = CosmosDBAccountResource.CreateResourceIdentifier( subscriptionId, resourceGroupName, accountName); var account = armClient.GetCosmosDBAccountResource(accountId); await account.GetAsync(); // Fetch latest data ``` ## Update Account ```csharp // Get current account var account = await resourceGroup.GetCosmosDBAccountAsync("my-cosmos-account"); // Create patch data var patchData = new CosmosDBAccountPatch { EnableAutomaticFailover = true, ConsistencyPolicy = new ConsistencyPolicy(DefaultConsistencyLevel.Session) }; patchData.Tags.Add("UpdatedBy", "Automation"); // Apply update var operation = await account.Value.UpdateAsync(WaitUntil.Completed, patchData); ``` ## Delete Account ```csharp var account = await resourceGroup.GetCosmosDBAccountAsync("my-cosmos-account"); await account.Value.DeleteAsync(WaitUntil.Completed); ``` ## List Accounts ```csharp // In resource group await foreach (var account in resourceGroup.GetCosmosDBAccounts()) { Console.WriteLine($"Account: {account.Data.Name}"); Console.WriteLine($" Location: {account.Data.Location}"); Console.WriteLine($" Kind: {account.Data.Kind}"); } // In subscription await foreach (var account in subscription.GetCosmosDBAccountsAsync()) { Console.WriteLine($"{account.Data.Name} in {account.Data.ResourceGroupName}"); } ``` ## Get Keys and Connection Strings ```csharp // Get keys var keys = await account.GetKeysAsync(); Console.WriteLine($"Primary Key: {keys.Value.PrimaryMasterKey}"); Console.WriteLine($"Secondary Key: {keys.Value.SecondaryMasterKey}"); Console.WriteLine($"Primary Read-Only: {keys.Value.PrimaryReadonlyMasterKey}"); Console.WriteLine($"Secondary Read-Only: {keys.Value.SecondaryReadonlyMasterKey}"); // Get connection strings var connectionStrings = await account.GetConnectionStringsAsync(); foreach (var cs in connectionStrings.Value.ConnectionStrings) { Console.WriteLine($"{cs.Description}:"); Console.WriteLine($" {cs.ConnectionString}"); } // Regenerate key await account.RegenerateKeyAsync( WaitUntil.Completed, new CosmosDBAccountRegenerateKeyContent(CosmosDBAccountKeyKind.Primary)); ``` ## Failover Operations ```csharp // Manual failover (for testing) var failoverContent = new CosmosDBFailoverPolicies(new[] { new CosmosDBFailoverPolicy { LocationName = AzureLocation.WestUS, FailoverPriority = 0 }, new CosmosDBFailoverPolicy { LocationName = AzureLocation.EastUS, FailoverPriority = 1 } }); await account.FailoverPriorityChangeAsync(WaitUntil.Completed, failoverContent); ``` ## Network Configuration ### Private Endpoint ```csharp // Note: Private endpoints are typically created via Azure.ResourceManager.Network // The Cosmos account needs to be configured to accept private endpoint connections var accountData = new CosmosDBAccountCreateOrUpdateContent(location, locations) { PublicNetworkAccess = CosmosDBPublicNetworkAccess.Disabled, IsVirtualNetworkFilterEnabled = true }; ``` ### IP Firewall Rules ```csharp var accountData = new CosmosDBAccountCreateOrUpdateContent(location, locations) { IPRules = { new CosmosDBIPAddressOrRange { IPAddressOrRange = "104.42.195.92" }, new CosmosDBIPAddressOrRange { IPAddressOrRange = "40.76.54.131" }, new CosmosDBIPAddressOrRange { IPAddressOrRange = "52.176.6.30/32" } } }; ``` ### Virtual Network Rules ```csharp var accountData = new CosmosDBAccountCreateOrUpdateContent(location, locations) { IsVirtualNetworkFilterEnabled = true, VirtualNetworkRules = { new CosmosDBVirtualNetworkRule { Id = new ResourceIdentifier( "/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet}"), IgnoreMissingVnetServiceEndpoint = false } } }; ``` ## Consistency Levels | Level | Description | Use Case | |-------|-------------|----------| | `Strong` | Linearizable reads | Financial transactions | | `BoundedStaleness` | Reads lag by K versions or T time | Gaming leaderboards | | `Session` | Read your own writes | User sessions (default) | | `ConsistentPrefix` | Reads never see out-of-order writes | Social feeds | | `Eventual` | No ordering guarantee | Analytics, non-critical reads | ```csharp // Bounded Staleness example ConsistencyPolicy = new ConsistencyPolicy(DefaultConsistencyLevel.BoundedStaleness) { MaxStalenessPrefix = 100000, // Max versions behind MaxIntervalInSeconds = 300 // Max time behind (5 min) } ``` ## Backup Policies ### Periodic Backup ```csharp BackupPolicy = new PeriodicModeBackupPolicy { PeriodicModeProperties = new PeriodicModeProperties { BackupIntervalInMinutes = 240, // 4 hours BackupRetentionIntervalInHours = 720, // 30 days BackupStorageRedundancy = BackupStorageRedundancy.Geo } } ``` ### Continuous Backup ```csharp BackupPolicy = new ContinuousModeBackupPolicy { ContinuousModeTier = ContinuousModeTier.Continuous30Days } ``` ## Account Kinds | Kind | API | Description | |------|-----|-------------| | `GlobalDocumentDB` | SQL (Core) | Default, most common | | `MongoDB` | MongoDB | MongoDB wire protocol | | `Parse` | SQL | Parse Server compatibility | ```csharp // MongoDB account var accountData = new CosmosDBAccountCreateOrUpdateContent(location, locations) { Kind = CosmosDBAccountKind.MongoDB, ApiServerVersion = CosmosDBServerVersion.V4_2 }; ``` -
sql-resources.md 9.7 KB
# SQL API Resources Patterns for managing SQL (Core) API databases, containers, and programmability objects. ## SQL Database Operations ### Create Database ```csharp using Azure.ResourceManager.CosmosDB; using Azure.ResourceManager.CosmosDB.Models; var databaseData = new CosmosDBSqlDatabaseCreateOrUpdateContent( new CosmosDBSqlDatabaseResourceInfo("my-database")); var databaseCollection = account.GetCosmosDBSqlDatabases(); var operation = await databaseCollection.CreateOrUpdateAsync( WaitUntil.Completed, "my-database", databaseData); CosmosDBSqlDatabaseResource database = operation.Value; ``` ### Create Database with Shared Throughput ```csharp var databaseData = new CosmosDBSqlDatabaseCreateOrUpdateContent( new CosmosDBSqlDatabaseResourceInfo("my-database")) { Options = new CosmosDBCreateUpdateConfig { Throughput = 400 // Shared across containers } }; // Or with autoscale var databaseData = new CosmosDBSqlDatabaseCreateOrUpdateContent( new CosmosDBSqlDatabaseResourceInfo("my-database")) { Options = new CosmosDBCreateUpdateConfig { AutoscaleSettings = new AutoscaleSettings { MaxThroughput = 4000 } } }; ``` ### List Databases ```csharp await foreach (var db in account.GetCosmosDBSqlDatabases()) { Console.WriteLine($"Database: {db.Data.Name}"); Console.WriteLine($" Resource ID: {db.Data.Resource.DatabaseName}"); } ``` ### Delete Database ```csharp var database = await account.GetCosmosDBSqlDatabaseAsync("my-database"); await database.Value.DeleteAsync(WaitUntil.Completed); ``` ## SQL Container Operations ### Create Container with Partition Key ```csharp var containerData = new CosmosDBSqlContainerCreateOrUpdateContent( new CosmosDBSqlContainerResourceInfo("my-container") { PartitionKey = new CosmosDBContainerPartitionKey { Paths = { "/tenantId" }, Kind = CosmosDBPartitionKind.Hash, Version = 2 // Use V2 for hierarchical partition keys } }); var containerCollection = database.GetCosmosDBSqlContainers(); var operation = await containerCollection.CreateOrUpdateAsync( WaitUntil.Completed, "my-container", containerData); ``` ### Hierarchical Partition Key (V2) ```csharp var containerData = new CosmosDBSqlContainerCreateOrUpdateContent( new CosmosDBSqlContainerResourceInfo("my-container") { PartitionKey = new CosmosDBContainerPartitionKey { Paths = { "/tenantId", "/userId", "/sessionId" }, Kind = CosmosDBPartitionKind.MultiHash, Version = 2 } }); ``` ### Create Container with Indexing Policy ```csharp var containerData = new CosmosDBSqlContainerCreateOrUpdateContent( new CosmosDBSqlContainerResourceInfo("my-container") { PartitionKey = new CosmosDBContainerPartitionKey { Paths = { "/partitionKey" }, Kind = CosmosDBPartitionKind.Hash }, IndexingPolicy = new CosmosDBIndexingPolicy { Automatic = true, IndexingMode = CosmosDBIndexingMode.Consistent, // Include paths IncludedPaths = { new CosmosDBIncludedPath { Path = "/*" } }, // Exclude paths ExcludedPaths = { new CosmosDBExcludedPath { Path = "/largeTextField/*" }, new CosmosDBExcludedPath { Path = "/_etag/?" } }, // Composite indexes for ORDER BY on multiple fields CompositeIndexes = { new CosmosDBCompositePath[] { new() { Path = "/name", Order = CompositePathSortOrder.Ascending }, new() { Path = "/timestamp", Order = CompositePathSortOrder.Descending } } }, // Spatial indexes SpatialIndexes = { new SpatialSpec { Path = "/location/*", Types = { SpatialType.Point, SpatialType.Polygon } } } } }); ``` ### Create Container with TTL ```csharp var containerData = new CosmosDBSqlContainerCreateOrUpdateContent( new CosmosDBSqlContainerResourceInfo("my-container") { PartitionKey = new CosmosDBContainerPartitionKey { Paths = { "/partitionKey" }, Kind = CosmosDBPartitionKind.Hash }, // Default TTL in seconds (-1 = off, 0 = on but no default, >0 = default seconds) DefaultTtl = 86400 // 24 hours }); ``` ### Create Container with Unique Keys ```csharp var containerData = new CosmosDBSqlContainerCreateOrUpdateContent( new CosmosDBSqlContainerResourceInfo("my-container") { PartitionKey = new CosmosDBContainerPartitionKey { Paths = { "/tenantId" }, Kind = CosmosDBPartitionKind.Hash }, UniqueKeys = new CosmosDBUniqueKeyPolicy { UniqueKeys = { new CosmosDBUniqueKey { Paths = { "/email" } }, new CosmosDBUniqueKey { Paths = { "/department", "/employeeId" } } } } }); ``` ### Create Container with Dedicated Throughput ```csharp var containerData = new CosmosDBSqlContainerCreateOrUpdateContent( new CosmosDBSqlContainerResourceInfo("my-container") { PartitionKey = new CosmosDBContainerPartitionKey { Paths = { "/partitionKey" }, Kind = CosmosDBPartitionKind.Hash } }) { Options = new CosmosDBCreateUpdateConfig { Throughput = 1000 // Dedicated to this container } }; ``` ### List Containers ```csharp await foreach (var container in database.GetCosmosDBSqlContainers()) { Console.WriteLine($"Container: {container.Data.Name}"); Console.WriteLine($" Partition Key: {string.Join(", ", container.Data.Resource.PartitionKey.Paths)}"); Console.WriteLine($" Default TTL: {container.Data.Resource.DefaultTtl}"); } ``` ### Delete Container ```csharp var container = await database.GetCosmosDBSqlContainerAsync("my-container"); await container.Value.DeleteAsync(WaitUntil.Completed); ``` ## Stored Procedures ### Create Stored Procedure ```csharp var sprocData = new CosmosDBSqlStoredProcedureCreateOrUpdateContent( new CosmosDBSqlStoredProcedureResourceInfo("bulkDelete") { Body = @" function bulkDelete(query) { var context = getContext(); var container = context.getCollection(); var response = context.getResponse(); var deleted = 0; var accepted = container.queryDocuments( container.getSelfLink(), query, function(err, docs) { if (err) throw err; docs.forEach(function(doc) { container.deleteDocument(doc._self); deleted++; }); response.setBody({ deleted: deleted }); } ); if (!accepted) { response.setBody({ deleted: deleted, continuation: true }); } }" }); var sprocCollection = container.GetCosmosDBSqlStoredProcedures(); await sprocCollection.CreateOrUpdateAsync( WaitUntil.Completed, "bulkDelete", sprocData); ``` ### List Stored Procedures ```csharp await foreach (var sproc in container.GetCosmosDBSqlStoredProcedures()) { Console.WriteLine($"Stored Procedure: {sproc.Data.Name}"); } ``` ## Triggers ### Create Trigger ```csharp var triggerData = new CosmosDBSqlTriggerCreateOrUpdateContent( new CosmosDBSqlTriggerResourceInfo("validateDocument") { Body = @" function validateDocument() { var context = getContext(); var request = context.getRequest(); var doc = request.getBody(); if (!doc.createdAt) { doc.createdAt = new Date().toISOString(); } request.setBody(doc); }", TriggerType = CosmosDBSqlTriggerType.Pre, TriggerOperation = CosmosDBSqlTriggerOperation.Create }); var triggerCollection = container.GetCosmosDBSqlTriggers(); await triggerCollection.CreateOrUpdateAsync( WaitUntil.Completed, "validateDocument", triggerData); ``` ### Trigger Types | Type | When | |------|------| | `Pre` | Before the operation | | `Post` | After the operation | ### Trigger Operations | Operation | Applies To | |-----------|------------| | `All` | All operations | | `Create` | Document creation | | `Update` | Document updates | | `Delete` | Document deletion | | `Replace` | Document replacement | ## User Defined Functions (UDFs) ### Create UDF ```csharp var udfData = new CosmosDBSqlUserDefinedFunctionCreateOrUpdateContent( new CosmosDBSqlUserDefinedFunctionResourceInfo("formatCurrency") { Body = @" function formatCurrency(amount, currency) { return currency + ' ' + amount.toFixed(2); }" }); var udfCollection = container.GetCosmosDBSqlUserDefinedFunctions(); await udfCollection.CreateOrUpdateAsync( WaitUntil.Completed, "formatCurrency", udfData); ``` ## Partition Key Strategies | Strategy | Path Example | Use Case | |----------|--------------|----------| | Single property | `/tenantId` | Multi-tenant apps | | Synthetic key | `/partitionKey` | Computed from multiple fields | | Hierarchical | `/tenantId`, `/userId` | Large tenants with sub-partitioning | | ID-based | `/id` | Even distribution, no cross-partition queries | ### Choosing Partition Key 1. **High cardinality** — Many distinct values 2. **Even distribution** — No hot partitions 3. **Query alignment** — Most queries include partition key 4. **Immutable** — Cannot change after document creation -
throughput.md 7.7 KB
# Throughput Configuration Patterns for configuring and managing throughput (RU/s) for Cosmos DB resources. ## Throughput Concepts | Type | Description | Min RU/s | Use Case | |------|-------------|----------|----------| | **Manual** | Fixed provisioned throughput | 400 | Predictable workloads | | **Autoscale** | Scales between 10% and max | 1000 (max) | Variable workloads | | **Serverless** | Pay per request | N/A | Dev/test, sporadic traffic | ## Database-Level Throughput (Shared) Throughput shared across all containers in the database. ### Set Manual Throughput ```csharp using Azure.ResourceManager.CosmosDB; using Azure.ResourceManager.CosmosDB.Models; // Create database with shared throughput var databaseData = new CosmosDBSqlDatabaseCreateOrUpdateContent( new CosmosDBSqlDatabaseResourceInfo("my-database")) { Options = new CosmosDBCreateUpdateConfig { Throughput = 400 } }; await databaseCollection.CreateOrUpdateAsync( WaitUntil.Completed, "my-database", databaseData); ``` ### Set Autoscale Throughput ```csharp var databaseData = new CosmosDBSqlDatabaseCreateOrUpdateContent( new CosmosDBSqlDatabaseResourceInfo("my-database")) { Options = new CosmosDBCreateUpdateConfig { AutoscaleSettings = new AutoscaleSettings { MaxThroughput = 4000 // Scales between 400-4000 RU/s } } }; ``` ### Update Database Throughput ```csharp var database = await account.GetCosmosDBSqlDatabaseAsync("my-database"); // Update to manual throughput var throughputData = new ThroughputSettingsUpdateData( new ThroughputSettingsResourceInfo { Throughput = 800 }); await database.Value.CreateOrUpdateCosmosDBSqlDatabaseThroughputAsync( WaitUntil.Completed, throughputData); ``` ### Get Database Throughput ```csharp var database = await account.GetCosmosDBSqlDatabaseAsync("my-database"); var throughput = await database.Value.GetCosmosDBSqlDatabaseThroughputAsync(); Console.WriteLine($"Throughput: {throughput.Value.Data.Resource.Throughput}"); Console.WriteLine($"Min Throughput: {throughput.Value.Data.Resource.MinimumThroughput}"); if (throughput.Value.Data.Resource.AutoscaleSettings != null) { Console.WriteLine($"Autoscale Max: {throughput.Value.Data.Resource.AutoscaleSettings.MaxThroughput}"); } ``` ## Container-Level Throughput (Dedicated) Throughput dedicated to a single container. ### Set Manual Throughput ```csharp var containerData = new CosmosDBSqlContainerCreateOrUpdateContent( new CosmosDBSqlContainerResourceInfo("my-container") { PartitionKey = new CosmosDBContainerPartitionKey { Paths = { "/partitionKey" }, Kind = CosmosDBPartitionKind.Hash } }) { Options = new CosmosDBCreateUpdateConfig { Throughput = 1000 } }; await containerCollection.CreateOrUpdateAsync( WaitUntil.Completed, "my-container", containerData); ``` ### Set Autoscale Throughput ```csharp var containerData = new CosmosDBSqlContainerCreateOrUpdateContent( new CosmosDBSqlContainerResourceInfo("my-container") { PartitionKey = new CosmosDBContainerPartitionKey { Paths = { "/partitionKey" }, Kind = CosmosDBPartitionKind.Hash } }) { Options = new CosmosDBCreateUpdateConfig { AutoscaleSettings = new AutoscaleSettings { MaxThroughput = 10000 // Scales between 1000-10000 RU/s } } }; ``` ### Update Container Throughput ```csharp var container = await database.GetCosmosDBSqlContainerAsync("my-container"); // Update to new throughput var throughputData = new ThroughputSettingsUpdateData( new ThroughputSettingsResourceInfo { Throughput = 2000 }); await container.Value.CreateOrUpdateCosmosDBSqlContainerThroughputAsync( WaitUntil.Completed, throughputData); ``` ### Get Container Throughput ```csharp var container = await database.GetCosmosDBSqlContainerAsync("my-container"); var throughput = await container.Value.GetCosmosDBSqlContainerThroughputAsync(); Console.WriteLine($"Throughput: {throughput.Value.Data.Resource.Throughput}"); ``` ## Migrate Between Throughput Modes ### Manual to Autoscale ```csharp var container = await database.GetCosmosDBSqlContainerAsync("my-container"); // Migrate to autoscale await container.Value.MigrateCosmosDBSqlContainerToAutoscaleAsync(WaitUntil.Completed); ``` ### Autoscale to Manual ```csharp var container = await database.GetCosmosDBSqlContainerAsync("my-container"); // Migrate to manual (uses current autoscale throughput as manual value) await container.Value.MigrateCosmosDBSqlContainerToManualThroughputAsync(WaitUntil.Completed); ``` ### Database-Level Migration ```csharp var database = await account.GetCosmosDBSqlDatabaseAsync("my-database"); // To autoscale await database.Value.MigrateCosmosDBSqlDatabaseToAutoscaleAsync(WaitUntil.Completed); // To manual await database.Value.MigrateCosmosDBSqlDatabaseToManualThroughputAsync(WaitUntil.Completed); ``` ## Throughput Calculation Guidelines ### Estimating RU/s | Operation | Approximate RU Cost | |-----------|---------------------| | Point read (1KB doc by ID + partition key) | 1 RU | | Write (1KB doc) | 5-10 RU | | Query (simple, single partition) | 2-5 RU | | Query (complex, cross-partition) | 10-100+ RU | ### Sizing Formula ``` Required RU/s = (Reads/sec × RU per read) + (Writes/sec × RU per write) + (Queries/sec × RU per query) ``` ### Autoscale Tiers | Max Throughput | Min Throughput (10%) | Monthly Cost Estimate | |----------------|----------------------|----------------------| | 1,000 RU/s | 100 RU/s | ~$58 | | 4,000 RU/s | 400 RU/s | ~$233 | | 10,000 RU/s | 1,000 RU/s | ~$584 | | 100,000 RU/s | 10,000 RU/s | ~$5,840 | ## Best Practices 1. **Start with autoscale** for new workloads until you understand traffic patterns 2. **Use database-level throughput** when containers have similar access patterns 3. **Use container-level throughput** for containers with distinct performance needs 4. **Monitor RU consumption** via Azure Monitor to right-size throughput 5. **Set alerts** for 429 (rate limiting) errors 6. **Consider serverless** for dev/test or sporadic workloads ## Error Handling ```csharp try { await container.Value.CreateOrUpdateCosmosDBSqlContainerThroughputAsync( WaitUntil.Completed, throughputData); } catch (RequestFailedException ex) when (ex.Status == 400) { // Common: throughput below minimum or invalid autoscale settings Console.WriteLine($"Invalid throughput configuration: {ex.Message}"); } catch (RequestFailedException ex) when (ex.Status == 409) { // Conflict: migration already in progress Console.WriteLine($"Throughput migration in progress: {ex.Message}"); } ``` ## Throughput for Other APIs ### Cassandra Keyspace ```csharp var keyspaceData = new CassandraKeyspaceCreateOrUpdateContent( new CassandraKeyspaceResourceInfo("my-keyspace")) { Options = new CosmosDBCreateUpdateConfig { Throughput = 400 } }; ``` ### MongoDB Database ```csharp var mongoDbData = new MongoDBDatabaseCreateOrUpdateContent( new MongoDBDatabaseResourceInfo("my-mongodb")) { Options = new CosmosDBCreateUpdateConfig { AutoscaleSettings = new AutoscaleSettings { MaxThroughput = 4000 } } }; ``` ### Gremlin Database ```csharp var gremlinData = new GremlinDatabaseCreateOrUpdateContent( new GremlinDatabaseResourceInfo("my-gremlin")) { Options = new CosmosDBCreateUpdateConfig { Throughput = 400 } }; ``` ### Table API ```csharp var tableData = new CosmosDBTableCreateOrUpdateContent( new CosmosDBTableResourceInfo("my-table")) { Options = new CosmosDBCreateUpdateConfig { Throughput = 400 } }; ```
-
-
SKILL.md 8.4 KB
--- name: azure-resource-manager-cosmosdb-dotnet description: | Azure Resource Manager SDK for Cosmos DB in .NET. Use for MANAGEMENT PLANE operations: creating/managing Cosmos DB accounts, databases, containers, throughput settings, and RBAC via Azure Resource Manager. NOT for data plane operations (CRUD on documents) - use Microsoft.Azure.Cosmos for that. Triggers: "Cosmos DB account", "create Cosmos account", "manage Cosmos resources", "ARM Cosmos", "CosmosDBAccountResource", "provision Cosmos DB". license: MIT metadata: author: Microsoft version: "1.0.0" package: Azure.ResourceManager.CosmosDB --- # Azure.ResourceManager.CosmosDB (.NET) Management plane SDK for provisioning and managing Azure Cosmos DB resources via Azure Resource Manager. > **⚠️ Management vs Data Plane** > - **This SDK (Azure.ResourceManager.CosmosDB)**: Create accounts, databases, containers, configure throughput, manage RBAC > - **Data Plane SDK (Microsoft.Azure.Cosmos)**: CRUD operations on documents, queries, stored procedures execution ## Installation ```bash dotnet add package Azure.ResourceManager.CosmosDB dotnet add package Azure.Identity ``` **Current Versions**: Stable v1.4.0, Preview v1.4.0-beta.13 ## Environment Variables ```bash AZURE_SUBSCRIPTION_ID=<your-subscription-id> # Required: Azure subscription ID AZURE_TOKEN_CREDENTIALS=prod # Required only if DefaultAzureCredential is used in production AZURE_TENANT_ID=<tenant-id> # For service principal auth (optional) AZURE_CLIENT_ID=<client-id> # For service principal auth (optional) AZURE_CLIENT_SECRET=<client-secret> # For service principal auth (optional) ``` ## Authentication ```csharp using Azure.Identity; using Azure.ResourceManager; using Azure.ResourceManager.CosmosDB; // Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential> var credential = new DefaultAzureCredential( DefaultAzureCredential.DefaultEnvironmentVariableName ); // Or use a specific credential directly in production: // See https://learn.microsoft.com/dotnet/api/overview/azure/identity-readme?view=azure-dotnet#credential-classes // var credential = new ManagedIdentityCredential(); var armClient = new ArmClient(credential); // Get subscription var subscriptionId = Environment.GetEnvironmentVariable("AZURE_SUBSCRIPTION_ID"); var subscription = armClient.GetSubscriptionResource( new ResourceIdentifier($"/subscriptions/{subscriptionId}")); ``` ## Resource Hierarchy ``` ArmClient └── SubscriptionResource └── ResourceGroupResource └── CosmosDBAccountResource ├── CosmosDBSqlDatabaseResource │ └── CosmosDBSqlContainerResource │ ├── CosmosDBSqlStoredProcedureResource │ ├── CosmosDBSqlTriggerResource │ └── CosmosDBSqlUserDefinedFunctionResource ├── CassandraKeyspaceResource ├── GremlinDatabaseResource ├── MongoDBDatabaseResource └── CosmosDBTableResource ``` ## Core Workflow ### 1. Create Cosmos DB Account ```csharp using Azure.ResourceManager.CosmosDB; using Azure.ResourceManager.CosmosDB.Models; // Get resource group var resourceGroup = await subscription .GetResourceGroupAsync("my-resource-group"); // Define account var accountData = new CosmosDBAccountCreateOrUpdateContent( location: AzureLocation.EastUS, locations: new[] { new CosmosDBAccountLocation { LocationName = AzureLocation.EastUS, FailoverPriority = 0, IsZoneRedundant = false } }) { Kind = CosmosDBAccountKind.GlobalDocumentDB, ConsistencyPolicy = new ConsistencyPolicy(DefaultConsistencyLevel.Session), EnableAutomaticFailover = true }; // Create account (long-running operation) var accountCollection = resourceGroup.Value.GetCosmosDBAccounts(); var operation = await accountCollection.CreateOrUpdateAsync( WaitUntil.Completed, "my-cosmos-account", accountData); CosmosDBAccountResource account = operation.Value; ``` ### 2. Create SQL Database ```csharp var databaseData = new CosmosDBSqlDatabaseCreateOrUpdateContent( new CosmosDBSqlDatabaseResourceInfo("my-database")); var databaseCollection = account.GetCosmosDBSqlDatabases(); var dbOperation = await databaseCollection.CreateOrUpdateAsync( WaitUntil.Completed, "my-database", databaseData); CosmosDBSqlDatabaseResource database = dbOperation.Value; ``` ### 3. Create SQL Container ```csharp var containerData = new CosmosDBSqlContainerCreateOrUpdateContent( new CosmosDBSqlContainerResourceInfo("my-container") { PartitionKey = new CosmosDBContainerPartitionKey { Paths = { "/partitionKey" }, Kind = CosmosDBPartitionKind.Hash }, IndexingPolicy = new CosmosDBIndexingPolicy { Automatic = true, IndexingMode = CosmosDBIndexingMode.Consistent }, DefaultTtl = 86400 // 24 hours }); var containerCollection = database.GetCosmosDBSqlContainers(); var containerOperation = await containerCollection.CreateOrUpdateAsync( WaitUntil.Completed, "my-container", containerData); CosmosDBSqlContainerResource container = containerOperation.Value; ``` ### 4. Configure Throughput ```csharp // Manual throughput var throughputData = new ThroughputSettingsUpdateData( new ThroughputSettingsResourceInfo { Throughput = 400 }); // Autoscale throughput var autoscaleData = new ThroughputSettingsUpdateData( new ThroughputSettingsResourceInfo { AutoscaleSettings = new AutoscaleSettingsResourceInfo { MaxThroughput = 4000 } }); // Apply to database await database.CreateOrUpdateCosmosDBSqlDatabaseThroughputAsync( WaitUntil.Completed, throughputData); ``` ### 5. Get Connection Information ```csharp // Get keys var keys = await account.GetKeysAsync(); Console.WriteLine($"Primary Key: {keys.Value.PrimaryMasterKey}"); // Get connection strings var connectionStrings = await account.GetConnectionStringsAsync(); foreach (var cs in connectionStrings.Value.ConnectionStrings) { Console.WriteLine($"{cs.Description}: {cs.ConnectionString}"); } ``` ## Key Types Reference | Type | Purpose | |------|---------| | `ArmClient` | Entry point for all ARM operations | | `CosmosDBAccountResource` | Represents a Cosmos DB account | | `CosmosDBAccountCollection` | Collection for account CRUD | | `CosmosDBSqlDatabaseResource` | SQL API database | | `CosmosDBSqlContainerResource` | SQL API container | | `CosmosDBAccountCreateOrUpdateContent` | Account creation payload | | `CosmosDBSqlDatabaseCreateOrUpdateContent` | Database creation payload | | `CosmosDBSqlContainerCreateOrUpdateContent` | Container creation payload | | `ThroughputSettingsUpdateData` | Throughput configuration | ## Best Practices 1. **Use `WaitUntil.Completed`** for operations that must finish before proceeding 2. **Use `WaitUntil.Started`** when you want to poll manually or run operations in parallel 3. **Use `DefaultAzureCredential`** — never hardcode keys 4. **Handle `RequestFailedException`** for ARM API errors 5. **Use `CreateOrUpdateAsync`** for idempotent operations 6. **Navigate hierarchy** via `Get*` methods (e.g., `account.GetCosmosDBSqlDatabases()`) ## Error Handling ```csharp using Azure; try { var operation = await accountCollection.CreateOrUpdateAsync( WaitUntil.Completed, accountName, accountData); } catch (RequestFailedException ex) when (ex.Status == 409) { Console.WriteLine("Account already exists"); } catch (RequestFailedException ex) { Console.WriteLine($"ARM Error: {ex.Status} - {ex.ErrorCode}: {ex.Message}"); } ``` ## Reference Files | File | When to Read | |------|--------------| | [references/account-management.md](references/account-management.md) | Account CRUD, failover, keys, connection strings, networking | | [references/sql-resources.md](references/sql-resources.md) | SQL databases, containers, stored procedures, triggers, UDFs | | [references/throughput.md](references/throughput.md) | Manual/autoscale throughput, migration between modes | ## Related SDKs | SDK | Purpose | Install | |-----|---------|---------| | `Microsoft.Azure.Cosmos` | Data plane (document CRUD, queries) | `dotnet add package Microsoft.Azure.Cosmos` | | `Azure.ResourceManager.CosmosDB` | Management plane (this SDK) | `dotnet add package Azure.ResourceManager.CosmosDB` |
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.