- Use Azure Bastion as a jump host for RDP and SSH - Tue, Apr 18 2023
- Azure Virtual Desktop: Getting started - Fri, Apr 14 2023
- Understanding Azure service accounts - Fri, Mar 31 2023
Whereas Azure SQL Database is Microsoft Azure's primary relational database management system, Cosmos DB is Azure's main nonrelational database offering. Cosmos DB offers cloud development teams several significant advantages, including:
- Fully managed Platform as a Service architecture
- Five APIs/data models to support migration from various NoSQL databases
- Five transaction consistency levels
- Turnkey global replication
- Multi-region read/write access
Cosmos DB is a very cool product, for sure. But what does this opinion have to do with the life of the busy Windows systems administrator? Well, potentially a lot, especially for businesses adopting a "cloud-first" application development/deployment model in Azure.
Let's start this lesson by deploying a Cosmos DB account using Azure PowerShell. Next, I'll show you a couple of administrative actions we can automate. Access key regeneration is by far the most important, especially given recent tech news. Onward!
Sorting our prerequisites
To perform the steps I'll demonstrate, you'll need some tools. Here's the short list:
- PowerShell 7
- Azure PowerShell modules
- Azure Bicep CLI
- (Optional) Visual Studio Code, with the PowerShell, ARM Tools, and Bicep extensions
Open an elevated PowerShell console, and run the following statements to install Azure PowerShell:
Install-Module -Name Az -Force -Verbose Invoke-WebRequest -Uri https://aka.ms/installazurecliwindows -OutFile .\AzureCLI.msi; Start-Process msiexec.exe -Wait -ArgumentList '/I AzureCLI.msi /quiet'; rm .\AzureCLI.msi
Installing Bicep CLI on Windows is a bit of a pain to do with PowerShell at this time. Thus, I suggest that you simply run the .MSI installer and be done with it.
Next, sign into Azure, and set your subscription context if necessary:
Connect-AzAccount Set-AzContext -SubscriptionName "My Azure Subscription"
Deploying a Cosmos DB account
Start your Cosmos DB journey by creating a Cosmos account. The account is associated with one and only one of the supported APIs:
- Core: This is the preferred API because it's where Microsoft does all its innovation and new feature development. Data is stored as JSON documents, and the API uses a SQL-like query language.
- MongoDB: Supports migration from MongoDB JSON databases.
- Cassandra: Supports migration from Apache Cassandra wide column store databases.
- Table: Supports migration from the Azure Table Storage service (part of the general purpose storage account).
- Gremlin: Supports migration from Apache Gremlin graph databases.
We'll use Bicep to deploy the account. Note that your Cosmos DB account name needs to be globally unique. Here's the .bicep template:
param appName string = uniqueString(resourceGroup().id) param accountName string = toLower('cosmos-${appName}') param location string = resourceGroup().location param databaseName string = toLower('db-${appName}') resource cosmos 'Microsoft.DocumentDB/databaseAccounts@2020-04-01' = { name: accountName location: location properties: { enableFreeTier: true databaseAccountOfferType: 'Standard' consistencyPolicy: { defaultConsistencyLevel: 'Session' } locations: [ { locationName: location } ] } } resource cosmosdb 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases@2020-04-01' = { name: '${cosmos.name}/${databaseName}' properties: { resource: { id: databaseName } options: { throughput: 400 } } }
To perform the deployment using Azure PowerShell, run the command below. Note that the resource group you specify must already exist:
New-AzResourceGroupDeployment -Name cosmos-db -ResourceGroupName "your-rg" -TemplateFile "./cosmos-account.bicep" -Verbose
At the end of this process, you'll have a new Cosmos DB account that uses the Core (SQL) API. You'll also have a new, empty database.
In the Core Cosmos DB resource model, the database comprises one or more containers, which in turn contain your JSON documents. We'll do that next.
Creating a Cosmos DB container and inserting data
Now, we tap into the Az.CosmosDB PowerShell module where all the programmatic Cosmos DB goodness is found. Let's create a new container to store JSON data. It's beyond our scope, but you can check the docs to learn more about selecting the best partition key, indexing, and Request Unit (RU) scale settings:
# Create an Azure Cosmos DB container with default indexes and throughput at 400 RU (Code reference: https://timw.info/7mo) $resourceGroupName = "myResourceGroup" $accountName = "mycosmosaccount" $databaseName = "myDatabase" $containerName = "myContainer" $partitionKeyPath = "/myPartitionKey" $throughput = 400 #minimum = 400 New-AzCosmosDBSqlContainer ` -ResourceGroupName $resourceGroupName ` -AccountName $accountName ` -DatabaseName $databaseName ` -Name $containerName ` -PartitionKeyKind Hash ` -PartitionKeyPath $partitionKeyPath ` -Throughput $throughput
To insert data into the container, we'll need to fetch the CosmosDB community module from the PowerShell Gallery:
Install-Module -Name CosmosDB -Verbose Import-Module -Name CosmosDB
We can then invoke the module's New-CosmosDbDocument command to insert a new JSON document into the container:
# Insert data into the container (Ref: https://timw.info/put) $cosmosDbContext = New-CosmosDbContext -Account $accountName -Database $databaseName -ResourceGroup $resourceGroupName $document = @" { "id": "7ea9b3c6-bb1a-3c38-2268-8e17de5b1c70", "productName": "widget-211", "key": "211" } "@ New-CosmosDbDocument -Context $cosmosDbContext -CollectionId 'myContainer' -DocumentBody $document -PartitionKey "211"
Querying the Cosmos DB container
We can continue to use PowerShell and the Cosmos DB module to run queries against our container and JSON data. This first example assumes you know your document's ID:
PS C:\> Get-CosmosDbDocument -Context $cosmosDbContext -CollectionId "myContainer" -Id "7ea9b3c6-bb1a-3c38-2268-8e17de5b1c70",
The second example implements the Core API's SQL-like query language:
$query = "SELECT * FROM myContainer c WHERE (c.productName = 'widget-211')" Get-CosmosDbDocument -Context $cosmosDbContext -CollectionId 'myContainer' -Query $query
Regenerating Cosmos DB account access keys
Last but certainly not least, I want to teach you how to programmatically regenerate your Cosmos DB account's primary read/write access key. Why? Because the Microsoft Security Response Center disclosed an enormous breach recently in which millions of Cosmos DB customers' databases were exposed to the public!
The vulnerability in question affected only the account's primary read/write key. However, you can also perform this procedure on the secondary read/write and primary and secondary read-only keys. The following commands come from the native Az.CosmosDB modules, by the way:
Subscribe to 4sysops newsletter!
# See current primary rw key value for reference (Get-AzCosmosDBAccountKey -ResourceGroupName $resourceGroupName -Name $accountName).PrimaryMasterKey # Regenerate Cosmos account's primary read/write key New-AzCosmosDBAccountKey -ResourceGroupName $resourceGroupName -Name $accountName -KeyKind "primary"
I suggest you define an Azure Automation runbook and schedule Cosmo DB account key regeneration on a regular basis.