Resource Tagging in Azure


A brief explanation of the concept of tags in Azure, and a few scripts for managing tags. In this post I’m not focusing on how to manage tags manually in the Azure Portal, rather a possible way to manage tags with Azure PowerShell.

Purpose

Tagging in Microsoft Azure or in the cloud generally is useful when you operate a number of resources. By applying metadata to logically organize and manage resources in an easy way, since tags are just additional metadata or attributes associated with Microsoft Azure ARM (Azure Resource Manager) resources.

Tag assignment

Tags can be specifically be assigned individual resources like storage accounts, virtual machines, or Resource Groups. Resource groups organize related resources to facilitate management, but when a Resource Group is assigned a tag its only assigned to the Resource Group and not its child resources. So bare in mind that child resources within a Resource Group not inherit tags.

Tag example

Tags consists of Key → Value pairs that we can assign to resources, for instance project, owner, department and life cycle phase tag. You give the tag a Key and a suitable value, which you can use to filter later on. A resource can have up to 15 tags, it’s therefore important to have a concise and consistent naming standard for your tags. In other words, do not use tags that don’t provide any useful information. Below is an example of the result of a tagged resource.

Key             Value
---             -----
Project         Learning Tags
Department      IT
LifeCyclePhase  Stage

Why do we tag Resources?

Tagging let you organize deployed Azure resources. For instance we can use tags when it comes to things like:

  • Search by a specific tag, let’s say we want to find all resources tagged with Department → IT.
  • It facilitates viewing of related resources, for instance you like a list of Stage servers vs. Production servers.
  • It facilitates billing and cost management, overview of different projects and customers as well.
  • Allows automation and bulk actions, for instance “shutdown all VMs with the tag LifeCyclePhase → Stage

Tag restriction:

When creating resource tags, there is some limitations or restriction to consider:

  • A resource can have a maximum of 15 tags
  • A Resource Group can have a maximum of 15 key/pairs
  • A tag name is restricted to 512 characters and tag value is restricted to 256 characters.
  • Tags applied to a Resource Group is not inherited by the resources within the Resource Group
  • Tags cannot be applied to classic resources, such as Cloud Services.
  • Tag names cannot contain the following characters <,>,%,&,,?,/

Tag Management

Tags can be managed in the Azure Portal, but only after a resource is created. You can also manage tags from Azure PowerShell and Azure CLI. When I learned about it, I thought I create some scripts for managing tags, just to get some hands on experience. It ended up with a script for getting, adding and removing tags. It ended with the following scripts:

Get-AzResourceTag

In this script, I use the cmdlet Get-AzResource and wrapped it with parenthesis and selected the property tags, to list the properties to the resource specified in the parameter $ResourceName and $ResourceGroupNamee. I also used Write-Verbose to be able to see what the function does when it is runs, by this can be called by adding -Verbose in the function call, for instance

Get-AzResourceTag -ResourceName "vm1" -ResourceGroupName "rg1" -Verbose.

# Note to use the function use . source (. .\Get-AzResourceTag.ps1) to load it into memory or
# hit the play button (F5) if you use PowerShell ISE,
# or mark everything and hit F8 (works in both VS Code and PS ISE).

function Get-AzResourceTag {
    [CmdletBinding()]
    param (
        # Name of the resource
        [Parameter(Mandatory = $true)]
        [String]
        $ResourceName,
        # Name of the Resource Group
        [Parameter(Mandatory = $true)]
        [String]
        $ResourceGroupName
    )
    process {
        Write-Verbose "Getting a Azure Resource tags for $ResourceName.."
        (Get-AzResource -Name $ResourceName -ResourceGroupName $ResourceGroupName).Tags
    }
}

# When executed in the PowerShell window, you will see the followin
PS C:\>Get-AzResourceTag -ResourceName "vm1" -ResourceGroupName "rg1" -Verbos
VERBOSE: Getting a Azure Resource tags for vm1..

Key             Value
---             -----
Project         Learning Tags
Department      IT
LifeCyclePhase  Stage

New-AzResourceTag

To add a tag to an Azure Resource you can use the cmdlet Set-AzResource , this cmdlet takes Resource Name or Resource id, Resource Group, and a hash table as input to create a key→value pair tag. The first thing I did was to create an advanced PowerShell function, which comes with many great features such as verbose and debug, and then creating the necessary parameters (for my needs).

Then I retrieve the reference Id of the resource specified in the parameters, then listing all the tags already existing in the resource. Then adding the new tag to the hash table, notice that I use += to add the new tag, if you just use = , you will overwrite all existing tags and the newly created tag will be the only one left.

At last, I only list out the all the tags again to see the new changes.

function New-AzResourceTag {
[CmdletBinding()]
param (
    # Name of the resource
    [Parameter(Mandatory = $true)]
    [String]
    $ResourceName,

    # Name of the Resource Group
    [Parameter(Mandatory = $true)]
    [String]
    $ResourceGroupName,

    # Name of the tag
    [Parameter(Mandatory = $true)]
    [String]
    $TagName,

    # Value of the tag
    [Parameter(Mandatory = $true)]
    [String]
    $TagValue
)
process {
    Write-Verbose "Getting a reference to an Azure Resource.."
    $Resource = Get-AzResource -Name $ResourceName -ResourceGroupNam$ResourceGroupName

    Write-Verbose "Retrieving existing resource tags, if any"
    $Tags = (Get-AzResource -Name $ResourceName).Tags

    # Add new tags to existing tags
    Write-Verbose "Adding new tag to existing tags.."
    $Tags += @{ $TagName = $TagValue }

    Write-Verbose "Creating tag.."
    Set-AzResource -ResourceId $Resource.Id -Tag $Tags -Force

    Write-Verbose "Finished setting new tag value.."

    Write-Host -ForegroundColor Green "New tag values:"
    (Get-AzResource -Name $ResourceName -ResourceGroupName $ResourceGroupName).Tags
}}

Remove-AzResourceTags

To remove the tags from a resource you can simple just add an empty hash table, then it will overwrite all existing tags.

Notice the name of the function, it ends with tags in plural, the following script will remove all the tags added to a resource.

function Remove-AzResourceTags {
    [CmdletBinding()]
    param (
        # Name of the resource
        [Parameter(Mandatory = $true)]
        [String]
        $ResourceName,

        # Name of the Resource Group
        [Parameter(Mandatory = $true)]
        [String]
        $ResourceGroupName
    )
    process {
        Write-Verbose "Retriving resource id.."
        $Resource = (Get-AzResource -Name $ResourceName -ResourceGroupName$ResourceGroupName).Id

        Write-Verbose "Removing tags from resource: $ResourceName..."
        Set-AzResource -ResourceId $Resource -Tag @{ } -Force

        Write-Verbose "All tags on the resource $ResourceName is removed.."
        (Get-AzResource -Name $ResourceName -ResourceGroupName $ResourceGroupName.Tags

        Write-Verbose "Listing tags.. empty though..."
        (Get-AzResource -Name $ResourceName -ResourceGroupName $ResourceGroupName).Tags
    }
}

To sum up, this was a brief on purpose, usage scenarios, restrictions and management of tagging in Azure. Hope you enjoyed!