-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
fix(core): toJsonString()
cannot handle list intrinsics
#13544
Conversation
The previous attempt at a fix missed one important case: the types of the values involved in the `{ Fn::Join }` expression didn't actually match up. They all needed to be strings, but the previous implentation just dropped list-typed values in there. Unfortunately, there is no way to do it correctly with just string manipulation in CloudFormation (`{ Fn::Join }` etc), so we'll have to resort to using a Custom Resource if we encounter list values. Actually fixes #13465.
toJsonString()
cannot handle liststoJsonString()
cannot handle list intrinsics
// But that has the unfortunate side effect that if `CFN_EVAL({ Ref: MyList }) == []`, then it would | ||
// evaluate to `[""]`, which is a different value. Since CloudFormation does not have arbitrary | ||
// conditionals there's no way to deal with this case properly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rix0rrr I think I found a way with a Fn::Join
on a Fn::Split
acting like a replace:
cdk.Fn.join('', cdk.Fn.split('""', myString)) // acts like a replace
For #13465 and the issue with the array of ENIs, it looks like that
[cdk.Token.asList(cdk.Fn.join('', cdk.Fn.split('""', cdk.Stack.of(stack).toJsonString(cdk.Fn.join('","', endpoint.vpcEndpointNetworkInterfaceIds)))))]
Gives the following CF
{
"Fn::Join": [
"",
[
"{\"action\":\"describeNetworkInterfaces\",\"service\":\"EC2\",\"parameters\":{\"NetworkInterfaceIds\":[",
{
"Fn::Join": [
"",
{
"Fn::Split": [
"\"\"",
{
"Fn::Join": [
"",
[
"\"",
{
"Fn::Join": [
"\\\",\\\"",
{
"Fn::GetAtt": [
"OtherEndpoint88C37F72",
"NetworkInterfaceIds"
]
}
]
},
"\""
]
]
}
]
}
]
},
"]},\"physicalResourceId\":{\"id\":\"physical-id\"},\"outputPath\":\"NetworkInterfaces.0.PrivateIpAddress\"}"
]
]
}
Successfully tested this with a GatewayVpcEndpoint
which has no ENIs and hence returns an empty list for the vpcEndpointNetworkInterfaceIds
attribute.
Even if it's really really ugly, it's better than a custom resource, right? WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EHRMAGERD
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are like a wizard.
A dirty wizard...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like it though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait no. This solution will break when presented with [""]
.
That value would successfully make it through the transformation initially and then be substituted away to []
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bu then maybe the CR is the right solution
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm also thinking about it... afraid nothing's to be done, as:
JOIN(<whatever>, []) == JOIN(<whatever>, [""]) == ""
Once we've JOINed, we've lost the ability to make the distinction between []
and [""]
... right?
(I'm starting to doubt myself now)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think there's a way to do it. You loose information after the first join:
[].join('","') === [''].join('","')
and the only "first operation" you can do on the array with CF is a Fn::Join
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK our comments crossed each other... I don't think it's possible in pure CF. This is sad 😢 .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IF ONLY we had a functional { Fn::If }
...
Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
The previous attempt at a fix missed one important case: the types of the values involved in the `{ Fn::Join }` expression didn't actually match up. They all needed to be strings, but the previous implentation just dropped list-typed values in there. Unfortunately, there is no way to do it correctly with just string manipulation in CloudFormation (`{ Fn::Join }` etc), so we'll have to resort to using a Custom Resource if we encounter list values. Actually fixes aws#13465. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
The previous attempt at a fix missed one important case: the types of the values involved in the `{ Fn::Join }` expression didn't actually match up. They all needed to be strings, but the previous implentation just dropped list-typed values in there. Unfortunately, there is no way to do it correctly with just string manipulation in CloudFormation (`{ Fn::Join }` etc), so we'll have to resort to using a Custom Resource if we encounter list values. Actually fixes aws#13465. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
The previous attempt at a fix missed one important case: the types of the values involved in the `{ Fn::Join }` expression didn't actually match up. They all needed to be strings, but the previous implentation just dropped list-typed values in there. Unfortunately, there is no way to do it correctly with just string manipulation in CloudFormation (`{ Fn::Join }` etc), so we'll have to resort to using a Custom Resource if we encounter list values. Actually fixes aws#13465. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
The previous attempt at a fix missed one important case: the types
of the values involved in the
{ Fn::Join }
expression didn't actuallymatch up. They all needed to be strings, but the previous implentation
just dropped list-typed values in there.
Unfortunately, there is no way to do it correctly with just string
manipulation in CloudFormation (
{ Fn::Join }
etc), so we'll haveto resort to using a Custom Resource if we encounter list values.
Actually fixes #13465.
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license