You apply tags to your Azure resources giving metadata to logically organize them into a taxonomy. Each tag consists of a name and a value pair. For example, you can apply the name "Environment" and the value "Production" to all the resources in production.
After you apply tags, you can retrieve all the resources in your subscription with that tag name and value. Tags enable you to retrieve related resources from different resource groups. This approach is helpful when you need to organize resources for billing or management.
Your taxonomy should consider a self-service metadata tagging strategy in addition to an auto-tagging strategy to reduce the burden on users and increase accuracy.
The following limitations apply to tags:
- Not all resource types support tags. To determine if you can apply a tag to a resource type, see Tag support for Azure resources.
- Each resource or resource group can have a maximum of 50 tag name/value pairs. Currently, storage accounts only support 15 tags, but that limit will be raised to 50 in a future release. If you need to apply more tags than the maximum allowed number, use a JSON string for the tag value. The JSON string can contain many values that are applied to a single tag name. A resource group can contain many resources that each have 50 tag name/value pairs.
- The tag name is limited to 512 characters, and the tag value is limited to 256 characters. For storage accounts, the tag name is limited to 128 characters, and the tag value is limited to 256 characters.
- Generalized VMs don't support tags.
- Tags applied to the resource group are not inherited by the resources in that resource group.
- Tags can't be applied to classic resources such as Cloud Services.
- Tag names can't contain these characters:
<
, >
, %
, &
, \
, ?
, /
To apply tags to resources, the user must have write access to that resource type. To apply tags to all resource types, use the
Contributor role. To apply tags to only one resource type, use the contributor role for that resource. For example, to apply tags to virtual machines, use the
Virtual Machine Contributor.
Note
This article provides steps for how to delete personal data from the device or service and can be used to support your obligations under the GDPR. If you’re looking for general info about GDPR, see the
GDPR section of the Service Trust portal.
Policies
You can use
Azure Policy to enforce tagging rules and conventions. By creating a policy, you avoid the scenario of resources being deployed to your subscription that don't comply with the expected tags for your organization. Instead of manually applying tags or searching for resources that aren't compliant, you can create a policy that automatically applies the needed tags during deployment. The following section shows example policies for tags.
PowerShell
Note
This article has been updated to use the new Azure PowerShell Az module. You can still use the AzureRM module, which will continue to receive bug fixes until at least December 2020. To learn more about the new Az module and AzureRM compatibility, see
Introducing the new Azure PowerShell Az module. For Az module installation instructions, see
Install Azure PowerShell.
To see the existing tags for a resource group, use:
(Get-AzResourceGroup -Name examplegroup).Tags
That script returns the following format:
Name Value
---- -----
Dept IT
Environment Test
To see the existing tags for a resource that has a specified resource ID, use:
(Get-AzResource -ResourceId /subscriptions/<subscription-id>/resourceGroups/<rg-name>/providers/Microsoft.Storage/storageAccounts/<storage-name>).Tags
Or, to see the existing tags for a resource that has a specified name and resource group, use:
(Get-AzResource -ResourceName examplevnet -ResourceGroupName examplegroup).Tags
To get resource groups that have a specific tag, use:
(Get-AzResourceGroup -Tag @{ Dept="Finance" }).ResourceGroupName
To get resources that have a specific tag, use:
(Get-AzResource -Tag @{ Dept="Finance"}).Name
To get resources that have a specific tag name, use:
(Get-AzResource -TagName Dept).Name
Every time you apply tags to a resource or a resource group, you overwrite the existing tags on that resource or resource group. Therefore, you must use a different approach based on whether the resource or resource group has existing tags.
To add tags to a resource group without existing tags, use:
Set-AzResourceGroup -Name examplegroup -Tag @{ Dept="IT"; Environment="Test" }
To add tags to a resource group that has existing tags, retrieve the existing tags, add the new tag, and reapply the tags:
$tags = (Get-AzResourceGroup -Name examplegroup).Tags
$tags.Add("Status", "Approved")
Set-AzResourceGroup -Tag $tags -Name examplegroup
To add tags to a resource without existing tags, use:
$r = Get-AzResource -ResourceName examplevnet -ResourceGroupName examplegroup
Set-AzResource -Tag @{ Dept="IT"; Environment="Test" } -ResourceId $r.ResourceId -Force
To add tags to a resource that has existing tags, use:
$r = Get-AzResource -ResourceName examplevnet -ResourceGroupName examplegroup
$r.Tags.Add("Status", "Approved")
Set-AzResource -Tag $r.Tags -ResourceId $r.ResourceId -Force
To apply all tags from a resource group to its resources, and not keep existing tags on the resources, use the following script:
$groups = Get-AzResourceGroup
foreach ($g in $groups)
{
Get-AzResource -ResourceGroupName $g.ResourceGroupName | ForEach-Object {Set-AzResource -ResourceId $_.ResourceId -Tag $g.Tags -Force }
}
To apply all tags from a resource group to its resources, and keep existing tags on resources that aren't duplicates, use the following script:
$group = Get-AzResourceGroup "examplegroup"
if ($null -ne $group.Tags) {
$resources = Get-AzResource -ResourceGroupName $group.ResourceGroupName
foreach ($r in $resources)
{
$resourcetags = (Get-AzResource -ResourceId $r.ResourceId).Tags
if ($resourcetags)
{
foreach ($key in $group.Tags.Keys)
{
if (-not($resourcetags.ContainsKey($key)))
{
$resourcetags.Add($key, $group.Tags[$key])
}
}
Set-AzResource -Tag $resourcetags -ResourceId $r.ResourceId -Force
}
else
{
Set-AzResource -Tag $group.Tags -ResourceId $r.ResourceId -Force
}
}
}
To remove all tags, pass an empty hash table:
Set-AzResourceGroup -Tag @{} -Name examplegroup
Azure CLI
To see the existing tags for a resource group, use:
az group show -n examplegroup --query tags
That script returns the following format:
{
"Dept" : "IT",
"Environment" : "Test"
}
Or, to see the existing tags for a resource that has a specified name, type, and resource group, use:
az resource show -n examplevnet -g examplegroup --resource-type "Microsoft.Network/virtualNetworks" --query tags
When looping through a collection of resources, you might want to show the resource by resource ID. A complete example is shown later in this article. To see the existing tags for a resource that has a specified resource ID, use:
az resource show --id <resource-id> --query tags
To get resource groups that have a specific tag, use az group list
:
az group list --tag Dept=IT
To get all the resources that have a particular tag and value, use az resource list
:
az resource list --tag Dept=Finance
Every time you apply tags to a resource or a resource group, you overwrite the existing tags on that resource or resource group. Therefore, you must use a different approach based on whether the resource or resource group has existing tags.
To add tags to a resource group without existing tags, use:
az group update -n examplegroup --set tags.Environment=Test tags.Dept=IT
To add tags to a resource without existing tags, use:
az resource tag --tags Dept=IT Environment=Test -g examplegroup -n examplevnet --resource-type "Microsoft.Network/virtualNetworks"
To add tags to a resource that already has tags, retrieve the existing tags, reformat that value, and reapply the existing and new tags:
jsonrtag=$(az resource show -g examplegroup -n examplevnet --resource-type "Microsoft.Network/virtualNetworks" --query tags)
rt=$(echo $jsonrtag | tr -d '"{},' | sed 's/: /=/g')
az resource tag --tags $rt Project=Redesign -g examplegroup -n examplevnet --resource-type "Microsoft.Network/virtualNetworks"
To apply all tags from a resource group to its resources, and not keep existing tags on the resources, use the following script:
groups=$(az group list --query [].name --output tsv)
for rg in $groups
do
jsontag=$(az group show -n $rg --query tags)
t=$(echo $jsontag | tr -d '"{},' | sed 's/: /=/g')
r=$(az resource list -g $rg --query [].id --output tsv)
for resid in $r
do
az resource tag --tags $t --id $resid
done
done
To apply all tags from a resource group to its resources, and keep existing tags on resources, use the following script:
groups=$(az group list --query [].name --output tsv)
for rg in $groups
do
jsontag=$(az group show -n $rg --query tags)
t=$(echo $jsontag | tr -d '"{},' | sed 's/: /=/g')
r=$(az resource list -g $rg --query [].id --output tsv)
for resid in $r
do
jsonrtag=$(az resource show --id $resid --query tags)
rt=$(echo $jsonrtag | tr -d '"{},' | sed 's/: /=/g')
az resource tag --tags $t$rt --id $resid
done
done
Templates
To tag a resource during deployment, add the tags
element to the resource you're deploying. Provide the tag name and value.
Apply a literal value to the tag name
The following example shows a storage account with two tags (Dept
and Environment
) that are set to literal values:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]"
}
},
"resources": [
{
"apiVersion": "2019-04-01",
"type": "Microsoft.Storage/storageAccounts",
"name": "[concat('storage', uniqueString(resourceGroup().id))]",
"location": "[parameters('location')]",
"tags": {
"Dept": "Finance",
"Environment": "Production"
},
"sku": {
"name": "Standard_LRS"
},
"kind": "Storage",
"properties": {}
}
]
}
Apply an object to the tag element
You can define an object parameter that stores several tags, and apply that object to the tag element. Each property in the object becomes a separate tag for the resource. The following example has a parameter named tagValues
that is applied to the tag element.
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]"
},
"tagValues": {
"type": "object",
"defaultValue": {
"Dept": "Finance",
"Environment": "Production"
}
}
},
"resources": [
{
"apiVersion": "2019-04-01",
"type": "Microsoft.Storage/storageAccounts",
"name": "[concat('storage', uniqueString(resourceGroup().id))]",
"location": "[parameters('location')]",
"tags": "[parameters('tagValues')]",
"sku": {
"name": "Standard_LRS"
},
"kind": "Storage",
"properties": {}
}
]
}
Apply a JSON string to the tag name
To store many values in a single tag, apply a JSON string that represents the values. The entire JSON string is stored as one tag that can't exceed 256 characters. The following example has a single tag named CostCenter
that contains several values from a JSON string:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]"
}
},
"resources": [
{
"apiVersion": "2019-04-01",
"type": "Microsoft.Storage/storageAccounts",
"name": "[concat('storage', uniqueString(resourceGroup().id))]",
"location": "[parameters('location')]",
"tags": {
"CostCenter": "{\"Dept\":\"Finance\",\"Environment\":\"Production\"}"
},
"sku": {
"name": "Standard_LRS"
},
"kind": "Storage",
"properties": {}
}
]
}
To apply tags from a resource group to a resource, use the
resourceGroup function. When getting the tag value, use the
tags.[tag-name]
syntax instead of the
tags.tag-name
syntax, because some characters aren't parsed correctly in the dot notation.
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]"
}
},
"resources": [
{
"apiVersion": "2019-04-01",
"type": "Microsoft.Storage/storageAccounts",
"name": "[concat('storage', uniqueString(resourceGroup().id))]",
"location": "[parameters('location')]",
"tags": {
"Dept": "[resourceGroup().tags['Dept']]",
"Environment": "[resourceGroup().tags['Environment']]"
},
"sku": {
"name": "Standard_LRS"
},
"kind": "Storage",
"properties": {}
}
]
}
Portal
To view the tags for a resource or a resource group, looks for existing tags in the overview. If you have not previously applied tags, the list is empty.
To add a tag, select Click here to add tags.
Provide a name and value. Select + to add the tag.
Continue adding tags as needed. When done, select Save.
The tags are now displayed in the overview.
To add or delete a tag, select change.
To delete a tag, select the trash icon. Then, select Save.
To bulk assign tags to multiple resources:
From any list of resources, select the checkbox for the resources you want to assign the tag.
Select Assign tags
After each name and value, select +. When done, select Assign.
To view all resources with a tag:
Select All services and Tags.
Select the tag for viewing resources.
All resources with that tag are displayed.
For quick access, pin the view to the dashboard.
The view is available from the dashboard.
REST API
The Azure portal and PowerShell both use the
Resource Manager REST API behind the scenes. If you need to integrate tagging into another environment, you can get tags by using
GET on the resource ID and update the set of tags by using a
PATCH call.
You can use tags to group your billing data. For example, if you're running multiple VMs for different organizations, use the tags to group usage by cost center. You can also use tags to categorize costs by runtime environment, such as the billing usage for VMs running in the production environment.
Next steps