-
Notifications
You must be signed in to change notification settings - Fork 4k
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): Vpc.fromVpcAttributes
using list tokens now throws errors
#11945
Comments
Wanted to open up this issue right now :-) None of my projects work with cdk 1.77 got exactly the same behaviour ... i added some debug output tu the core function
and ended up with an error message like:
please fix this, want to use cdk 1.77 because auf WEB_IDENTITY_TOKEN_FILE Credentials, but right now its unusable :-/ |
@Markus7811 I was able to work around this by importing the route tables IDs as well. This silences the warning, and prevents it from triggering the check. That could be an option for you as well if that data is available to you. |
good point ... testing it out :-) Main Problem ... the errormessage tells me that it's token 202 - but i don't have any idea what resource or import is causing this. |
Thanks for the reproduction steps @bf-sodle , but the code you pasted doesn't do it for me. I'm also going to need details on how you're USING the vpc. |
I figured it out, that this line is causing (my) problems (importing subnets with id only): aws-cdk/packages/@aws-cdk/aws-eks/lib/cluster.ts Line 1642 in 3530e8c
But the code causing this issue is: aws-cdk/packages/@aws-cdk/aws-ec2/lib/vpc.ts Line 1934 in 3530e8c
|
Honestly, because of the way the CDK works, You must have been getting infrastructure that was only using the first AZ/SubnetId of your list, right? I mean, it could be done if you tell us how many elements there will be in the list, but not automatically. |
Vpc.fromVpcAttributes
using list tokens now throws errors
Since the |
It was working ... i was using it with ssm parameter and fn.split to get an array ... (the parameter was written joining the subnetids with ",") |
Can you show me some code of how you were using that Vpc imported in that way though? With what kind of resource(s) were you using it? |
of course :-) As written above, I import eks clusters from ssm ... this.clusterRef = eks.Cluster.fromClusterAttributes(this, id, {
clusterName: props.clusterName,
vpc: ec2.Vpc.fromVpcAttributes(this, 'Vpc', {
availabilityZones: ssm.StringListParameter.fromStringListParameterName(this, 'VpcAvailabilityZonesSsm', `/eks/${props.clusterName}/EksClusterRef/VpcAvailabilityZones`).stringListValue,
vpcId: vpcId,
}),
kubectlRoleArn: ssm.StringParameter.fromStringParameterName(
this,
'KubectlRoleArnSsm',
`/eks/${props.clusterName}/EksClusterRef/KubectlRoleArn`,
).stringValue,
kubectlSecurityGroupId: ssm.StringParameter.fromStringParameterName(
this,
'KubectlSecurityGroupIdSsm',
`/eks/${props.clusterName}/EksClusterRef/KubectlSecurityGroupId`,
).stringValue,
kubectlLayer: lambda.LayerVersion.fromLayerVersionArn(
this,
'KubectlLayer',
ssm.StringParameter.fromStringParameterName(
this,
'KubectlLayerSsm',
`/eks/${props.clusterName}/EksClusterRef/KubectlLayer`,
).stringValue,
),
clusterCertificateAuthorityData: ssm.StringParameter.fromStringParameterName(
this,
'ClusterCertificateAuthorityDataSsm',
`/eks/${props.clusterName}/EksClusterRef/ClusterCertificateAuthorityData`,
).stringValue,
clusterEncryptionConfigKeyArn: ssm.StringParameter.fromStringParameterName(
this,
'ClusterEncryptionConfigKeyArnSsm',
`/eks/${props.clusterName}/EksClusterRef/ClusterEncryptionConfigKeyArn`,
).stringValue,
clusterSecurityGroupId: ssm.StringParameter.fromStringParameterName(
this,
'ClusterSecurityGroupIdSsm',
`/eks/${props.clusterName}/EksClusterRef/ClusterSecurityGroupId`,
).stringValue,
openIdConnectProvider: openIdConnectProvider,
kubectlPrivateSubnetIds: cdk.Fn.split(',', ssm.StringParameter.fromStringParameterName(this, 'KubectlPrivateSubnetsStringSsm', `/eks/${props.clusterName}/EksClusterRef/KubectlPrivateSubnetsString`).stringValue),
kubectlEnvironment: {
http_proxy: ssm.StringParameter.fromStringParameterName(
this,
'KubectlEnvironmentHttpProxySsm',
`/eks/${props.clusterName}/EksClusterRef/KubectlEnvironmentHttpProxy`,
).stringValue,
https_proxy: ssm.StringParameter.fromStringParameterName(
this,
'KubectlEnvironmentHttpsProxySsm',
`/eks/${props.clusterName}/EksClusterRef/KubectlEnvironmentHttpsProxy`,
).stringValue,
no_proxy: ssm.StringParameter.fromStringParameterName(
this,
'KubectlEnvironmentNoProxySsm',
`/eks/${props.clusterName}/EksClusterRef/KubectlEnvironmentNoProxy`,
).stringValue,
},
}); This was working till 1.76, but not with 1.77 ... |
On our end, we're importing the entire VPC as described above. We're then able to create an auto-scaling group like so, and it seems to span both all private subnets as it should. const vpcId = cdk.Fn.importValue("myVpcId");
const availabilityZones = cdk.Fn.split(",", cdk.Fn.importValue("myAvailabilityZones"));
const publicSubnetIds = cdk.Fn.split(",", cdk.Fn.importValue("myPublicSubnetIds"));
const privateSubnetIds = cdk.Fn.split(",", cdk.Fn.importValue("myPrivateSubnetIds"));
const isolatedSubnetIds = cdk.Fn.split(",", cdk.Fn.importValue("myIsolatedSubnetIds"));
const vpc = ec2.Vpc.fromVpcAttributes(this, "importedVpc", {
vpcId,
availabilityZones,
publicSubnetIds,
privateSubnetIds,
isolatedSubnetIds,
});
const clusterAsg = new autoscaling.AutoScalingGroup(this, "ecs-ec2-asg", {
instanceType: ec2.InstanceType.of(instanceClass, instanceSize),
machineImage,
minCapacity,
maxCapacity,
desiredCapacity,
vpc,
allowAllOutbound: false,
associatePublicIpAddress: false,
vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE },
role,
}); |
Blows my mind, because I feel like that wouldn't work. I will look into that. EDIT: Oh wait for ASG it might... |
I believe the magic is in using the ecsec2asgASGBC05D157:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
MaxSize: "4"
MinSize: "2"
DesiredCapacity: "2"
LaunchConfigurationName:
Ref: ecsec2asgLaunchConfig487A86FD
VPCZoneIdentifier:
Fn::Split:
- ","
- Fn::ImportValue: myPrivateSubnetIds |
I solved it for my use case by switching to VPC fromLookup instead of fromAttributes and switching from ssm.StringParameter.fromStringParameterName to ssm.StringParameter.valueFromLookup for the subnet part. Now the warnings are displayed and it works like it should ... |
…ime lists Even though using `Vpc.fromVpcAttributes()` using deploy-time lists like from `Fn.importValue()`s and `CfnParameters` was never really supposed to work, it accidentally did. The reason for that is: ```ts // Encoded list token const subnetIds = Token.asList(Fn.importValue('someValue')) // [ '#{Token[1234]}' ] // Gets parsed to a singleton `Subnet` list: const subnets = subnetIds.map(s => Subnet.fromSubnetAttributes({ subnetId: s })); // [ Subnet({ subnetId: '#{Token[1234]}' }) ] // This 'subnetId' is illegal by itself, and if yould try to use it for, // say, an ec2.Instance it would fail. However, if you treat this single // subnet as a GROUP of subnets: new CfnAutoScalingGroup({ subnetIds: subnets.map(s => s.subnetId) }) // [ '#{Token[1234]}' ] // And this resolves back to: resolve(cfnSubnetIds) // SubnetIds: { Fn::ImportValue: 'someValue' } ``` -------- We introduced an additional check in #11899 to make sure that the list-element token that represents an encoded list (`'#{Token[1234]}'`) never occurs in a non-list context, because it's illegal there. However, because: * `Subnet.fromSubnetAttributes()` logs the subnetId as a *warning* to its own metadata (which will log a string like `"there's something wrong with '#{Token[1234]}' ..."`). * All metadata is resolved just the same as the template expressions are. The `resolve()` function encounters that orphaned list token in the metadata and throws. -------- The *proper* solution would be to handle unparseable list tokens specially to never get into this situation, but doing that requires introducing classes and new concepts that will be a large effort and not be backwards compatible. Tracking in #4118. Another possible solution is to stop resolving metadata. I don't know if we usefully use this feature; I think we don't. However, we have tests enforcing that it is being done, and I'm scared to break something there. The quick solution around this for now is to have `Subnet.fromSubnetAttributes()` recognize when it's about to log a problematic identifier to metadata, and don't do it. Fixes #11945.
…ime lists (#12040) Even though using `Vpc.fromVpcAttributes()` using deploy-time lists like from `Fn.importValue()`s and `CfnParameters` was never really supposed to work, it accidentally did. The reason for that is: ```ts // Encoded list token const subnetIds = Token.asList(Fn.importValue('someValue')) // [ '#{Token[1234]}' ] // Gets parsed to a singleton `Subnet` list: const subnets = subnetIds.map(s => Subnet.fromSubnetAttributes({ subnetId: s })); // [ Subnet({ subnetId: '#{Token[1234]}' }) ] // This 'subnetId' is illegal by itself, and if yould try to use it for, // say, an ec2.Instance it would fail. However, if you treat this single // subnet as a GROUP of subnets: new CfnAutoScalingGroup({ subnetIds: subnets.map(s => s.subnetId) }) // [ '#{Token[1234]}' ] // And this resolves back to: resolve(cfnSubnetIds) // SubnetIds: { Fn::ImportValue: 'someValue' } ``` -------- We introduced an additional check in #11899 to make sure that the list-element token that represents an encoded list (`'#{Token[1234]}'`) never occurs in a non-list context, because it's illegal there. However, because: * `Subnet.fromSubnetAttributes()` logs the subnetId as a *warning* to its own metadata (which will log a string like `"there's something wrong with '#{Token[1234]}' ..."`). * All metadata is resolved just the same as the template expressions are. The `resolve()` function encounters that orphaned list token in the metadata and throws. -------- The *proper* solution would be to handle unparseable list tokens specially to never get into this situation, but doing that requires introducing classes and new concepts that will be a large effort and not be backwards compatible. Tracking in #4118. Another possible solution is to stop resolving metadata. I don't know if we usefully use this feature; I think we don't. However, we have tests enforcing that it is being done, and I'm scared to break something there. The quick solution around this for now is to have `Subnet.fromSubnetAttributes()` recognize when it's about to log a problematic identifier to metadata, and don't do it. Fixes #11945. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
|
@rix0rrr not sure if I'm missing something, but I'm still facing the same issue with const vpc = Vpc.fromVpcAttributes(scope, 'DefaultVpc', {
vpcId: ssm.StringParameter.valueForStringParameter(scope, `${basePath}/VpcId`),
availabilityZones: ssm.StringParameter.valueForStringParameter(scope, `${basePath}/AvailabilityZones`),
privateSubnetIds: ssm.StringParameter.valueForStringParameter(scope, `${basePath}/PrivateSubnetIds`),
privateSubnetRouteTableIds: ssm.StringParameter.valueForStringParameter(scope, `${basePath}/PrivateSubnetRouteTableIds`),
publicSubnetIds: ssm.StringParameter.valueForStringParameter(scope, `${basePath}/PublicSubnetIds`),
publicSubnetRouteTableIds: ssm.StringParameter.valueForStringParameter(scope, `${basePath}/PublicSubnetRouteTableIds`),
});
const cluster = new eks.Cluster(this, 'DetestadrCluster', {
vpc: vpc,
defaultCapacity: 0,
version: eks.KubernetesVersion.V1_18
}); Throwing the same error when resolving the template:
In addition, spinning an ECS cluster has no issues: const ecsCluster = new ecs.Cluster(this, 'EcsCluster', {
clusterName: `blablablaCluster`,
vpc: vpc,
}); |
…ime lists (aws#12040) Even though using `Vpc.fromVpcAttributes()` using deploy-time lists like from `Fn.importValue()`s and `CfnParameters` was never really supposed to work, it accidentally did. The reason for that is: ```ts // Encoded list token const subnetIds = Token.asList(Fn.importValue('someValue')) // [ '#{Token[1234]}' ] // Gets parsed to a singleton `Subnet` list: const subnets = subnetIds.map(s => Subnet.fromSubnetAttributes({ subnetId: s })); // [ Subnet({ subnetId: '#{Token[1234]}' }) ] // This 'subnetId' is illegal by itself, and if yould try to use it for, // say, an ec2.Instance it would fail. However, if you treat this single // subnet as a GROUP of subnets: new CfnAutoScalingGroup({ subnetIds: subnets.map(s => s.subnetId) }) // [ '#{Token[1234]}' ] // And this resolves back to: resolve(cfnSubnetIds) // SubnetIds: { Fn::ImportValue: 'someValue' } ``` -------- We introduced an additional check in aws#11899 to make sure that the list-element token that represents an encoded list (`'#{Token[1234]}'`) never occurs in a non-list context, because it's illegal there. However, because: * `Subnet.fromSubnetAttributes()` logs the subnetId as a *warning* to its own metadata (which will log a string like `"there's something wrong with '#{Token[1234]}' ..."`). * All metadata is resolved just the same as the template expressions are. The `resolve()` function encounters that orphaned list token in the metadata and throws. -------- The *proper* solution would be to handle unparseable list tokens specially to never get into this situation, but doing that requires introducing classes and new concepts that will be a large effort and not be backwards compatible. Tracking in aws#4118. Another possible solution is to stop resolving metadata. I don't know if we usefully use this feature; I think we don't. However, we have tests enforcing that it is being done, and I'm scared to break something there. The quick solution around this for now is to have `Subnet.fromSubnetAttributes()` recognize when it's about to log a problematic identifier to metadata, and don't do it. Fixes aws#11945. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Greetings, Is the LAMP stack scalable and durable example on on the example templates to provision application frameworks AWS page as good example of a template that can lead to the error when trying to resolve the subnets from the parameter? Such that if you set a default for the subnets as follows
Which is referenced in the AutoScaling resource by
When trying to resolve an item in the CfnAutoScalingGroup C.getVpcZoneIdentifier() list, using the template this.resolve(item) method, the error
And a solution is to replace the reference to the subnet parameter as
Or is there a coding solution for this and a way to recognize this problem? Regards |
When importing a VPC using outputs from another stack, if the route table IDs are not specified for each imported subnet, a warning is printed to the console, as expected:
This warning line is wrongly evaluated by the new "floating token" check introduced by #11899, and throws an error when synthesizing the stack:
Additionally, this line is "consumed" by the floating-token check and does not reach the console.
Reproduction Steps
What did you expect to happen?
VPC is imported without error, and the following warning line is printed to the console:
What actually happened?
No warning is printed about the route table, and the stack fails to synthesize with the following error:
Environment
Other
The floating token check should ignore CDK "logging" lines if possible.
This is 🐛 Bug Report
The text was updated successfully, but these errors were encountered: