My Quest To Finding the Perfect AWS Resource Naming Scheme

Anthony WatAnthony Wat
8 min read

Introduction

There are only two hard things in Computer Science: cache invalidation and naming things. -- Phil Karlton

I am sure that you've seen this famous quote in pretty much any article about naming conventions, and this blog post is no exception because the quote resonates to my experience as a cloud consultant. In the field, what I often see is that clients with smaller AWS environment do not have a consistent naming scheme due to ad-hoc usages, while larger clients who are looking to improve governance have a hard time defining an agreeable naming convention in the organization. In many cases, I'd ask the clients for resource naming preferences during engagements and they would turn the question around asking us for recommendation.

So, it is imperative that I can readily provide a naming convention that works for most cases but can also be customized to client needs as necessary. This calls for some R&D for a prescriptive naming scheme, which I now share my experience with you.

💡
If you wish to skip to the final recommended naming scheme, scroll down to the Adding my own tweaks for use in AWS section.

Defining the requirements

In my mind, a good naming scheme should exhibit the following traits:

  • It must be standardized with a well-defined schema which ideally can be parsed.

  • It must facilitate easy sorting, filtering, and identification of resources.

  • It must capture key information about the resource, such as usage and location.

  • It must adhere to limits such as case and length imposed by the cloud provider.

With these requirements, I set forth to find the best convention for naming AWS resources.

In search for cloud provider guidance

One thing which I find AWS usually does better than other cloud providers is information development. You'll always find helpful literatures and design patterns from AWS Blog and AWS Prescriptive Guidance, or learn something new from AWS Workshops. It is thus logical to search for resource naming recommendations from these AWS resources. However, there is eerily little information from AWS on resource naming for some reason. The only literature I found is an archived whitepaper on tagging best practices that recommended a dot notation <account-name>.<resource-name>.<type> (for example, prod.public-az1.subnet) which frankly is not super descriptive. The current version of the whitepaper doesn't even include the naming convention! As someone who prefers to follow the canon, I found this to be quite odd.

Being a multi-cloud practitioner, I then looked towards the next contender, Microsoft Azure, to provide more official guidance on resource naming. Indeed, the Cloud Adoption Framework for Azure has a comprehensive page on this topic. The framework recommends the naming convention <resource-type>-<workload>-<environment>-<region>-<instance> (for example, pip-sharepoint-prod-westus-001), which is better because it captures more hints that describe the purpose of the resource. The article goes on to list the key naming components, strategies such as scoping and abbreviation, and numerous resource-specific examples with more variations for comparison. While there aspects I can nitpick on, such as the ordering of naming components and the padded instance suffix, the general dash-separated format makes a lot of sense. Thus I considered this naming convention to be my baseline.

Scouring the community for inspirations

I also did more research on the internet for additional inspirations. Most Google search results refer to web pages and forum discussions recommending different variations of naming format similar to that of the Azure CAF, which is a good sign to being on the right track. That being said, I found one blog post named Cloud Naming Convention by Stepan Stipl to be especially thoughtful. Although the naming convention was developed for Google Cloud, it is very much applicable to other clouds. Stefan recommends the naming convention <prefix>-<project>-<env>-<resource>-<location>-<description>-<suffix> with the following schema:

ComponentDescriptionRequiredConstraints
prefixFixed prefixYes[a-z][a-z0-9]{3}
projectProject nameYes[a-z0-9]{4-10}
envEnvironmentYes[a-z], from enum
resourceResource typeYes[a-z]{3}, from enum
locationResource locationNo[a-z0-9]{1,6}
descriptionAdditional descriptionNo[a-z0-9]{1,20}
suffixRandom suffixNo[a-z0-9]{4}

For details about the naming components, please read Stepan's blog post.

  • VPC: ste-blog-p-cne-primary

  • Subnet: ste-blog-p-csn-euwe1-primary

There is so much I like about this naming convention:

  • The format is lean and concise thanks to length limits and optional components.

  • Most important information is incorporated into the naming convention.

  • The components are ordered from general to specific, which helps with sorting and identifying resources just by eyeballing.

  • The length limits are compatible with that of resources for all cloud providers. The naming convention caters mostly to the limit of 63 characters for Google Cloud, but it is applicable also to Azure and AWS.

And so I adopted this naming convention as my new baseline.

Adding my own tweaks for use in AWS

What remains is to tweak the baseline from Stepan so that it works better for AWS resources. Albeit opinionated, here are the changes I made:

  • Consider prefix to be optional, since it's not super useful in common use cases.

  • Generalize project to also identify workload, application, or general usage. This allows one to quickly identify resources by category.

  • Allow a handful of characters for env , such as dev|qas|prd for a three-letter convention (SAP folks may recognize this three-system landscape naming) or dev|test|prod for a slightly more spelled-out variation, for better readability.

  • Use a short, common-sense name while referencing resource type in ARNs as needed for resource. ARNs typically have a service segment and a resource-type segment - see this GitHub gist courtesy of Cory Mawhorter for a list of example. For example, I would use sg for security groups and ssmdoc for SSM documents.

  • Use region abbreviation for location and combine it with an AZ suffix (a to f) for more efficient use of name real estate. I use this page from the Amazon S3 User Guide as the official source for the region abbreviations. For example, I would use use1a to represent the us-east-1 region's first AZ.

The resulting naming convention is <prefix>-<usage>-<env>-<resource>-<location>-<description>-<suffix> but with an updated schema as follows:

ComponentDescriptionRequiredConstraints
prefixFixed prefixNo[a-z][a-z0-9]{3}
usageProject, workload, application, or general usageYes[a-z0-9]{4,10}
envEnvironmentYes[a-z]{1,5}, from enum
resourceResource typeYes[a-z0-9]{1,12}
locationResource location (region + AZ)No[a-z0-9]{1,5}
descriptionAdditional descriptionNo[a-z0-9]{1,20}
suffixRandom suffixNo[a-z0-9]{4}

Here are a few examples of naming AWS resources using this scheme:

  • VPC: shrsvcs-prod-vpc-use1

  • Subnet: shrsvcs-prod-subnet-use1a-private

  • EC2: ecommerce-dev-ec2-usw1a-web

  • RDS: app-stg-rds-cac1-postgres-wp

The limits and special cases

While the naming convention is applicable to most resources, there are a few outliers which require different naming. Here are some cases that I tend to follow existing convention from AWS instead:

  • IAM resources are generally named by AWS in camel case with a descriptive name such as IAMRoleForReachabilityAnalyzerCrossAccountResourceAccess.

  • CloudWatch log groups are named in segments separated by / , such as /aws/clientvpn/networking-prod-clientvpn-cac1. Similar naming is employed for other resources such as AWS Secrets Manager secrets or SSM parameters.

  • S3 bucket names must be globally unique, thus I would add prefix using the company name abbreviation and suffix using the AWS account ID, for example, avg-app-prod-s3-use1-webassets-111111111111 .

This list is by no means exhaustive and you may find other cases that warrant a deviation from the general naming convention.

Sidebar: Terraform modules that generate standard resource names

During my research, I came across the Terraform null label module that facilitates generation of consistent names and tags for resources. The naming convention is component-based and can be customized to match the recommended scheme above. This module is cloud agnostic and seems quite popular. Although the usage is clunky as one module definition is required per resource to be named or tagged, you can probably simplify it using the for_each meta-argument.

I also discovered that Azure provides an Azure Naming module as a helper to keep consistency on your resources names for Terraform. I am not sure how it fares in practice, but I am sharing this in case anyone is interested.

Summary

I have since used this custom naming convention on several AWS landing zone and migration/modernization projects with success. Clients appreciated a prescriptive naming convention that is logical, easy to follow, and often better than their existing scheme that was either defined in haste or inherited from their on-premises environments.

That being said, it is important to recognize that there is no one size that fits all, and you may have unique requirements that necessitates further customization. So long as you have a naming convention that is standardized and captures important metadata, it is as good as any other. Along with a good tagging strategy, a sensible resource naming convention will improve the governance and management of your AWS resources.

I hope that you find this blog post helpful and can adopt the suggested resource naming convention for your resource on AWS and even other cloud providers. Be sure to check out my other blog posts for more AWS and DevOps topics, and let me know what you'd like to learn more about!

2
Subscribe to my newsletter

Read articles from Anthony Wat directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Anthony Wat
Anthony Wat