Skip to content

Commit

Permalink
fix(ec2): interface endpoints do not work with Vpc.fromLookup() (#1…
Browse files Browse the repository at this point in the history
…8554)

The validation was too eager, causing a validation error before
the actual lookup happened.

Add a property to `SelectedSubnets` to make it clear in consuming
code that validation shouldn't happen yet.

Fixes #17600.


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
rix0rrr authored Jan 20, 2022
1 parent b49b002 commit f55cd2b
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 2 deletions.
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-ec2/lib/vpc-endpoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ export class InterfaceVpcEndpoint extends VpcEndpoint implements IInterfaceVpcEn
const subnets = subnetSelection.subnets;

// Sanity check the subnet count
if (subnetSelection.subnets.length == 0) {
if (!subnetSelection.isPendingLookup && subnetSelection.subnets.length == 0) {
throw new Error('Cannot create a VPC Endpoint with no subnets');
}

Expand Down
12 changes: 12 additions & 0 deletions packages/@aws-cdk/aws-ec2/lib/vpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,17 @@ export interface SelectedSubnets {
* Whether any of the given subnets are from the VPC's public subnets.
*/
readonly hasPublic: boolean;

/**
* The subnet selection is not actually real yet
*
* If this value is true, don't validate anything about the subnets. The count
* or identities are not known yet, and the validation will most likely fail
* which will prevent a successful lookup.
*
* @default false
*/
readonly isPendingLookup?: boolean;
}

/**
Expand Down Expand Up @@ -430,6 +441,7 @@ abstract class VpcBase extends Resource implements IVpc {
internetConnectivityEstablished: tap(new CompositeDependable(), d => subnets.forEach(s => d.add(s.internetConnectivityEstablished))),
subnets,
hasPublic: subnets.some(s => pubs.has(s)),
isPendingLookup: this.incompleteSubnetDefinition,
};
}

Expand Down
21 changes: 20 additions & 1 deletion packages/@aws-cdk/aws-ec2/test/vpc-endpoint.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { AnyPrincipal, PolicyStatement } from '@aws-cdk/aws-iam';
import * as cxschema from '@aws-cdk/cloud-assembly-schema';
import { ContextProvider, Fn, Stack } from '@aws-cdk/core';
// eslint-disable-next-line max-len
import { GatewayVpcEndpoint, GatewayVpcEndpointAwsService, InterfaceVpcEndpoint, InterfaceVpcEndpointAwsService, InterfaceVpcEndpointService, SecurityGroup, SubnetType, Vpc } from '../lib';
import { GatewayVpcEndpoint, GatewayVpcEndpointAwsService, InterfaceVpcEndpoint, InterfaceVpcEndpointAwsService, InterfaceVpcEndpointService, SecurityGroup, SubnetFilter, SubnetType, Vpc } from '../lib';

describe('vpc endpoint', () => {
describe('gateway endpoint', () => {
Expand Down Expand Up @@ -268,6 +268,25 @@ describe('vpc endpoint', () => {

});

describe('add interface endpoint to looked-up VPC', () => {
test('initial run', () => {
// GIVEN
const stack = new Stack(undefined, undefined, { env: { account: '1234', region: 'us-east-1' } });
const vpc = Vpc.fromLookup(stack, 'Vpc', {
vpcId: 'doesnt-matter',
});

// THEN: doesn't throw
vpc.addInterfaceEndpoint('SecretsManagerEndpoint', {
service: InterfaceVpcEndpointAwsService.SECRETS_MANAGER,
subnets: {
subnetFilters: [SubnetFilter.byIds(['1234'])],
},
});
});
});


test('import/export', () => {
// GIVEN
const stack2 = new Stack();
Expand Down

0 comments on commit f55cd2b

Please sign in to comment.