aws / aws/aws-cdk

aws-s3-assets : Upgrading from LegacyStackSynthesizer to DefaultStackSynthesizer with cross-stack reference causes UpdateFailed

Open
#23,879 3 comments 0 reactions 0 assignees View on GitHub
@aws-cdk/aws-s3-assets bug effort/medium p2 package/tools
Dominant language
TypeScript
Stars
12.9k
Forks
4.6k
Avg merge
1d 19h
Merged PRs (30d)
74

Description

### Describe the bug

When upgrading from the `LegacyStackSynthesizer` to the `DefaultStackSynthesizer`, cross-stack asset dependencies cause deployment to fail with the following exception:

`Export ProducingStack:ExportsOutputRefAssetParameters6547f4c9757e3c9a9d37d7a5d75004ce634cb9b01af7a7606412c36b947f248fS3BucketA01FB337B366B8FA cannot be deleted as it is in use by ConsumingStack
`

The issue of redeployment failing after removing generic cross-stack dependencies is described in #3414. In this specific case, CDK's legacy synthesizer creates an `AssetParameters` export in the producing stack so that it can be used in the consuming stack. However, the `DefaultStackSynthesizer` does not create this export. The result is that when upgrading from the `DefaultStackSynthesizer` to the `LegacyStackSynthesizer`, the deployment fails because the producing stack's export cannot be deleted while referenced by the consuming stack.

### Expected Behavior

Deployment succeeds when updating an app with cross-stack asset dependencies from the `LegacyStackSynthesizer` to the `DefaultStackSynthesizer`.

### Current Behavior

Deployment fails to update the producing stack

### Reproduction Steps

Define stack classes as follows:

```
import os

from constructs import Construct

from aws_cdk import (
App,
Stack,
CfnOutput,
Fn,
LegacyStackSynthesizer,
StackProps
)

from aws_cdk.aws_s3 import (
Bucket,
)

from aws_cdk.aws_s3_assets import (
Asset,
)

from aws_cdk.aws_lambda import (
Function,
Code,
Runtime
)

class ProducingStack(Stack):

def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)

bucket = Bucket(self, "My Bucket")
self.bucket = bucket

dirname = os.path.dirname(__file__)
asset = Asset(self, "MyImageAsset", path=os.path.join(dirname, "asset.png"))
self.asset=asset

class ConsumingStack(Stack):

def __init__(self, scope: Construct, construct_id: str, bucket, asset, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)

lambda_func = Function( self, "My Function", code=Code.from_inline("handler = lambda event, context : {}"), handler="index.handler", runtime=Runtime.PYTHON_3_7)
bucket.grant_read_write(lambda_func)

asset.grant_read(lambda_func)

app = App()
```

Deploy with stacks defined using `LegacyStackSynthesizer`:
```
producing_stack = ProducingStack(app, "ProducingStack", synthesizer=LegacyStackSynthesizer())
ConsumingStack(app, "ConsumingStack", producing_stack.bucket, producing_stack.asset, synthesizer=LegacyStackSynthesizer())
app.synth()
```

Deploy with stacks defined without synthesizer specified, defaulting to `DefaultStackSynthesizer`:
```
producing_stack = ProducingStack(app, "ProducingStack")
ConsumingStack(app, "ConsumingStack", producing_stack.bucket, producing_stack.asset)
app.synth()
```

### Possible Solution

_No response_

### Additional Information/Context

_No response_

### CDK CLI Version

2.61.0

### Framework Version

_No response_

### Node.js Version

v19.4.0

### OS

Same behavior on MacOS and AL2

### Language

Python

### Language Version

3.10.9

### Other information

_No response_

Contributor guide

Open the contributing guide

Research direction

Start with the LegacyStackSynthesizer and DefaultStackSynthesizer entry points and the aws_s3_assets.Asset cross-stack dependency in the provided Python reproduction. Synthesize and deploy the ProducingStack and ConsumingStack with each synthesizer, then verify that upgrading to DefaultStackSynthesizer completes without UpdateFailed or an in-use export deletion error.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, python
Domain
cloud, infrastructure
Issue type
Bug
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.