aws / aws/aws-cli

cloudformation deploy: timestamp-only ChangeSet name guarantees collision under concurrent invocations

Open Beginner friendly
#10,315 2 comments 0 reactions 0 assignees View on GitHub
bug cloudformation customization p3
Dominant language
Python
Stars
17.3k
Forks
4.6k
Avg merge
1d 10h
Merged PRs (30d)
18

Description

## Describe the bug

\`aws cloudformation deploy\` generates the ChangeSet name using only a Unix timestamp at 1-second precision:

\`\`\`python
# awscli/customizations/cloudformation/deployer.py:91-92
# Each changeset will get a unique name based on time
changeset_name = self.changeset_prefix + str(int(time.time()))
\`\`\`

Unlike the analogous issue in \`cloudfront\` (\`unique_string()\` — fixed in #10281) which had a 1-in-1,000,000 collision chance per second, this implementation has **no random component at all**. Two concurrent invocations within the same second generate **identical** ChangeSet names with 100% probability, causing the second to fail with \`AlreadyExistsException\`.

Related to #5435 (feature request to expose \`--change-set-name\`), which would serve as a workaround but does not address the root cause.

## Regression Issue

- [ ] Select this option if this issue appears to be a regression.

## Expected Behavior

\`aws cloudformation deploy\` always generates a unique ChangeSet name, regardless of how quickly or how many times it is invoked concurrently against the same stack.

## Current Behavior

When two invocations of \`aws cloudformation deploy\` target the same stack within the same second, both attempt to create a ChangeSet named (for example):

```
awscli-cloudformation-package-deploy-1747339200
```

The second invocation fails immediately:

```
An error occurred (AlreadyExistsException) when calling the CreateChangeSet
operation: ChangeSet [awscli-cloudformation-package-deploy-1747339200] already exists
```

The error is re-raised with no additional context, making it difficult to diagnose in CI/CD logs.

## Reproduction Steps

Run two simultaneous deploys against the same stack:

```bash
STACK=my-stack
TEMPLATE=template.yaml

aws cloudformation deploy --stack-name "$STACK" --template-file "$TEMPLATE" &
aws cloudformation deploy --stack-name "$STACK" --template-file "$TEMPLATE" &
wait
```

If both commands start within the same second (common in CI matrix jobs or parallel pipeline steps), one will fail with \`AlreadyExistsException\`.

## Possible Solution

Replace \`int(time.time())\` with \`uuid.uuid4()\`, which provides 122 bits of cryptographically random entropy and eliminates both the timestamp dependency and collision risk entirely. \`uuid\` is already part of the Python standard library.

\`\`\`python
import uuid

# Before
changeset_name = self.changeset_prefix + str(int(time.time()))

# After
changeset_name = self.changeset_prefix + str(uuid.uuid4())
\`\`\`

The resulting name (\`awscli-cloudformation-package-deploy-\`, ~73 chars) satisfies CloudFormation's ChangeSet naming constraint (alphanumeric + hyphens, max 128 chars). This is the same fix applied to \`cloudfront.unique_string()\` in #10281.

## Additional Information/Context

This affects CI/CD matrix builds and parallel pipeline stages that deploy the same stack concurrently. The comment on line 91 ("Each changeset will get a unique name based on time") reflects the intent but the implementation does not achieve uniqueness within the same second.

## CLI version used

aws-cli/2.x — reproducible across all versions; the timestamp-based naming has been present since the deploy command was introduced.

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

Reproducible on any OS/platform (Linux, macOS, Windows).

Contributor guide

Open the contributing guide

Research direction

Review awscli/customizations/cloudformation/deployer.py at lines 91-92 and trace how the deploy command creates its ChangeSet name. Reproduce the issue with two simultaneous aws cloudformation deploy invocations, then verify that concurrent deployments no longer generate the same name or fail with AlreadyExistsException.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, python
Domain
cli, cloud
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.