Lately, I have been playing around with Azure DevOps, specifically a web application deployment using ARM Templates and Azure PowerShell.
I have a project, and an associated GIT repository, in Azure DevOps where I keep my ARM Templates and PowerShell scripts that I use for the deployment of my web application.
The release pipeline is triggered off of a commit to the master
branch.
I have a table in Azure Storage, called lookups
.
This is where I store all my lookup data, in this case, a list of all the Sports data available for my web application.
I store the Sports data in my repository in a file called sports.json
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
[ { "RowKey": "7fa95637-67d8-4ead-a1de-7aa8c2846ff9", "Name": "Basketball", "IsPopular": "true" }, { "RowKey": "063a601c-590d-468c-b9ea-a1d82c8fc673", "Name": "Football", "IsPopular": "true" }, { "RowKey": "35f25d50-9b3d-41f7-b788-dc92678c7720", "Name": "Baseball", "IsPopular": "true" }, { "RowKey": "84e14ebb-ff6a-4466-b976-46dff368afdb", "Name": "Soccer", "IsPopular": "true" }, { "RowKey": "b8fd389b-de76-4c45-abec-2f1e7f569af5", "Name": "Hockey", "IsPopular": "true" }, { "RowKey": "2bdc4cc8-5bda-4b37-9c02-5f4cfc2e4918", "Name": "Tennis", "IsPopular": "false" }, { "RowKey": "50b5ab15-bbd9-444d-a70d-63c4dd28a990", "Name": "Lacrosse", "IsPopular": "false" } ] |
In one of my release tasks, I would like to populate the lookups
table with the Sports data.
This can be accomplished through an Azure PowerShell task with the help of the AzureRMStorageTable module.
I am very thankful to Paulo Marques da Costa’s for his article, Working with Azure Tables from PowerShell – AzureRmStorageTable/AzTable PS Module v2.0, this was a huge help in figuring all the nuances of working with Table Storage with Azure PowerShell 2.*.
This feature is only available using Azure PowerShell 2.*, so make sure you set the Task Version to 4.* preview.
Let’s take a look at the PowerShell script.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
param ( [string]$EnvironmentName = $(throw "-EnvironmentName is required."), [string]$EnvironmentShortName = $(throw "-EnvironmentShortName is required."), [string]$DataPath ) Install-Module AzureRmStorageTable -Force $resourceGroupName = "XXXXXXXXXXX-" + $EnvironmentShortName.ToLower() + "-rg" $storageAccountName = "XXXXXXXXXXX" + $EnvironmentShortName.ToLower() + "001stgacc"; $storageAccount = Get-AzStorageAccount -ResourceGroupName $resourceGroupName -AccountName $storageAccountName $storageTable = Get-AzStorageTable ` -Name "lookups" ` -Context $storageAccount.Context ` -ErrorVariable ev ` -ErrorAction SilentlyContinue if ($ev) { New-AzStorageTable -Name "lookups" -Context $storageAccount.Context $storageTable = Get-AzStorageTable -Name "lookups" -Context $storageAccount.Context } $sportsPath = "sports.json" Write-Host $DataPath if ($DataPath) { $sportsPath = $DataPath + $sportsPath } $sports = Get-Content -Raw -Path $sportsPath | ConvertFrom-Json ForEach ($sport in $sports) { try { Add-AzTableRow ` -table $storageTable.CloudTable ` -partitionKey "Sport" ` -rowKey $sport.RowKey ` -property @{"Name" = $sport.Name; "IsPopular" = $sport.IsPopular } ` -ErrorVariable ev ` -ErrorAction SilentlyContinue } catch [System.Management.Automation.MethodInvocationException] { $tableRow = Get-AzTableRow ` -table $storageTable.CloudTable ` -partitionKey "Sport" ` -rowKey $sport.RowKey $tableRow.Name = $sport.Name $tableRow.IsPopular = $sport.IsPopular $tableRow | Update-AzTableRow -table $storageTable.CloudTable Write-Host $tableRow } } |
The script attempts to get the Azure Table Storage table lookups
, if it is not found, it then creates thelookups
table in Azure Table Storage.
The script takes three parameters:
EnvironmentName
andEnvironmentShortName
are used for naming resourcesDataPath
points to location of thesports.json
file
When working locally, I do not pass anything for the DataPath parameter, it will use the root location of the script, while in Azure DevOps, I pass the value of $(System.DefaultWorkingDirectory)/_Teamaloo.Infrastructure/
to the DataPath parameter.
The scripts loads up the sports.json
file and starts iterating through each record. It tries to add the record, if that fails, the assumption is the record already exists, and it then updates the record.
One thing I want to call out, in order to get this script to run, I had to add the Install-Module AzureRmStorageTable -Force
command at the beginning, using -Force
disables any required user interaction.
The AzureRmStorageTable module was not available by default.
I tried using Install-Module AzTable
, the updated namespace, but that did not work.
Once I imported this module, everything worked perfectly.
This took me a couple of days to figure out, so hopefully this saves someone else a day or two.
As always, if there is an easier way to do this, please share!
Discover more from Matt Ruma
Subscribe to get the latest posts sent to your email.
Thank you Matt . your post helped me a lot .
As far as you know is this still currently the best way to insert data into an Azure Storage Table?
Thanks for this post. As far as you know is this still currently the best way to insert data into an Azure Storage Table?