Update Azure Resource Tags via DevOps

In a recent development at work, we were looking for a way to expose certain metadata about our resources into the Azure Portal. This came out of that fact that we were trying to troubleshoot an issue with our functions, only to find out that one of it’s dependencies was not updated to the correct version.

So the thought came, if we surface up or display that dependency’s version on our function resource’s portal page, then we can validate the correct deployment is in place before we dive any further into code and that can potentialy reduce our troubleshooting efforts in future.

So for this reason, we decided to export that version number and any other related metadata to the portal using Azure Resource Tags and this post explores that further.

Now, like any other continuous integration, we were leveragining Azure CI/CD pipelines for deploying our Azure Functions, but we were still using the Classic model instead of the YAML

Alright, so with that set… my first step was to start with the some built-in task, that could extract and output data which could be processed by the deployment pipeline and for that I leveraged the PowerShell task as shown below:

image

After importing the task, I configured the inline script as shown below:

# Load the passed in csproj file
$xml = [xml](Get-Content -Path $(csprojfile))

# Get Metadata
$functionVersion = $xml.Project.ItemGroup.PackageReference | Where-Object {$_.Include -eq "Microsoft.NET.Sdk.Functions"} | Select Version
$buildData = "$(Build.BuildNumber) - $(Build.DefinitionName) - $(Build.Repository.Name) - $(Build.SourceBranch) - $(Build.SourceVersion)"

# Write Metadata to file
Add-Content -Path $(Build.ArtifactStagingDirectory)\Tags.txt -Value "Common Lib. Version : $functionVersion"
Add-Content -Path $(Build.ArtifactStagingDirectory)\Tags.txt -Value "BuildDetails : $buildData"

Exploring the above snippet, we first extract out the Functions SDK version from the .csproj file and output that along with other build information to a Tags.txt file.

NOTE: In order to reuse this task in many pipelines, I converted it to a Task Group and parmeterized the csproj file. If you use YAML, then the same could be done via Templates

Following is the snapshot of using that task in a CI pipeline:

image

Running the above pipeline and looking at the artifacts generated we can verify that tags are exported as expected:

image

image

Alright, so with CI in place, next step was to update the CD pipeline to get these tags and create / append that to the Azure Function resource. This is where I used Azure Powershell task with inline script as shown below:

image

# Get Metadata tags from file
$newTags = (Get-Content -Path $(tagsfile))

# Get existing tags from the resource
$tags = (Get-AzResource -ResourceGroupName $(resourceGroupName) -ResourceName $(resourceName)).Tags

# Append new tags 
foreach($tag in $newTags) 
{
        $key = $tag.Split(":")[0]
        $value = $tag.Split(":")[1]
         if (! $tags.ContainsKey($key))
         { 
               $tags.Add($key,$value)
         }
         else
         {
               $tags[$key] = $value
         }
}

# Set Tags
Set-AzResource -ResourceGroupName $(resourceGroupName) -ResourceName $(resourceName) -ResourceType Microsoft.Web/sites -Tag $tags -Force

You can see in the above snippet that we first get the contents of Tags.txt file and then get the existing tags on our function App, only to then append / update and set them accordingly using the Az module in powershell.

NOTE: Like the last task, this one is also exported to a Task group for reusability and the values like tagsfile, resourceGroupName, etc are parameterized accordingly.

Following is the snapshot of using this task in a deployment pipeline:

image

And finally running the deployment pipeline, you can see our tags are displayed on the portal page as shown below:

image

So…that’s it folks, I am sure there are numerous ways to accomplish this. If you know of any, feel free to leave your comments!!!

Related Posts