Skip to content

Commit 4a113e6

Browse files
authored
fix(ec2): fix subnet selection on looked-up VPCs (#4090)
Looked-up VPCs are created with a dummy configuration before the first lookup happens; a `selectSubnets` call on the dummy configuration is likely to fail. Add an exception to make the initial lookup not fail. Fixes #3650.
1 parent 364fd56 commit 4a113e6

File tree

2 files changed

+30
-6
lines changed

2 files changed

+30
-6
lines changed

packages/@aws-cdk/aws-ec2/lib/vpc.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,11 @@ abstract class VpcBase extends Resource implements IVpc {
282282
*/
283283
protected readonly natDependencies = new Array<IConstruct>();
284284

285+
/**
286+
* If this is set to true, don't error out on trying to select subnets
287+
*/
288+
protected incompleteSubnetDefinition: boolean = false;
289+
285290
/**
286291
* Returns IDs of selected subnets
287292
*/
@@ -347,7 +352,7 @@ abstract class VpcBase extends Resource implements IVpc {
347352
const allSubnets = [...this.publicSubnets, ...this.privateSubnets, ...this.isolatedSubnets];
348353
const subnets = allSubnets.filter(s => subnetGroupNameFromConstructId(s) === groupName);
349354

350-
if (subnets.length === 0) {
355+
if (subnets.length === 0 && !this.incompleteSubnetDefinition) {
351356
const names = Array.from(new Set(allSubnets.map(subnetGroupNameFromConstructId)));
352357
throw new Error(`There are no subnet groups with name '${groupName}' in this VPC. Available names: ${names}`);
353358
}
@@ -369,7 +374,10 @@ abstract class VpcBase extends Resource implements IVpc {
369374
subnets = subnets.filter(s => subnetGroupNameFromConstructId(s) === subnetGroupNameFromConstructId(subnets[0]));
370375
}
371376

372-
if (subnets.length === 0) {
377+
// Force merge conflict here with https://github.com/aws/aws-cdk/pull/4089
378+
// see ImportedVpc
379+
380+
if (subnets.length === 0 && !this.incompleteSubnetDefinition) {
373381
const availableTypes = Object.entries(allSubnets).filter(([_, subs]) => subs.length > 0).map(([typeName, _]) => typeName);
374382
throw new Error(`There are no '${subnetType}' subnet groups in this VPC. Available types: ${availableTypes}`);
375383
}
@@ -759,7 +767,7 @@ export class Vpc extends VpcBase {
759767
* Import an exported VPC
760768
*/
761769
public static fromVpcAttributes(scope: Construct, id: string, attrs: VpcAttributes): IVpc {
762-
return new ImportedVpc(scope, id, attrs);
770+
return new ImportedVpc(scope, id, attrs, false);
763771
}
764772

765773
/**
@@ -796,10 +804,10 @@ export class Vpc extends VpcBase {
796804
const attributes = ContextProvider.getValue(scope, {
797805
provider: cxapi.VPC_PROVIDER,
798806
props: { filter } as cxapi.VpcContextQuery,
799-
dummyValue: DUMMY_VPC_PROPS
807+
dummyValue: undefined
800808
});
801809

802-
return this.fromVpcAttributes(scope, id, attributes);
810+
return new ImportedVpc(scope, id, attributes || DUMMY_VPC_PROPS, attributes === undefined);
803811

804812
/**
805813
* Prefixes all keys in the argument with `tag:`.`
@@ -1418,12 +1426,13 @@ class ImportedVpc extends VpcBase {
14181426
public readonly vpnGatewayId?: string;
14191427
public readonly internetConnectivityEstablished: IDependable = new ConcreteDependable();
14201428

1421-
constructor(scope: Construct, id: string, props: VpcAttributes) {
1429+
constructor(scope: Construct, id: string, props: VpcAttributes, isIncomplete: boolean) {
14221430
super(scope, id);
14231431

14241432
this.vpcId = props.vpcId;
14251433
this.availabilityZones = props.availabilityZones;
14261434
this.vpnGatewayId = props.vpnGatewayId;
1435+
this.incompleteSubnetDefinition = isIncomplete;
14271436

14281437
// tslint:disable:max-line-length
14291438
const pub = new ImportSubnetGroup(props.publicSubnetIds, props.publicSubnetNames, props.publicSubnetRouteTableIds, SubnetType.PUBLIC, this.availabilityZones, 'publicSubnetIds', 'publicSubnetNames', 'publicSubnetRouteTableIds');

packages/@aws-cdk/aws-ec2/test/test.vpc.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,21 @@ export = {
862862

863863
test.done();
864864
},
865+
866+
'selecting subnets by name from a looked-up VPC does not throw'(test: Test) {
867+
// GIVEN
868+
const stack = new Stack(undefined, undefined, { env: { region: 'us-east-1', account: '123456789012' }});
869+
const vpc = Vpc.fromLookup(stack, 'VPC', {
870+
vpcId: 'vpc-1234'
871+
});
872+
873+
// WHEN
874+
vpc.selectSubnets({ subnetName: 'Bleep' });
875+
876+
// THEN: no exception
877+
878+
test.done();
879+
},
865880
};
866881

867882
function getTestStack(): Stack {

0 commit comments

Comments
 (0)