“There are two hard problems in computer science: naming things, cache invalidation, and off-by-one errors.”

It’s common when instantiating cloud resources to be working in a namespace that requires unique names. Sometimes that namespace is cloud-wide, and there’s a very good chance someone else somewhere has already created a my-test-app or similar.

The official Azure docs recommend numbering your instances. There are some hidden pitfalls to that approach; even the Azure docs note the complexity involved with left-zero-padding numbers when instantiating multiple resources.

Numbers, in this case, are just a specific example of a uniqueness token - a string more-or-less guaranteed to be unique across a name space that can be suffixed to a name. Like a shorter GUID, really, you just don’t need as many characters.

The thing with using numbers as a uniqueness token is that they carry some gotchas:

  • If they’re used in a fixed-width field in a naming scheme, you have the aforementioned padding and parsing you have to do
  • Numbers can imply ordinality even if they’re not intended to. If I have resources named { resource-001, resource-002, resource-003, resource-006, resource-007, resource-010 } what’s the next available token if I want to add another resource? Is it 004? 011? Something else?
  • If there was a resource named resource-004 at some point, is it okay for me to reuse that for a new resource even if it’s a new resource?
  • What if, like key vaults, there’s a soft delete policy and I can’t reuse that name?
  • Even if there’s no gaps in the sequence, figuring out the next available token when you want add more resources can be challenging

Another option is to use short, randomly generated strings of characters that have a very low probability of collisions. For example, the New-UniquenessToken function in this post spits out five character strings that look like this: tcrkp, dxscz, pfybt The function intentionally excludes characters like o, O, 0, g, q, l, 1 that can be easily confused with each other if you’re not using a programming font. In this case, given resources named { resource-dehar, resource-eybrz, resource-btxcz, resource-zekay, resource-pkary } I can easily add a new resource by generating a new token without having to worry about ordinality.

This approach does bring caveats of its own. In particular, if you want to instantiate a large number of resources using a stateful infrastructure-as-code tool - like Terraform - you need to use some kind of fixed random seed to ensure the tokens don’t vary every time you run the tool, destroying and recreating resources unnecessarily. That makes this approach better for the Immutable Infrastructure pattern and tools like Bicep that implement it.

As a side note for probability aficionados: the New-UniquenessToken has about a 1 in 1000 chance of producing a collision. That’s probably too high for production use.