Summary
Create meaningful service names that are unlikely to change over time and don’t replicate data in existing identifiers by composing the name from three elements that describe what the service does.
Service Name
SemServ = [Namespace] - [Domain | Entity] - [Role]
Where
[Namespace] - an optional word or string used to name an area or sub-system of the overall solution.
[Domain | Entity] - a noun describing the Domain OR primary entity the service operates on.
[Role] the main responsibility of the service in the domain, or what it does to, or for, the entity.
Use Service names as the root for naming other objects
Service Executable
[SemServ] : [SemVer]
Service Deployment Name
[SemServ] : [DeploymentStrategy]
Service Instance Name
[SemServ] : [DeploymentStrategy] : [InstanceId]
Introduction
As cloud-based systems mature, they enter a phase of continuous evolution - New services are added, old services are deprecated and retired, monoliths are decomposed, and deployments grow and spread over multiple regions and zones. Container orchestrators and serverless solutions accelerate this process by enabling services to come into existence on demand and disappear when not needed.
Those responsible for developing and operating large systems struggle to make sense of solutions that comprise hundreds of services with meaningless, obscure, and mismatched names. These solutions are a nightmare to operate and evolve. Any attempt at change must begin with an archeological expedition of unknown proportions to first identify the scope of the change, since the engineers who developed the system are often long gone.
To make matters worse, service names often comprise semantic elements that are no longer true - The names of organizations that no longer exist, deployment details that have changed, implementation technologies that have been retired, etc.
As a solution to this problem, we propose a simple set of rules that dictate how service names should be created. These rules are based on widespread common practices used by many of the companies we have worked with and avoid many of the problems we have encountered.
To make this approach work, you must identify your system’s sub-domains and entities and the actions performed upon these objects. You already know these terms; they are embedded in the language you use to describe your solution.
We named this system “Semantic Service Naming.” (SemServ) after Semantic Versioning (SemVer) because names created under this scheme convey meaning about the underlying purpose and function of the service, they deliberately avoid duplicating information stored elsewhere by PaaS and IaaS providers and do not include data that is likely to change causing service names to be out of date and confusing. This approach will not solve all problems with service names, but when combined with a good labeling scheme, will reduce or avoid many of the more common problems.
Semantic Service Naming Specification (SemServ)
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.
All service names MUST be made of at least two descriptive parts
First the [Domain | Entity]
Second, the [Role] that the service performs concerning the domain or entity.
Examples: Payment-Processor, Settlement-Distributor, Job-Scheduler, Ticket-Dispatcher. etc.In large solutions, where multiple services comprise a single sub-system, each service in the sub-system MAY be given a common prefix or [Namespace]. Namespaces SHOULD NOT be named after things that MAY change, like Organization Names, but rather SHOULD either be given arbitrary, easily remembered, distinctive names or names that describe the general functional area
Examples: Hydra, Periscope, Albion, Toolchain, Finance, etc.[Namespaces] MAY be grouped into themes to indicate some invariant commonality across sub-systems.
Examples: Norse Goddesses; Eir, Skuld, and Weth, for observability sub-systems or Old Rivers; Finke, Meuse, Rhine for messaging sub-systems.The [Namespace], [Domain | Entity], and [Role] MUST be separated by a “-”
Examples Finke-Message-Decorator, Toolchain-Pipeline-Scheduler, or just Payment-Processor if no namespace is required.Multipart component names MAY be used but each part MUST be indicated by a case change or by “_” and MUST NOT be separated by a “-”
Example PaymentFraud-Monitor, or Payment_Fraud-monitorA Semantic Service Name MUST uniquely identify a logical service within a System. The logical service is distinct from its various deployment strategies, instances, or versioned executables whose names SHOULD all be derived from the Service Name.
Examples: The Logical Service Hydra-Job-Scheduler may be used as the root for the following namesService Executable
[SemServ] : [SemVer]
Hydra-Job-scheduler:7.12.4Service Deployment Name
[SemServ] : [DeploymentStrategy]
Hydra-Job-Scheduler:Green
Hydra-Job-Scheduler:Blue
Hydra-Job-Scheduler:CanaryService Instance Name
[SemServ] : [DeploymentStrategy] : [InstanceId]
Hydra-Job-Scheduler:Green:0b22a22eec53b9321It is up to you to make sure you can tell the difference between different types of objects. For example, a list containing a mix of executables, deployments, and instances from the above examples may be confusing unless you know how to tell the difference between a SemVer, a DeploymentStrategy and an InstanceID. RegEx pattern matching can be useful in this regard.
Why use Semantic Service Naming
All services require names. Anyone who has worked on a large, successful SaaS solution can attest that there are many possible naming conventions, some useful, some not. The SemServ convention is designed to be simple and long-lasting, requiring little change over time, and acts as a foundation for naming many other concepts, such as deployments, executables, and instance names.
We believe a service name should describe what the service does and no more! Who owns the service, what technologies it implements, what resource type it is, how it is deployed, and what version it is are all important pieces of information, but they have no place in the service name. They have no place in the service name because they can usually be found elsewhere and are likely to change over the life of the service, and renaming services once they are deployed is so onerous that it is often avoided, resulting in confusion and much wasted time.
The name of a service should reflect its core purpose as this is unlikely to change over its life. SemServ is designed to avoid many problems and solve ONE - To provide a simple, useful way to name services that is unlikely to change over the life of the service.
FAQ
Why shouldn’t I put the account, region, or resource type in the service name?
Commercial IaaS and PaaS providers identify each resource with a URI. This URI is composed of useful information that can be extracted as needed. This information SHOULD NOT be included in the service name as it is redundant. Typically, resource Identifiers contain the region or location, the account or project, and the resource type and resource name or id. There is no need to duplicate this in the name, it’s already in the resource identifier. If any of these items change, then the resource identifier will change automatically and the service name or id can stay the same.
AWS identifies ALL resources with an Amazon Resource Name (ARN)
arn:partition:service:region:account-id:resource-type/resource-id
Azure identifies resources with an Azure Resource ID
/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{providerNamespace}/{resourceType}/{resourceName}
GCP identifies all resources with Resource Names
projects/project_id/locations/location_id/resourceType/resource_id
Or, for resources that are global or not tied to a specific location, the format might be simpler:
projects/project_id/resourceType/resource_id
In short. It is easier to learn how to fetch the URI for a resource than to change its name frequently.
What about Environments?
With environments, you have choices. Being able to easily tell the difference between a service in production or a service in a verification environment is important. There are several ways this can be achieved without embedding the information in the service name.
- Use different accounts or projects for each environment. This will have the effect of encoding the environment into the URI
- Use an environment tag. But make sure your deployment process ensures every deployed resource gets a tag. This is not as easy as it seems when resources are created and destroyed elastically.
- Add the environment to the service name if you must but remember to re-name each service when you deploy to a new environment.
What about the other data I currently encode into names?
The remaining semantic elements typically used by enterprises; Organizations, Customers, Projects, Products, Technologies etc. should be assigned to tags. Metadata tags are available from all the popular providers, AWS, GCP, Azure etc. There are limits on the number and complexity of tags these providers will support, so pick a few and design simple easily understood faceted or hierarchical taxonomies that your organization can manage effectively as they slowly change over time. Reapply tags whenever you deploy a service. You should also develop processes to update tags even when the service is not being deployed. For example, when a reorg happens in your enterprise and services change organizational ownership.
What if it’s only a temporary service?
Temporary services frequently become permanent or long-lasting. If you’re going to the trouble of creating a service, then give it a meaningful name.
ABOUT
The Semantic Service Naming specification was inspired by SemVer and was originally written by John R. Harris, cofounder of SPAN Digital.
If you’d like to leave feedback, please open an issue on GitHub