# My Quest To Finding the Perfect AWS Resource Naming Scheme

## 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.

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">If you wish to skip to the final recommended naming scheme, scroll down to the <strong>Adding my own tweaks for use in AWS </strong>section.</div>
</div>

## 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](https://aws.amazon.com/blogs/) and [AWS Prescriptive Guidance](https://aws.amazon.com/prescriptive-guidance/), or learn something new from [AWS Workshops](https://workshops.aws/). 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](https://d1.awsstatic.com/whitepapers/aws-tagging-best-practices.pdf) 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](https://docs.aws.amazon.com/whitepapers/latest/tagging-best-practices/tagging-best-practices.html) 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](https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/resource-naming) 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](https://stepan.wtf/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](https://stepan.wtf/cloud-naming-convention/).

* 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](https://cloud.google.com/compute/docs/naming-resources), but it is applicable also to [Azure](https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/resource-name-rules) and [AWS](https://stackoverflow.com/questions/46052869/what-are-the-most-restrictive-aws-resource-name-limitations-e-g-characters-and).
    

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](https://help.sap.com/docs/SOFTWARE_LOGISTICS_TOOLSET_CTS_PLUG-IN/05c12df5b54849c49940a14bc089d8b4/63a30a4ac00811d2851c0000e8a57770.html) 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](https://gist.github.com/cmawhorter/80bf94f12bf7516d50a7d61ed28859d3) 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](https://docs.aws.amazon.com/AmazonS3/latest/userguide/aws-usage-report-understand.html) 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:

| 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](https://en.wikipedia.org/wiki/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](https://registry.terraform.io/modules/cloudposse/label/null/latest) 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](https://developer.hashicorp.com/terraform/language/meta-arguments/for_each).

I also discovered that Azure provides an [Azure Naming module](https://github.com/Azure/terraform-azurerm-naming) 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](https://blog.avangards.io/) for more AWS and DevOps topics, and let me know what you'd like to learn more about!
