(servicecatalog): ProductStackHistory changes last product version ID
- Dominant language
- TypeScript
- Stars
- 12.9k
- Forks
- 4.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 83
Description
### Describe the bug
`ProductStackHistory` is expected to keep older product versions as-is for consistency. But currently, the ID of last deployed product version changes by adding new version.
This becomes a blocker for users of Account Factory Customization (AFC) in AWS Control Tower because users may lost product version id that is used by AFC blueprint.
### Expected Behavior
Product version IDs should be immutable when adding a new version with `currentVersionLocked: true`.
### Current Behavior
The ID of last deployed product version changes by adding new version.
### Reproduction Steps
## Deploy v1
```typescript
import { App, Stack } from 'aws-cdk-lib';
import { CloudFormationProduct, ProductStack, ProductStackHistory } from 'aws-cdk-lib/aws-servicecatalog';
import { Construct } from 'constructs';
import { Queue } from 'aws-cdk-lib/aws-sqs';
const app = new App();
const stack = new Stack(app, "ServiceCatalog")
class MyProduct extends ProductStack {
constructor(scope: Construct, id: string) {
super(scope, id);
new Queue(this, "SCQueue1")
}
}
const productStackHistory = new ProductStackHistory(stack, 'ProductStackHistory', {
productStack: new MyProduct(stack, 'MyProduct'),
currentVersionName: 'v1',
currentVersionLocked: true,
});
new CloudFormationProduct(stack, 'Product', {
productName: 'MyProduct',
owner: 'Platform team at Example Company',
productVersions: [
productStackHistory.currentVersion(),
],
});
```

## Deploy v2 with no changes in ProductStack
```diff
@@ -15,7 +15,7 @@ class MyProduct extends ProductStack {
const productStackHistory = new ProductStackHistory(stack, 'ProductStackHistor>
productStack: new MyProduct(stack, 'MyProduct'),
- currentVersionName: 'v1',
+ currentVersionName: 'v2',
currentVersionLocked: true,
});
@@ -23,7 +23,7 @@ new CloudFormationProduct(stack, 'Product', {
productName: 'MyProduct',
owner: 'Platform team at Example Company',
productVersions: [
- // productStackHistory.versionFromSnapshot("v1"),
+ productStackHistory.versionFromSnapshot("v1"),
productStackHistory.currentVersion(),
],
});
```
`cdk diff`

Result of deployment

## Deploy v3 with changes in ProductStack
```diff
@@ -9,13 +9,13 @@ const stack = new Stack(app, "ServiceCatalog")
class MyProduct extends ProductStack {
constructor(scope: Construct, id: string) {
super(scope, id);
- new Queue(this, "SCQueue1")
+ new Queue(this, "SCQueue3")
}
}
const productStackHistory = new ProductStackHistory(stack, 'ProductStackHistor>
productStack: new MyProduct(stack, 'MyProduct'),
- currentVersionName: 'v2',
+ currentVersionName: 'v3',
currentVersionLocked: true,
});
@@ -24,6 +24,7 @@ new CloudFormationProduct(stack, 'Product', {
owner: 'Platform team at Example Company',
productVersions: [
productStackHistory.versionFromSnapshot("v1"),
+ productStackHistory.versionFromSnapshot("v2"),
productStackHistory.currentVersion(),
],
});
```
`cdk diff`

Result of deployment

### Possible Solution
_No response_
### Additional Information/Context
_No response_
### CDK CLI Version
2.68.0 (build 25fda51)
### Framework Version
2.68.0
### Node.js Version
v18.13.0
### OS
macOS Monterey 12.6.3
### Language
Typescript
### Language Version
4.9.5
### Other information
_No response_
Contributor guide
Research direction
Start with the ProductStackHistory behavior shown in the TypeScript v1–v3 reproduction and compare the generated cdk diff and deployment results. Trace how currentVersionLocked and versionFromSnapshot determine product version IDs; done means adding a new version without changing the ID of the previously deployed version.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, typescript
- Domain
- cloud, infrastructure
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100