Uploading Governance Tags back to Azure
  • Updated on 20 May 2020
  • 2 minutes to read
  • Contributors
  • Print
  • Comments
  • Share
  • Dark
    Light

Uploading Governance Tags back to Azure

  • Print
  • Comments
  • Share
  • Dark
    Light

In this part I would like to take the csv file produced by the script that downloaded the tags and which I have then modified in the csv file and apply the changes back to Azure.

In the script at the bottom I will point to the function that will update Azure. It will take the csv path and the resource group to update. It will then go through the resources in the spreadsheet and compare the tags, adding missing ones and updating those that changed. If any tags on the resource have changed then it will use Set-AzResource to update the tags.

Full Script



function UpdateResourceGovernanceTags([string] $csvPath, [string] $resourceGroup)
{    

    $csv = Import-Csv $csvPath

    #Download Resources in Resource Group
    Write-Host 'Downloading resources from Azure'
    $azResources = Get-AzResource -ResourceGroupName $resourceGroup
    $azResourceDictionary = New-Object "System.Collections.Generic.Dictionary``2[System.String,System.Object]"
    foreach($azResource in $azResources){
        $azResourceDictionary.Add($azResource.Id, $azResource)
    }

    #Process the CSV File
    Write-Host 'Processing CSV file' $csvPath
    foreach($item in $csv)
    {
        $resourceTagsChanged = $false

        #Write-Host $item

        #Read Items from CVS Line
        $id = $item.Id
        $resourceGroupName = $item.ResourceGroup
        $name = $item.Name
        $type = $item.Type
        $environment = $item.Tag_Environment
        $costCentre = $item.Tag_costCentre
        $managedBy = $item.Tag_managedBy
        $documentationLink = $item.Tag_documentationLink

        if($type -eq 'Microsoft.Web/customApis'){
            Write-Host 'Skipping resource' $name 'because its a custom api - they seem to not like the Set-AzResource'
            continue
        }


        #Create Governance Tags
        Write-Host 'Adding governance tags from csv'
        $governanceTags = New-Object "System.Collections.Generic.Dictionary``2[System.String,System.Object]" 
        $governanceTags.Add('Environment', $environment)
        $governanceTags.Add('costCentre', $costCentre)
        $governanceTags.Add('managedBy', $managedBy)
        $governanceTags.Add('documentationLink', $documentationLink)

        #Get Matching Azure Resource
        $resource = $azResourceDictionary[$id]        
        if($resource -ne $null){
            if($resource.ResourceGroupName -eq $resourceGroup){
            
                Write-Host 'Processing Resource' $resource.Name
            
                #Get Existing Tags
                Write-Host 'Getting existing tags for resource' $resource.Name
                $resourceTags = New-Object "System.Collections.Generic.Dictionary``2[System.String,System.Object]" 
                if($resource.Tags -ne $null){
                
                    #Some resources may have null tags
                    foreach($resourceTag in $resource.Tags.GetEnumerator()){
                        $resourceTags.Add($resourceTag.Key, $resourceTag.Value)
                    }
                }

                #Merge Governance Tags into Resource Tags
                Write-Host 'Merge Governance Tags into Resource Tags for resource' $resource.Name
                foreach($governanceTag in $governanceTags.GetEnumerator()){

                    if($governanceTag.Value -ne ''){ 
                               
                        if($resourceTags.ContainsKey($governanceTag.Key)){
                        
                            $existingTagValue = $resourceTags[$governanceTag.Key]
                            if($existingTagValue -ne $governanceTag.Value){

                                #Update Tag as the value has changed
                                Write-Host 'Updating Tag' $governanceTag.Key 'with value' $governanceTag.Value
                                $resourceTags[$governanceTag.Key] = $governanceTag.Value
                                $resourceTagsChanged = $true
                            }
                        }
                        else{

                            #Add Missing Tag
                            Write-Host 'Adding missing Tag' $governanceTag.Key 'to value' $governanceTag.Value
                            $resourceTags.Add($governanceTag.Key, $governanceTag.Value)
                            $resourceTagsChanged = $true
                        }
                    }
                    else{
                        Write-Host 'Skipping tag with no value:' $governanceTag.Key
                    }
                }

                if($resourceTagsChanged -eq $true){
                    
                    Write-Host 'Updating tags for resource: Name = ' $name ' - ID = ' $id
                    Set-AzResource -ResourceId $id -Tag $resourceTags -Force
                }
                else{
                    Write-Host 'Resource Tags unchanged = ' $name ' - ID = ' $id
                }
            }
            else{
                Write-Host $id ' not updated because resource group doesnt match'
            }
        } 
        else{
            Write-Host 'Resource is not in azure: ' $id
        }       
    }   
}

#Dev
$path = $PSScriptRoot + '\Resources.Dev.csv'
$resourceGroup = 'MyRG-Dev'
UpdateResourceGovernanceTags -csvPath $path -resourceGroup $resourceGroup

Was this article helpful?