Easy tagging of resources in Azure for billing and charge back

Tagging of resources in Azure can be a pain, especially if you have heaps of resources deployed. Tagging is used primarily for billing purposes and tags applied to the resource group are not inherited by the resources in that resource group. What’s more, if you want to chargeback Azure consumption to the business across various business units, tagging is the best way to do it. 

There’s a few of ways you can chargeback to business units by using tags:

However, if you follow the same methodology of separating Resource Groups per distributed application as per the Azure enterprise scaffold, life could all of a sudden get much easier.

If you have done this and assuming from a resource group level you have:

  • grouped your Azure resources as above on a per application basis
  • tagged all your Resource Groups
  • grouped your Azure resources as per above on a per application basis

… then you can contunue with this blog post so you can easily chargeback Azure costs to business units on a resource group by resource group level.

This script will:

  • apply all tags from a resource group to its child resources
  • retain existing tags on resources that are not duplicates
  • and not overwrite any duplicate tags

From here I have taken a script and have it below, you simply take this below and run this script in an Azure Automation runbook (PowerShell script) and have it scheduled to be run on a daily/weekly/monthly basis depending on how much your Resource Groups change. All it will do is as described above and update child resource tags. Even if this script runs over and over again, it won’t make any changes unless it needs to update child resources. If child resources have the same tags as the parrent resource group, it will simply skip over all resources and finish. 

To run this script automatically, you will need to set this up in Azure Automation. For this, you will need an Azure Automation Account (setup by following this guide) and an Azure Automation Run As account, which can be setup by following this guide

Create an Azure Automation runbook, paste this in and schedule it to be run. 

##########################################################################################
###################### To be used with an Azure Automation runbook
###################### make sure you create the Automation Credential -Name 'AzureRunAsConnection'
###################### make sure you Automation Variable -Name 'SubscriptionID'
######################
##########################################################################################
# Thanks to https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-using-tags
$ServicePrincipalConnection = Get-AutomationConnection Name 'AzureRunAsConnection'
$null = Add-AzureRmAccount `
ServicePrincipal `
TenantId $ServicePrincipalConnection.TenantId `
ApplicationId $ServicePrincipalConnection.ApplicationId `
CertificateThumbprint $ServicePrincipalConnection.CertificateThumbprint
Get-AzureRmSubscription SubscriptionId (Get-AutomationVariable Name 'SubscriptionID') | Select-AzureRmSubscription
##########################################################################################
###################### apply all tags from a resource group to its resources
###################### and retain existing tags on resources that are not duplicates
###################### and not overwrite any duplicate tags
######################
##########################################################################################
# Get all Resource Groups
$ResourceGroups = Get-AzureRmResourceGroup
foreach ($Group in $ResourceGroups) {
$group = Get-AzureRmResourceGroup Name $Group.ResourceGroupName
if ($null -ne $group.Tags) {
$resources = Get-AzureRmResource ResourceGroupName $group.ResourceGroupName
foreach ($r in $resources) {
$resourcetags = (Get-AzureRmResource ResourceId $r.ResourceId).Tags
if ($resourcetags) {
foreach ($key in $group.Tags.Keys) {
if (-not($resourcetags.ContainsKey($key))) {
$resourcetags.Add($key, $group.Tags[$key])
}
}
Set-AzureRmResource Tag $resourcetags ResourceId $r.ResourceId Force
}
else {
Set-AzureRmResource Tag $group.Tags ResourceId $r.ResourceId Force
}
}
}
}

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s