Predictable naming of resources in CloudFormation

Using parameters to enable predictable lookup of resources

Table Of Contents

Today I Explained

Some AWS Services have naming uniqueness requirements, which are typically within an AWS Account Region, or within an AWS Account. Which you’ll typically find out about when encountering an error message that sounds similar to:

An error occurred: ServiceLogs - /aws/ecs/myapplicationsloggroup already exists.

One of the mechanisms to address this is by leveraging a unique value within the name suffix.

This isn’t always adopted, as the having unique resource names in this way requires some means to lookup the resources. In AWS, this will be implemented by queryable tags, but for cross-account references this may not always be viable.

This is why some infrastructure as code will adopt predictable named resources, using a set of static parameters. The names are then a composition of multiple these parameters that are passed into the stack.

In practice, this can look something like the following:

Parameters:
  Environment:
    Description: The name of the environment of the application
    Type: String
    Default: sandbox
  Variant:
    Description: The name of the variant of the application
    Type: String
    Default: myapplication 
## Example
# ${environment}-${application_variant}-resourcename

In this approach, static parameters are parameters that should never change after the stack is created, as changing these names will require resource destruction & creation.

As these conventions will be generic, these templates may make use of these static parameters in other ways (besides naming).

This has the outcome of making the names generated by a stack predictable based on the values of Environment and Variant. This can be desirable for cases where you are unable to define a mechanism for resource discovery.

A note on overloading meaning with static parameters

Parameters which are not expected to change can be risky with infrastructure as code. Especially if its not clear that changing the value of this parameter can cause significant modification to the resources of the stack.

However one of the more frustrating aspects of these static parameters is that over time they become overloaded with meaning. Since the names for them are very generic (Environment, Variant, etc), they often end up being used by conditional logic.

This couples the desired behaviour of the resource (how it should be configured), with how it is predictably named. Which may be a problem if you want 2 deployments with the same behaviour, but would result in a naming conflict.

A note on predictable lookups

Controlling the name of a resource, whether through a single parameter (ResourceName) or a combination of parameters, does allow for “discovering” a resource without needing to perform service discovery.

Although often this is due to development practices, rather than any particular implementation within the tooling.

Generally, this isn’t a pattern that is desirable to adopt. As the use of predictable weak-references has the negative consequence of infecting other designs within the system. It becomes necessary that other systems support this kind of predictable weak-references, imposing the naming convention onto other systems.

For each system that the infrastructure as code needs to know about (artifacts, secrets, domains), the need to be able to predictably lookup a resource becomes expected.