stepan.wtf
Thu, Oct 10, 2019 cloud / gcp / architecture / terraform

Cloud Naming Convention

Consistent naming strategy is important and should be an essential part of any cloud effort. Sadly it’s often overlooked. It might seem like a luxury when you run a few “pet” servers, but it quickly becomes critical as the number of managed resources grows. It is the first step in achieving even basic levels of consistency and prerequisite to establishing any sort of cloud governance.

After reading this article, you’ll hopefully know how to get from:

1
2
3
4
5
6
$ gcloud container clusters list \
    --format 'value(name)'
k8s-cluster
k8s-cluster
k8s-cluster
k8s-cluster

to something like:

1
2
3
4
5
6
$ gcloud container clusters list \
    --format 'value(name)'
ste-blog-p-kcl-euwe4-primary
ste-webshop-d-kcl-euwe4-primary
ste-webshop-p-kcl-euwe4-primary
ste-webshop-p-kcl-usce1-primary

The latter will quickly tell us what type of resources are we dealing with, to which project and environment they belong, where are they located and whether they’re functionally equivalent to each other.

Benefits

Consistent and descriptive naming of resources has many benefits:


I’m not quite sure when I first came across this quote, but it since became one of my favourites. Martin Fowler attributes it to Phil Karlton.

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

Main Properties

Good naming convention must provide clarity and work in both directions:

We’ll focus on how a naming convention for cloud-level resources should look like. GCP is used in our examples, but the concepts and strategies are generic and can be easily adapted to other cloud providers.

Naming Restrictions

When designing your naming convention, you should take into account limitations imposed by the cloud provider. Each resource comes with a set of naming restrictions. The rule of thumb is to keep it short and simple (use only letters and numbers for individual components, keep - as separator).

GCP limits name length for most of the resources to 62 or 63 characters, Project IDs are limited to 30. Resources must have unique names, either globally or within a given scope. Some resources have additional constraints to take into consideration (e.g. GCP Projects can’t be immediately deleted).

Global Naming Pattern

First we establish naming pattern that all directly managed resources should follow - Global Naming Pattern.

[prefix]-[project]-[env]-[resource]-[location]-[description]-[suffix]

ComponentDescriptionReq.Constraints
prefixFixed prefixlen 3, fixed
projectProject namelen 4-10, a-z0-9
env .Environmentlen 1, a-z, enum
resourceResource typelen 3, a-z, enum
locationResource locationlen 1-6, a-z0-9
descriptionAdditional descriptionlen 1-20, a-z0-9
suffixRandom suffixlen 4, a-z0-9

Let’s go over the individual components more in detail.

Fixed Prefix

This is a fixed value prefix used for all resources. Typically some form of abbreviation for your organization name.

Project Name

This is different from a GCP Project. Typically one Project will have multiple GCP Projects. We’re using flat hierarchy and Project serves as the main mechanism of organizing resources into groups. I like using flat hierarchy as it’s very universal and flexible to fit pretty much any organizational structure. You might consider replacing this with some other form of group (e.g. team, product), but in my experience it never quite works in the long term.

Environment

Resources belong to deployment environments. It’s beneficial to establish a common set of names used across your organization.

Resource Type

I’ve tried various mechanisms over the time to construct the abbreviation for resources - most consistent results are achieved if the names are based on the API resource names. Abbreviation of the given resource type. In GCP I tend to use three letters.

For larger and more frequently used APIs (e.g. Compute, Kubernetes) first letter stands for the API and the remaining two for the resource type. For APIs with fewer resources, it’s the other way around. I know this is not a completely deterministic rule, but this will always be a compromise to it short and usable.

Resource Location

Location is required when there’s a possibility to create a given resource in different locations.

Additional Description

A description used to distinguish between resources of the same type but different roles. For example a group of servers with a different purpose - frontend and backend. This should not be used to differentiate between multiple instances of the same purpose resource, use suffix instead.

It’s also beneficial to agree on generic keywords used for description, when there is no better, more specific, term available. This avoids many different names like main, core, common, this and similar. Often good strategy is to use the Latin ordinal sequence, i.e. primary, secondary, tertiary, etc.

Random Suffix

I typically use a 2-byte number represented in hexadecimal form

Examples

Let’s go over several full examples of how resources should be named based on the above established pattern.

All the examples use prefix ste and belong to Production (p) environment of project blog.

GCP Projects

Projects (and Folders) are considered resource containers for the purpose of this naming convention and therefore omit the resource part of the name.

You can notice GCP does this by default for projects created via console - e.g. rapid-depot-253717. Project IDs in GCP have to be globally unique and cannot be deleted immediately. This is unfortunate for automation, as you can’t create a project with the same name right after it has been deleted. And that’s why we include the unique random suffix part.

Folders: We don’t use GCP folders to organize projects. I generally believe that keeping it simple and flat is beneficial more often than not. However, if you want to further structure your resources, consider adding an additional component to your naming pattern, such as [org_group]. Folders can then follow [prefix]-[org-group] pattern. GCP also allows configuring Project Name. I recommend to set this to the same value as Project ID and forget about it. For all the practical purposes you’ll reference the Projects by their IDs.

GCP Projects will therefore be named following the [prefix]-[project]-[env]-[suffix] pattern.

xkcd - Permanence by Randall Munroe

Exceptions

There will always be exceptions where it’s not possible to follow the Global Naming Pattern (for example resource does not allow - in the name) or when it simply doesn’t make sense. A subset of the full pattern should be used if possible and all exceptions documented.

Service Accounts

Service accounts follow the [resource]-[description] pattern only, as the project is already included in the part after @ and therefore there’s no need to repeat that bit,

IAM and Groups

This is a complex topic, perhaps for another article, but you should establish a naming convention for groups and a strategy on how to assign permissions. As a rule of thumb, never assign permissions directly to individuals, but to groups only.

Labelling Resources

You should also cover the use of labels (or tags). A good one is to add information to further categorize your resources, such as cost-center. Labels are also helpful in situations when you can’t manage resource names directly, but you can manage a set of labels that is propagated to the child resources (e.g. GKE Cluster labels or Instance Groups).

Do not duplicate information already contained in your naming convention (such as project) or create large numbers of unique labels with information that can be obtained from the objects themselves (such as creationTimestamp).

DNS

DNS naming convention across your infrastructure is again a larger topic, but you should definitely have one. A simple strategy can be creating a subdomain for each GCP project in the [project]-[env].<common_dns_domain> form. DNS records created for given resources should then follow the [resource]-[resource_location]-[description]-[suffix] part of the Global Naming pattern and therefore mirror the resource name.

This allows for easy subdomain delegation to individual GCP projects.

Summary

You should establish a consistent naming convention as one of the first things when you start using cloud or on a new project. It’s one of those things that are really easy to do in the beginning, but much more difficult to fix later on. And you’ll benefit from it every day.

The key to success with naming conventions is establishing them early on and ruthlessly following across your entire infrastructure. Automation helps a lot.

As usual, there’s no silver bullet and the actual naming convention should always be tailored to your environment. The main point is having one! And I hope this post gives you a head start.

Thanks for making it all the way till here. I wouldn’t blame you if you think by now that I have a serious OCD (and I probably do), but try to work in an environment with 120 Kubernetes clusters and every single one of them named simply just cluster!

Good luck on your cloud journey and I would love to hear about your experience with naming things. You can follow me on @stepanstipl.

References

  1. GCP - Creating and Managing Projects: https://cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects
  2. GCP - Best practices for enterprise organizations: https://cloud.google.com/docs/enterprise/best-practices-for-enterprise-organizations
  3. GCE API - REST reference: https://cloud.google.com/compute/docs/reference/rest/v1/
  4. GKE API - REST reference: https://cloud.google.com/kubernetes-engine/docs/reference/rest/
  5. GKE - Creating and managing labels: https://cloud.google.com/kubernetes-engine/docs/how-to/creating-managing-labels
  6. Azure - Recommended naming and tagging conventions: https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/considerations/naming-and-tagging
  7. AWS - Tagging Strategies: https://aws.amazon.com/answers/account-management/aws-tagging-strategies/