The primary intent of having a naming convention for Azure resources is to be able to identify essential information about a resource, for example:

  • related service or product for the resource;
  • resource type;
  • role of the resource or resource identifier used to differentiate between multiple instances of the same resource;
  • environment, etc.

Many organizations tend to adopt some variation of the Microsoft-suggested naming recommendations. If you haven’t reviewed them yet, I strongly encourage you to do. However, please be mindful and treat those naming patterns as suggestions and not strict rules. Picking them up without a second thought might not reflect the way your organization operates Azure services.

If you haven’t implemented a naming convention in your Azure environment, now is a good time to review the following naming patterns, which can be a good starting point on your cloud journey.

Generic Naming Rule

The general convention I suggest for naming your Azure resources when you don’t have any specific requirements is the following:

<product name>-<type of service abbreviated> [-<environment>][-<identifier>]

Where:

  • product name: product, application, service or platform;
  • type of service abbreviated: an abbreviation identifying Azure service type (see the list of sample abbreviations below);
  • environment (optional): environment name, e.g., production (prd), development (dev), testing (qa) or staging (stg);
  • identifier (optional): role of the resource or resource identifier used to differentiate between multiple instances of the same resource.
Why put the application name first and not the resource type? From my practice, it improves the search experience on the Azure portal and when using Azure PowerShell or CLI. Usually, when you are looking for a particular Azure resource, you first think of an application you work with and then of the resource type. Besides, people remember name patterns and tend to type names from the start. For example, when you have some resource name like ‘rg-myapp1’ and start typing ‘rg’ in the search box on the portal, you are likely to get the list of random resource groups first, which can be quite long. Then you need to continue typing to limit the results to a specific application. The console experience is similar – you need to type ‘*myapp1*’ or ‘rg-myapp1*’ when you could have saved your keystrokes and just typed ‘myapp1*’ to limit your search at the initial step to the resource of your application only. That change in the naming pattern might not seem like a big deal, but it can save your organization a lot of time, considering how often people search for a particular resource.

Use lowercase letters and numbers only in resource names. Spaces and special characters, except for hyphens, should not be used, as there are many cases when Azure resource restrictions limit their use. Also, because of those restrictions (resource name length), all the abbreviations and codes should be as short as possible to leave more room for using meaningful product/application names.

The kebab-case format should be used whenever possible. Hyphens can be removed for services where only alphanumeric characters are allowed, e.g., Storage accounts.

As most resource names are case-insensitive, using Camel case to save on delimiters like hyphens can lead to worse readability and more errors. Dots, underscores and spaces are not allowed for most of the resources. However, many second-level resources don’t have the same limitations as parent ones, and you can use more human-readable names for them.

Some resources might need to use the same name in multiple resource groups, and those might not have the <environment> suffix, which is optional, appended at the end of the name. The same is true for the optional <identifier> suffix.

Optional name parts should be consistent across an entire subscription. For example, if you choose to omit the <environment>part for a subscription, you should do the same for the resource groups and resources in it.

You might wonder why I don’t include the resource location in its name, as suggested by Microsoft. Nowadays, many Azure resources can be moved between regions, which wasn’t possible in the past. Unfortunately, renaming a resource to include a new region code in its name is impossible. I’ve seen many cases when having the resource location name part becomes completely dysfunctional and misleading. One possible exclusion from this is having multi-regional deployments when you use the location name/code as the identifier part in the resource name to distinguish between instances deployed in different regions, as resource movements rarely happen in that deployment model.

Generally, your resource name should consist only of immutable properties. Any other property that can be changed, like location, SKU or service tier, should not be included in resource names. If such updatable properties are essential for your operation, it is best to use Azure tags for them.

If you are looking to enforce a naming convention in your environment, you can check on how to do it with Azure Policy.

Naming Convention

For a start, your naming convention for Azure resources might look like the following.

Subscriptions

Naming pattern:

<organization>-<portfolio>-sub[-<environment>]

Where:

  • organization: organization short name;
  • portfolio: department, team or product line/portfolio;
  • environment: (optional) environment name.

Examples:

  • contoso-digital-platform-sub-dev
  • contoso-digital-platform-sub-prd

Resource Groups

Naming pattern:

<product name>-rg[-<environment>][-<identifier>]

Where:

  • product name: product, solution, service or platform;
  • environment (optional): environment name;
  • identifier (optional): a unique identifier used to differentiate between multiple instances of the same application deployment to avoid naming collisions (more on this below). It should be scoped to the subscription containing your resource group.

Examples:

  • application-rg-dev
  • application-rg-prd

Resources

Naming pattern:

<product name>-<type of service abbreviated> [-<environment>][-<identifier>]

Where:

  • name parts follow the generic naming rule;
  • the unique identifier should be scoped to a resource group containing the resource.

Examples of naming for the most common abbreviations for Azure services

Resource type

Resource name abbreviation

Examples

API Management services

-apim-

application-apim-dev

App Service Functions apps

-func-

salesapp-func-qa

App Service Plans

-asp-

publicweb-asp-prd

App Service Web apps

-web-

publicweb-web-prd

Application Gateways

-agw-

publicweb-agw-prd

Application Insights

-ai-

publicweb-ai-qa

Application Security Groups

-asg-

connectapp-asg-qa

Application Service Environments

-ase-

landingpage-ase-prd

Automation Accounts

-aa-

monitoring-aa-prd

Availability Sets

-as-

partnertools-as-stg

Cache for Redis

-redis-

partnertools-redis-dev

CDN profiles

-cdn-

publicweb-cdn-prd

Cognitive Services accounts

-cogs-

salesapp-cogs-qa

Container Registry

*creg*

connectappcregcvhiyu5h2o5o

Cosmos DBs

-cos-

salesapp-cos-qa

Event Hubs namespaces

-eh-

connectapp-eh-qa

Gateway connections

-cn-

connectapp-cn-qa

Key Vaults

-kv-

publicweb-kv-prd

Load Balancers

-lb-

connectapp-lb-qa-frontend

Log Analytics workspaces

-la-

monitoring-la-prd

Logic apps

-lapp-

salesapp-lapp-qa

Machine Learning workspaces

-ml-

salesapp-ml-qa

Network Interfaces

-nic-

connectapp-nic-qa-01

Network Security Groups

-nsg-

connectapp-nsg-qa-backend

Notification Hub namespaces

-nh-

connectapp-nh-prd

Public IPs

-pip-

connectapp-pip-qa-02

Resource Groups

-rg-

application-rg-qa

Route tables

-rt-

connectapp-rt-qa-01

Search services

-srch-

bookingservice-srch-stg

Service Buses

-sbus-

bookingservice-sbus-stg

Service Principal

-spn-

publicweb-spn-prd

SQL Server Managed Instances

-sqlmi-

salesapp-sqlmi-qa

SQL Databases

-sql-

publicweb-sql-prd

Storage accounts

*st*

publicwebsttcvhiyu5h2o5o

Traffic Manager profiles

-tm-

applications-tm-prd

Virtual Machines

-vm-

connectapp-vm-qa-db

Virtual Network Gateways

-gw-

connectapp-gw-qa-01

Virtual Networks

-vnet-

connectapp-vnet-qa

Naming Collisions

Some resources in Azure must be named uniquely at the subscription scope or across all of Azure. It is common to run into naming collisions for these resources.

One solution to get around naming collisions is to use a unique string when creating a resource. A unique string is typically a short hash of one or more concatenated input strings, so the output is sufficiently random to avoid naming collisions. Appending a unique string to a resource will help ensure the name satisfies any uniqueness constraints a resource requires. Creating a resource via an ARM/Bicep template is one way to create such unique strings.

Unique string scoped to a subscription:

"[uniqueString(subscription().subscriptionId)]"

Unique string scoped to a resource group:

"[uniqueString(resourceGroup().id)]"

A unique string that is globally unique and different between resource groups:

"[uniqueString(subscription().subscriptionId,resourceGroup().id)]"

When you need to create a new unique name each time you deploy a template and don’t intend to update the resource, you can use the utcNow function along with uniqueString, for example:

"[concat(uniqueString(resourceGroup().id), utcNow())]"

You can use this approach to create unique names when you employ immutable infrastructure.

In conclusion

Please be aware that there is no single best approach for naming your Azure resources. The important point is that you need to have a naming convention and follow it for the sake of resource maintainability and operation. Consistency in naming your resources is the key to speaking the same language between the members of different teams in your organization. So, please treat this guide as lessons from experience rather than the ultimate truth. If something doesn’t work for you, you likely need to revisit it and adjust to your needs.

What naming patterns and anti-patterns have you encountered in your work with Azure? What parts of resource naming were the most debatable in your teams? Please share your experience in the comments section 👇