My Quest To Finding the Perfect AWS Resource Naming Scheme
Follow along as I recount my quest to finding ideas and best practices to craft the perfect AWS resource naming convention.
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.
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:
Component | Description | Required | Constraints |
prefix | Fixed prefix | Yes | [a-z][a-z0-9]{3} |
project | Project name | Yes | [a-z0-9]{4-10} |
env | Environment | Yes | [a-z], from enum |
resource | Resource type | Yes | [a-z]{3}, from enum |
location | Resource location | No | [a-z0-9]{1,6} |
description | Additional description | No | [a-z0-9]{1,20} |
suffix | Random suffix | No | [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 asdev|qas|prd
for a three-letter convention (SAP folks may recognize this three-system landscape naming) ordev|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 usesg
for security groups andssmdoc
for SSM documents.Use region abbreviation for
location
and combine it with an AZ suffix (a
tof
) 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 useuse1a
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:
Component | Description | Required | Constraints |
prefix | Fixed prefix | No | [a-z][a-z0-9]{3} |
usage | Project, workload, application, or general usage | Yes | [a-z0-9]{4,10} |
env | Environment | Yes | [a-z]{1,5}, from enum |
resource | Resource type | Yes | [a-z0-9]{1,12} |
location | Resource location (region + AZ) | No | [a-z0-9]{1,5} |
description | Additional description | No | [a-z0-9]{1,20} |
suffix | Random suffix | No | [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 andsuffix
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!