aws / aws/aws-cdk

CDK: NestedStack can produce invalid template when referencing parent stack parameters

Open
#35,402 1 comment 0 reactions 1 assignee Claimed by @dgandhi62 View on GitHub
@aws-cdk/core bug effort/medium p1
Dominant language
TypeScript
Stars
12.9k
Forks
4.6k
Avg merge
2d 3h
Merged PRs (30d)
83

Description

### Describe the bug

In a situation where VPC details need to be passed into a parent stack as parameters, a nested stack that relies on those parameters can synthesize an invalid template that includes a reference to a Logical ID that only exists in the parent stack. In this case that appears to occur in situations where some of those parameter details will be used in a CloudFormation resource that requires the values be stringified as JSON.

### Regression Issue

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

### Last Known Working CDK Library Version

_No response_

### Expected Behavior

The nested stack should _not_ include a `Custom::AWSCDKCfnJsonStringify` that it does not need, and should not attempt to reference a Logical ID from the parent stack.

### Current Behavior

In the test case I've attached, the `ChildStack` template ends up with 2 `Custom::AWSCDKCfnJsonStringify` resources. The 2nd one is used elsewhere in the template. But `"CdkJsonStringify1"` one is not used anywhere in the template and it also contains `"Ref": "PrivateSubnetIds"`, where `PrivateSubnetIds` is the verbatim name of the parameter of the parent stack. This makes the child stack fail to deploy due to invalid syntax.

```json
"CdkJsonStringify1": {
"Type": "Custom::AWSCDKCfnJsonStringify",
"Properties": {
"ServiceToken": {
"Fn::GetAtt": [
"AWSCDKCfnUtilsProviderCustomResourceProviderHandlerCF82AA57",
"Arn"
]
},
"Value": {
"Fn::Split": [
",",
{
"Ref": "PrivateSubnetIds"
}
]
}
},
"UpdateReplacePolicy": "Delete",
"DeletionPolicy": "Delete",
"Metadata": {
"aws:cdk:path": "ParentStack/ChildStack/CdkJsonStringify1/Default"
}
},
```

### Reproduction Steps

Run `cdk synth` on this app and inspect the child stack's template that is produced.

```py
import aws_cdk
import constructs

class ParentStack(aws_cdk.Stack):

vpc: aws_cdk.aws_ec2.IVpc

def __init__(self, scope: constructs.Construct, id: str) -> None:
super().__init__(scope, id)

private_subnet_ids = aws_cdk.CfnParameter(
self, "PrivateSubnetIds", type="String", default=""
)

availability_zones = aws_cdk.CfnParameter(
self, "AvailabilityZones", type="String", default=""
)

vpc_id = aws_cdk.CfnParameter(
self, "VpcId", type="String", default=""
)

self.vpc = aws_cdk.aws_ec2.Vpc.from_vpc_attributes(
self, "Vpc",
vpc_id=vpc_id.value_as_string,
private_subnet_ids=aws_cdk.Fn.split(",", private_subnet_ids.value_as_string),
availability_zones=aws_cdk.Fn.split(",", availability_zones.value_as_string),
)

ChildStack(self, "ChildStack")

class ChildStack(aws_cdk.NestedStack):
def __init__(self, scope: constructs.Construct, id: str) -> None:
super().__init__(scope, id)

parent = self.nested_stack_parent
assert parent is not None
assert isinstance(parent, ParentStack)

cluster = aws_cdk.aws_ecs.Cluster(
self, "Cluster",
vpc=parent.vpc
)

task_definition = aws_cdk.aws_ecs.FargateTaskDefinition(
self, "TaskDefinition",
)

task_definition.add_container(
"Container",
image=aws_cdk.aws_ecs.ContainerImage.from_registry("hello-world"),
)

aws_cdk.aws_stepfunctions.StateMachine(
self, "StateMachine",
definition_body=aws_cdk.aws_stepfunctions.DefinitionBody.from_chainable(
aws_cdk.aws_stepfunctions_tasks.EcsRunTask(
self, "RunTask",
integration_pattern=aws_cdk.aws_stepfunctions.IntegrationPattern.RUN_JOB,
cluster=cluster,
task_definition=task_definition,
launch_target=aws_cdk.aws_stepfunctions_tasks.EcsFargateLaunchTarget(
platform_version=aws_cdk.aws_ecs.FargatePlatformVersion.LATEST
),
)
)
)

if __name__ == "__main__":
app = aws_cdk.App()
ParentStack(app, "ParentStack")
app.synth()
```

### Possible Solution

_No response_

### Additional Information/Context

_No response_

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

2.146.0

### AWS CDK CLI version

2.1010.0 (build 6b421db)

### Node.js Version

22.12.0

### OS

MacOS

### Language

Python

### Language Version

_No response_

### Other information

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.