After we set up our Azure Cosmos DB, we may want to get, add to, or update existing properties. We may use some of the get functionality that PowerShell provides to dynamically save values to encrypted configuration files or tables that we use for application purposes and this functionality could be added to the creation of the Cosmos database account, or a separate step in addition to the creation. In secure contexts, this ensures security without the properties after passing through human eyes since they are saved directly to an encrypted location. In the same manner, we may want to regenerate the keys for the account and save the connection strings with the new keys.
For the sake of examples in this tip, we’ll show keys to demonstrate the functionality of these PowerShell scripts with Azure Cosmos DB. In secure settings, we want to save these values directly to their location (file, table, encrypted storage, etc), if we have a target for our obtaining these properties.
Dependencies to Check
Identical to the create and remove of a Cosmos database account, these scripts require PowerShell’s Az module. In addition, we can either create a new Cosmos database account (done for this tip), or we can use an existing account for these scripts to get the properties (such as the Azure Cosmos DB we created in the first part of this series). For security reasons, I recommend testing with a new account and not an existing account if the existing account is being used for any other purposes outside of testing.
Once we have the correct module installed, we will connect to Azure using the below PowerShell call. Throughout this tip, we will not log in again but re-use the same PowerShell session. If you close the PowerShell session, another login will be required. In addition, we will also see where we can get and update this information through the Azure Portal, since the portal can be appropriate in organizations where there are few resources.
1 |
Connect-AzAccount |
Get Connection Strings
In the Azure Portal, we can get the connection string and key information (along with regenerating keys) from the Keys option under Settings. In the below images, the most of actual keys are removed and you will see different keys when you look at your Cosmos account. We’ll also note in the two images that we have read-write keys and read-only keys.
In the Azure Portal, we see the read-write keys for our Azure Cosmos DB.
In the tab to the right, we see the read-only keys for our Azure Cosmos DB.
We will need the connection string for applications to connect and use the Azure Cosmos DB. In smaller contexts where we may only have one or two Cosmos database accounts, we can get this information through the portal – though security even in these contexts is a risk (screen grabbing malware or keyloggers). Automating the retrieval of this information, especially after a set up so that it can be stored in a secured location for configuration use (files, tables, encrypted storage, etc) ensures strict security over allowing this information to pass through a user. The unfortunately reality with security is that malware can include screenshot attacks, internal users can sometimes compromise environments, and other attacks may occur from sophisticated malware. Automation of saving credentials reduces these attacks along with saving time, especially during the setup.
In the below script, we get the connection strings for our Azure Cosmos DB by saving the connectionStrings property to a variable and returning the variable. We’ll see that four connection strings return.
1 2 3 4 5 6 7 8 9 |
$api = "2015-04-08" $rGroup = "OurResourceGroup" $cosmosdb = "scosdb" $scons = (Invoke-AzResourceAction -Action listConnectionStrings ` -ResourceType "Microsoft.DocumentDb/databaseAccounts" -ApiVersion $api -ResourceGroupName $rGroup ` -Name $cosmosdb -Force).connectionStrings $scons.connectionString |
We’ll notice the order of our Azure Cosmos DB connection strings – the read-write are the first two followed by the read-only keys.
When we look at the results from the Azure portal, we see that the first two returned are the read and write keys with the second two keys being the read only keys. For demarcating these, we’ll get these individually by specifying their location in the object (inherited from System.Array). The comments only specify what the keys are for clarification.
1 2 3 4 5 6 7 |
### Read-Write keys $scons.connectionString[0] $scons.connectionString[1] ### Read-Only keys $scons.connectionString[2] $scons.connectionString[3] |
If we wanted to save the read-write connection strings, we would access the first two and we’d make the appropriate adjustments if we only wanted the ready connection strings.
Regenerate and Get Keys
For security purposes, we may want to regenerate keys on a schedule and update these keys for our Azure Cosmos DB. We can mirror standard password policies of updating keys every periodic cadence and follow the practices we used in the above code of saving this information directly to a secured location for configuration use. Depending on our design of regenerating keys and saving these keys, we want to thoroughly test this as it’s possible this could introduce outages if we haven’t ensured that no part of the regeneration and save fails (for instance, the script regenerates the key, but the save to the secured location fails, meaning that configurations will still use old values).
We can regenerate keys in the Azure Portal for our Azure Cosmos DB.
In the below code, we regenerate the Azure Cosmos DB secondary key and write it out on screen, which we do only for testing purposes in this tip (the first two characters are shown to confirm it differs from the above two characters). Our logic of updating the secondary key first is the following, if we assume that the primary key is used for our application:
- Regenerate the secondary key, save it to the secured location, and test the key. In this tip, we’ll only verify that the key has been updated by reviewing the first two characters to demonstrate the functionality
- If the update to the secondary key passes, update the primary key following the same process of regeneration, saving to a secured location, and testing. Updating the primary key follows the same process of updating the secondary key in Azure Cosmos DB except its name
- We can follow this same process if we want to regenerate the read only keys where we update one before the other. In this tip, we’ll see how to update the secondary read only key
If the testing of the secondary key regeneration fails, we would switch back to the primary key (this can be coded logically for testing).
1 2 3 4 5 6 7 8 9 10 |
$api = "2015-04-08" $rGroup = "OurResourceGroup" $cosmosdb = "scosdb" $regenerate = @{"keyKind"="secondary"} $2key = Invoke-AzResourceAction -Action regenerateKey ` -ResourceType "Microsoft.DocumentDb/databaseAccounts" -ApiVersion $api -ResourceGroupName $rGroup ` -Name $cosmosdb -Parameters $regenerate Write-Host $2key.secondaryMasterKey |
We see an updated value for our Azure Cosmos DB secondary key.
We can see that we can specify the key we want to update in the regenerate object – in the above script, we update the secondary key. What if we wanted to update the secondary read only key? In this case, we wouldn’t specify primary or secondary, but secondaryReadOnly in the regenerate object. In the below script, we run a similar regenerate and update the secondary read only key and return this value.
1 2 3 4 5 6 7 8 9 10 |
$api = "2015-04-08" $rGroup = "OurResourceGroup" $cosmosdb = "scosdb" $regenerate = @{"keyKind"="secondaryReadOnly"} $2key = Invoke-AzResourceAction -Action regenerateKey ` -ResourceType "Microsoft.DocumentDb/databaseAccounts" -ApiVersion $api -ResourceGroupName $rGroup ` -Name $cosmosdb -Parameters $regenerate Write-Host $2key.secondaryReadonlyMasterKey |
We see the secondary read only key has been updated.
The same logic applies to changing the primary key or primary read only key – we would simply replace secondary with primary (primary or primaryReadOnly) and regenerate the keys. Now that we’ve regenerated the secondary and secondary read only keys in our Azure Cosmos DB, we’ll call our previous function to get the connection string information and return the set of secondary keys only to confirm that both connection strings are updated with the regenerated keys.
1 2 3 4 5 6 7 8 9 10 11 |
$api = "2015-04-08" $rGroup = "OurResourceGroup" $cosmosdb = "scosdb" $scons = (Invoke-AzResourceAction -Action listConnectionStrings ` -ResourceType "Microsoft.DocumentDb/databaseAccounts" -ApiVersion $api -ResourceGroupName $rGroup ` -Name $cosmosdb -Force).connectionStrings ### Secondary keys only $scons.connectionString[1] $scons.connectionString[3] |
Our new secondary keys show when we return their connection strings.
Conclusion
We’ve seen that with PowerShell and the Az module we can get and update properties such as the keys and connection strings for our Azure Cosmos DB. With these tools, we can get the connection string or connection key information and pass it into a secure location without accessing it, if we need these values upon creation saved securely. Likewise, we can use these calls to get these values dynamically if they’re needed for a short period of time, such as a unit or security test. In a similar manner, we can regenerate keys, if we want to change the keys for security reasons (seasonal rotations, proactive security, updates, etc).
Keep in mind that we still want to consider when we use these scripts to get this information, how this information will be stored securely, and how we’ll avoid any outages if we make updates. PowerShell adds significant power to our Azure Cosmos DB automation and we still have to consider the best practices for our design.
Table of contents
Creating and Removing Azure Cosmos DBs with PowerShell |
Getting and Updating Connection Information for Azure Cosmos DB |
Creating and Removing Databases with PowerShell In Azure Cosmos DB |
Increasing or Decreasing Scale for Azure Cosmos DB |
Creating Containers with PowerShell For Azure Cosmos DB |
- Data Masking or Altering Behavioral Information - June 26, 2020
- Security Testing with extreme data volume ranges - June 19, 2020
- SQL Server performance tuning – RESOURCE_SEMAPHORE waits - June 16, 2020