aws / aws/aws-cdk

(core): `Names.uniqueResourceName` should support generating multiple unique names from the same construct

Open
#36,606 1 comment 1 reaction 0 assignees View on GitHub
@aws-cdk/core effort/medium feature-request p2
Dominant language
TypeScript
Stars
12.9k
Forks
4.6k
Avg merge
2d 3h
Merged PRs (30d)
83

Description

### Describe the feature

`Names.uniqueResourceName` should support generating multiple different unique names when called multiple times with the same construct.

### Use Case

When creating multiple child resources that require unique physical names, I need to call uniqueResourceName before the child constructs are initialized. Since I can only pass the parent construct (this), I get the same name for all resources.

```ts
// These all return the same name
const name1 = Names.uniqueResourceName(this);
const name2 = Names.uniqueResourceName(this);

new SomeResource(this, 'SomeResource1', {
name: name1, // Need a unique name here
});

new SomeResource(this, 'SomeResource2', {
name: name2, // Need a different unique name here
});
```

Currently I have to manually construct names like ${Stack.of(this).stackName}-${this.node.id}-ABC, which loses the hash-based uniqueness guarantee that uniqueResourceName provides.

### Proposed Solution

Add an optional string parameter to `UniqueResourceNameOptions` that differentiates the generated name. For example, include it in the hash calculation so that different input strings produce different unique names while keeping the output length consistent.

E.g.

```ts
const name1 = Names.uniqueResourceName(this, { discriminator: '1' });
const name2 = Names.uniqueResourceName(this, { discriminator: '2' });
```

To meet maxLength constraint, the additional string might only be used to caluclate the hash component.

### Other Information

A workaround is to create empty constructs just for name generation:

```ts
const parent1 = new Construct(this, 'Parent1');
const parent2 = new Construct(this, 'Parent2');
const name1 = Names.uniqueResourceName(parent1);
const name2 = Names.uniqueResourceName(parent2);
```

This works but adds unnecessary constructs to the tree.

Or, use Lazy to defer name resolution until after child constructs are initialized:

```ts
const resource1 = new SomeResource(this, 'Resource1', {
name: Lazy.string({ produce: () => Names.uniqueResourceName(resource1, { maxLength: 40 }) }),
});
```

This requires using Lazy for every resource and is verbose.

### Acknowledgements

- [ ] I may be able to implement this feature request
- [ ] This feature might incur a breaking change

### AWS CDK Library version (aws-cdk-lib)

2.233.0

### AWS CDK CLI version

2.1100.1

### Environment details (OS name and version, etc.)

n/a

Contributor guide

Open the contributing guide

Research direction

Start at the Names.uniqueResourceName entry point and inspect UniqueResourceNameOptions to understand current name and hash generation. Define how a discriminator should produce distinct names while respecting maxLength, then add coverage showing repeated calls with different discriminators return distinct valid names.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
infrastructure
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.