-
Notifications
You must be signed in to change notification settings - Fork 4.3k
fix(eks): looked up vpc causing premature validation errors for private subnets #33786
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
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #33786 +/- ##
=======================================
Coverage 82.38% 82.38%
=======================================
Files 120 120
Lines 6955 6955
Branches 1173 1173
=======================================
Hits 5730 5730
Misses 1120 1120
Partials 105 105
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
51d0172
to
83c35a0
Compare
if (privateSubnets.length === 0 && publicAccessDisabled) { | ||
// no private subnets and no public access at all, no good. | ||
throw new Error('Vpc must contain private subnets when public endpoint access is disabled'); | ||
if (!isLookedUpVPC && !isSubnetIdFilter) { |
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.
Note that LookedUpVpc
is always the type when using Vpc.fromLookup
. Its just that on the first synth, its values are dummy ones. The condition you are proposing here will make us skip the validation entirely, but actually we just want to skip it on the first synth, right?
So the condition needs to be based on the state of the VPC, not on its type.
There a couple other options to address this issue I think:
Subnet Selection
We already have a flag on SubnetSelection
that tells us whether a lookup is pending:
readonly isPendingLookup?: boolean; |
SubnetSelection
is used extensively in the EKS module. I don't have it all laid out, but can we leverage this to determine we don't need this validation?
incompleteSubnetDefinition
VpcBase
has a field indicating whether we should validate on subnets or not:
aws-cdk/packages/aws-cdk-lib/aws-ec2/lib/vpc.ts
Lines 459 to 462 in 2623e00
/** | |
* If this is set to true, don't error out on trying to select subnets | |
*/ | |
protected incompleteSubnetDefinition: boolean = false; |
Its not currently public though, but worst case, we can discuss making it so.
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.
didn't know about it, its pretty useful and solves this problem, refactored code to use isPendingLookup
, which returns false during dummyValue which i believe is due to dummy value being undefined under getValue (please correct me if the understanding is not correct), which results in LookedUpVpc
with incompleteSubnetDefinition to true
const attributes: cxapi.VpcContextResponse = ContextProvider.getValue(scope, {
provider: cxschema.ContextProvider.VPC_PROVIDER,
props: {
...overrides,
filter,
returnAsymmetricSubnets: true,
returnVpnGateways: options.returnVpnGateways,
subnetGroupNameTag: options.subnetGroupNameTag,
} as cxschema.VpcContextQuery,
dummyValue: undefined,
}).value;
new LookedUpVpc(scope, id, attributes ?? DUMMY_VPC_PROPS, attributes === undefined);
constructor(scope: Construct, id: string, props: cxapi.VpcContextResponse, isIncomplete: boolean)
this.incompleteSubnetDefinition = isIncomplete;
We don't need to make incompleteSubnetDefinition public as we can fetch the corresponding isPendingLookup
from selectSubnets method
@shikha372 Please also amend the PR title to briefly describe what the issue is. Avoid generic terms like "fixing". For example: |
c207f2e
to
e112c7f
Compare
diffAssets: false, | ||
}); | ||
|
||
app.synth(); |
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 guess this was intentional, but a note would be good to make your intention clear.
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.
actually this was not intentional, but i don't think its an issue as we don't need it anymore for integration tests.
const stack = new cdk.Stack(app, 'StackWithVpc', { | ||
env: { | ||
region: 'eu-west-1', | ||
account: '123456', |
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.
Can you explain how this successfully deploys? sorry I might just not be familiar with the magic that replaces/overrides this at deploy time, and why is this needed?
}); | ||
|
||
// Look up an existing VPC | ||
const vpc = ec2.Vpc.fromLookup(stack, 'Vpc', { |
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 really understand how this test works...the VPC you are looking up gets deployed in this same stack, so during lookup (synthesis), the VPC does not exist.
My guess is that the CLI just gives up and proceeds without fetching lookup values:
Can you confirm? You probably need to separate stacks here. Though I actually think an integ test is not really required here, the unit tests seem sufficient - can you elaborate on what additional value the integ tests give you?
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.
actually i was referring for existing VPC lookup test here , I tried to model it with two stacks but seems when we set enableLookups
in integ test it is not honoring the stack dependency and fails with the value not found.
// Add explicit dependency to ensure VPC stack is deployed first
clusterStack.addDependency(vpcStack);
new integ.IntegTest(app, 'aws-cdk-eks-cluster-private-endpoint-subnet-filter', {
testCases: [vpcStack],
// Test includes assets that are updated weekly. If not disabled, the upgrade PR will fail.
diffAssets: false,
enableLookups: true,
stackUpdateWorkflow: false,
});
But i;ve tested the validation with a sample CDK stack application linked to update aws-cdk module with fix;
export class CdkVpcAppStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const vpc = ec2.Vpc.fromLookup(this, 'Vpc', {
vpcName: 'aws-cdk-eks-cluster-private-endpoint-test',
isDefault: false });
new eks.Cluster(this, 'eks-cluster', {
vpc,
version: eks.KubernetesVersion.V1_31,
kubectlLayer: new KubectlV31Layer(this, 'KubectlLayer'),
endpointAccess: eks.EndpointAccess.PRIVATE,
vpcSubnets: [
{
// subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
subnetFilters: [
ec2.SubnetFilter.byIds(['subnet-XXXXX']),
],
}
]
});
}
}
aa1175e
to
dababbd
Compare
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.
(This review is outdated)
c93a02e
to
b2dc787
Compare
✅ Updated pull request passes all PRLinter validations. Dismissing previous PRLinter review.
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.
Wondering if we should also perform below validation here only if there is no pending lookups? Is it applicable?
if (placeClusterHandlerInVpc && privateSubnets.length === 0) {
throw new Error('Cannot place cluster handler in the VPC since no private subnets could be selected');
}
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.
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.
LGTM
addressed requested changes and reviewed with abstractions team for approval
Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
@Mergifyio update |
☑️ Nothing to do
|
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 main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
Comments on closed issues and PRs are hard for our team to see. |
Issue # (if applicable)
Related to one of the related issue for EKS and VPC in #22025 .
Reason for this change
Currently EKS cluster with private endpoint access fails during
cdk synth
operation for a lookedup VPC.investigating further into lookup implementation, the VPC id is first populated through some dummy values including the one for private subnets :
But there are no dummy values defined for the case of privatesubnetIds :
which results in return of filtering by IDs option as a null object until the values are fully resolved.
Reference code: https://github.com/aws/aws-cdk/blob/main/packages/aws-cdk-lib/aws-ec2/lib/vpc.ts#L2705
Description of changes
using existing field
isPendingLookup
in the SubnetSelection which is being set on the basis of this.incompleteSubnetDefinition = isIncomplete; whereisIncomplete
is set to false during first pass of cdk synth.So during first synth operation, validation will be skipped.
Describe any new or updated permissions being added
NA
Description of how you validated changes
Added unit test and integration test
Checklist
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license