Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(core): CDK creates unsupported list outputs from cross-stack references #21682

Open
gshpychka opened this issue Aug 19, 2022 · 2 comments
Open
Assignees
Labels
@aws-cdk/core Related to core CDK functionality bug This issue is a bug. effort/medium Medium work item – several days of effort p1

Comments

@gshpychka
Copy link
Contributor

gshpychka commented Aug 19, 2022

Describe the bug

When doing cross-stack references that point to a list value, CDK creates a CfnOutput with the list as its value. Cloudformation does not support outputting list values - it only supports strings. So this fails either during synth (if you explicitly pass a list), or during template validation (if you do a cdk.Fn.select and pass that to another stack).

Expected Behavior

Cross-stack references with list values work properly

Current Behavior

Cross-stack references with list values generate a synth-time error when passed explicitly:
jsii.errors.JSIIError: Resolution error: Resolution error: Found an encoded list token string in a scalar string context. Use 'Fn.select(0, list)' (not 'list[0]') to extract elements from token lists...
or a deploy-time validation error when doing a cdk.Fn.select:
Template format error: The Value field of every Outputs member must evaluate to a String.

Reproduction Steps

Here's a repro that produces both the synth-time and deploy-time errors. Uncomment ConsumerSynthTimeError to get a synth-time error.

from aws_cdk import aws_ec2 as ec2, aws_ssm as ssm
import aws_cdk as cdk
from constructs import Construct

app = cdk.App()

class Producer(cdk.Stack):
    def __init__(self, scope: Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        vpc = ec2.Vpc(self, "vpc")
        self.endpoint = ec2.InterfaceVpcEndpoint(
            self,
            "endpoint",
            vpc=vpc,
            service=ec2.InterfaceVpcEndpointAwsService.SECRETS_MANAGER,
        )
        self.single_dns_entry = cdk.Fn.select(0, self.endpoint.vpc_endpoint_dns_entries)

class ConsumerSynthTimeError(cdk.Stack):
    def __init__(
        self, scope: Construct, id: str, vpc_endpoint_dns_entries: list[str], **kwargs
    ) -> None:
        super().__init__(scope, id, **kwargs)

        ssm.StringListParameter(
            self, "parameter", string_list_value=vpc_endpoint_dns_entries
        )

class ConsumerDeployTimeError(cdk.Stack):
    def __init__(
        self, scope: Construct, id: str, vpc_endpoint_dns_entry: str, **kwargs
    ) -> None:
        super().__init__(scope, id, **kwargs)

        ssm.StringParameter(self, "parameter", string_value=vpc_endpoint_dns_entry)

producer = Producer(app, "producer")

# ConsumerSynthTimeError(
#     app,
#     "consumerSynthTime",
#     vpc_endpoint_dns_entries=producer.endpoint.vpc_endpoint_dns_entries,
# )

ConsumerDeployTimeError(
    app,
    "consumer",
    vpc_endpoint_dns_entry=producer.single_dns_entry,
)

app.synth()

Possible Solution

cdk.Fn.select should be placed in the producer stack instead of the consumer, and the result should be passed the output.

In cases where a whole list has to be passed, CDK could do a cdk.Fn.join in the producer, output that, and a cdk.Fn.split in the consumer.

Additional Information/Context

No response

CDK CLI Version

2.38.1

Framework Version

2.38.1

Node.js Version

18.7.0

OS

Linux

Language

Python

Language Version

3.10

Other information

No response

@gshpychka gshpychka added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Aug 19, 2022
@github-actions github-actions bot added the @aws-cdk/core Related to core CDK functionality label Aug 19, 2022
@rix0rrr rix0rrr added effort/medium Medium work item – several days of effort p1 and removed needs-triage This issue or PR still needs to be triaged. labels Sep 2, 2022
@rix0rrr rix0rrr removed their assignment Sep 2, 2022
@comcalvi comcalvi self-assigned this Nov 7, 2022
mergify bot pushed a commit that referenced this issue Dec 8, 2022
Previously only strings could be referenced across stacks, due to a CloudFormation requirement that all `Output`s evaluate to strings. This PR allows string lists to be referenced across stacks, like [VpcEndpoint DnsEntries](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpoint.html#aws-resource-ec2-vpcendpoint-return-values), by wrapping the exports / imports in `Fn::Split`s and `Fn::Join`s. This does not work across environments.

This also makes `ssm.StringListParameter` use `Fn.split(value)` instead of `value.split()`.

This is part of the fix to #21682. Cross-env support will be added in a future PR.

Adds a new public method, `exportListValue()`, to the `Stack` class to avoid breaking changes.

Implementation requires adding type hints to `IResolvable` and modifying the codegen to populate them correctly.


----

### All Submissions:

* [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Unconventional Dependencies:

* [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies)

### New Features

* [x] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [x] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
brennanho pushed a commit to brennanho/aws-cdk that referenced this issue Dec 9, 2022
Previously only strings could be referenced across stacks, due to a CloudFormation requirement that all `Output`s evaluate to strings. This PR allows string lists to be referenced across stacks, like [VpcEndpoint DnsEntries](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpoint.html#aws-resource-ec2-vpcendpoint-return-values), by wrapping the exports / imports in `Fn::Split`s and `Fn::Join`s. This does not work across environments.

This also makes `ssm.StringListParameter` use `Fn.split(value)` instead of `value.split()`.

This is part of the fix to aws#21682. Cross-env support will be added in a future PR.

Adds a new public method, `exportListValue()`, to the `Stack` class to avoid breaking changes.

Implementation requires adding type hints to `IResolvable` and modifying the codegen to populate them correctly.


----

### All Submissions:

* [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Unconventional Dependencies:

* [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies)

### New Features

* [x] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [x] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
brennanho pushed a commit to brennanho/aws-cdk that referenced this issue Jan 20, 2023
Previously only strings could be referenced across stacks, due to a CloudFormation requirement that all `Output`s evaluate to strings. This PR allows string lists to be referenced across stacks, like [VpcEndpoint DnsEntries](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpoint.html#aws-resource-ec2-vpcendpoint-return-values), by wrapping the exports / imports in `Fn::Split`s and `Fn::Join`s. This does not work across environments.

This also makes `ssm.StringListParameter` use `Fn.split(value)` instead of `value.split()`.

This is part of the fix to aws#21682. Cross-env support will be added in a future PR.

Adds a new public method, `exportListValue()`, to the `Stack` class to avoid breaking changes.

Implementation requires adding type hints to `IResolvable` and modifying the codegen to populate them correctly.


----

### All Submissions:

* [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Unconventional Dependencies:

* [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies)

### New Features

* [x] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [x] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
brennanho pushed a commit to brennanho/aws-cdk that referenced this issue Feb 22, 2023
Previously only strings could be referenced across stacks, due to a CloudFormation requirement that all `Output`s evaluate to strings. This PR allows string lists to be referenced across stacks, like [VpcEndpoint DnsEntries](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpoint.html#aws-resource-ec2-vpcendpoint-return-values), by wrapping the exports / imports in `Fn::Split`s and `Fn::Join`s. This does not work across environments.

This also makes `ssm.StringListParameter` use `Fn.split(value)` instead of `value.split()`.

This is part of the fix to aws#21682. Cross-env support will be added in a future PR.

Adds a new public method, `exportListValue()`, to the `Stack` class to avoid breaking changes.

Implementation requires adding type hints to `IResolvable` and modifying the codegen to populate them correctly.


----

### All Submissions:

* [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Unconventional Dependencies:

* [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies)

### New Features

* [x] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [x] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
@comcalvi
Copy link
Contributor

We've fixed this in one region with #22873, but it doesn't work for cross-account / region.

@gshpychka
Copy link
Contributor Author

My issue was about CloudFormation outputs, so single-environment by definition. Not sure whether the new cross-env references are relevant here as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/core Related to core CDK functionality bug This issue is a bug. effort/medium Medium work item – several days of effort p1
Projects
None yet
Development

No branches or pull requests

3 participants