diff --git a/packages/aws-cdk/lib/context-providers/vpcs.ts b/packages/aws-cdk/lib/context-providers/vpcs.ts index 99b2f6e7820a9..66a5e8e6d2cc5 100644 --- a/packages/aws-cdk/lib/context-providers/vpcs.ts +++ b/packages/aws-cdk/lib/context-providers/vpcs.ts @@ -80,6 +80,10 @@ export class VpcNetworkContextProviderPlugin implements ContextProviderPlugin { throw new Error(`Subnet ${subnet.SubnetArn} has invalid subnet type ${type} (must be ${SubnetType.Public}, ${SubnetType.Private} or ${SubnetType.Isolated})`); } + if (args.subnetGroupNameTag && !getTag(args.subnetGroupNameTag, subnet.Tags)) { + throw new Error(`Invalid subnetGroupNameTag: Subnet ${subnet.SubnetArn} does not have an associated tag with Key='${args.subnetGroupNameTag}'`); + } + const name = getTag(args.subnetGroupNameTag || 'aws-cdk:subnet-name', subnet.Tags) || type; const routeTableId = routeTables.routeTableIdForSubnetId(subnet.SubnetId); diff --git a/packages/aws-cdk/test/context-providers/vpcs.test.ts b/packages/aws-cdk/test/context-providers/vpcs.test.ts index e97090666d710..0b03aaf4cacd9 100644 --- a/packages/aws-cdk/test/context-providers/vpcs.test.ts +++ b/packages/aws-cdk/test/context-providers/vpcs.test.ts @@ -110,6 +110,144 @@ test('throws when no such VPC is found', async () => { })).rejects.toThrow(/Could not find any VPCs matching/); }); +test('throws when subnet with subnetGroupNameTag not found', async () => { + // GIVEN + const filter = { foo: 'bar' }; + const provider = new VpcNetworkContextProviderPlugin(mockSDK); + + mockVpcLookup({ + subnets: [ + { SubnetId: 'sub-123456', AvailabilityZone: 'bermuda-triangle-1337', MapPublicIpOnLaunch: true }, + { SubnetId: 'sub-789012', AvailabilityZone: 'bermuda-triangle-1337', MapPublicIpOnLaunch: false }, + ], + routeTables: [ + { + Associations: [{ SubnetId: 'sub-123456' }], + RouteTableId: 'rtb-123456', + Routes: [ + { + DestinationCidrBlock: '1.1.1.1/24', + GatewayId: 'local', + Origin: 'CreateRouteTable', + State: 'active', + }, + { + DestinationCidrBlock: '0.0.0.0/0', + GatewayId: 'igw-xxxxxx', + Origin: 'CreateRoute', + State: 'active', + }, + ], + }, + { + Associations: [{ SubnetId: 'sub-789012' }], + RouteTableId: 'rtb-789012', + Routes: [ + { + DestinationCidrBlock: '1.1.2.1/24', + GatewayId: 'local', + Origin: 'CreateRouteTable', + State: 'active', + }, + { + DestinationCidrBlock: '0.0.0.0/0', + NatGatewayId: 'nat-xxxxxx', + Origin: 'CreateRoute', + State: 'active', + }, + ], + }, + ], + vpnGateways: [{ VpnGatewayId: 'gw-abcdef' }], + }); + + // WHEN + await expect(provider.getValue({ + account: '1234', + region: 'us-east-1', + subnetGroupNameTag: 'DOES_NOT_EXIST', + filter, + })).rejects.toThrow(/Invalid subnetGroupNameTag: Subnet .* does not have an associated tag with Key='DOES_NOT_EXIST'/); +}); + +test('does not throw when subnet with subnetGroupNameTag is found', async () => { + // GIVEN + const filter = { foo: 'bar' }; + const provider = new VpcNetworkContextProviderPlugin(mockSDK); + + mockVpcLookup({ + subnets: [ + { SubnetId: 'sub-123456', AvailabilityZone: 'bermuda-triangle-1337', MapPublicIpOnLaunch: true, Tags: [{ Key: 'DOES_EXIST', Value: 'SubnetName1' }] }, + { SubnetId: 'sub-789012', AvailabilityZone: 'bermuda-triangle-1337', MapPublicIpOnLaunch: false, Tags: [{ Key: 'DOES_EXIST', Value: 'SubnetName2' }] }, + ], + routeTables: [ + { + Associations: [{ SubnetId: 'sub-123456' }], + RouteTableId: 'rtb-123456', + Routes: [ + { + DestinationCidrBlock: '1.1.1.1/24', + GatewayId: 'local', + Origin: 'CreateRouteTable', + State: 'active', + }, + { + DestinationCidrBlock: '0.0.0.0/0', + GatewayId: 'igw-xxxxxx', + Origin: 'CreateRoute', + State: 'active', + }, + ], + }, + { + Associations: [{ SubnetId: 'sub-789012' }], + RouteTableId: 'rtb-789012', + Routes: [ + { + DestinationCidrBlock: '1.1.2.1/24', + GatewayId: 'local', + Origin: 'CreateRouteTable', + State: 'active', + }, + { + DestinationCidrBlock: '0.0.0.0/0', + NatGatewayId: 'nat-xxxxxx', + Origin: 'CreateRoute', + State: 'active', + }, + ], + }, + ], + vpnGateways: [{ VpnGatewayId: 'gw-abcdef' }], + }); + + // WHEN + const result = await provider.getValue({ + account: '1234', + region: 'us-east-1', + subnetGroupNameTag: 'DOES_EXIST', + filter, + }); + + // THEN + expect(result).toEqual({ + vpcId: 'vpc-1234567', + vpcCidrBlock: '1.1.1.1/16', + availabilityZones: ['bermuda-triangle-1337'], + isolatedSubnetIds: undefined, + isolatedSubnetNames: undefined, + isolatedSubnetRouteTableIds: undefined, + privateSubnetIds: ['sub-789012'], + privateSubnetNames: ['SubnetName2'], + privateSubnetRouteTableIds: ['rtb-789012'], + publicSubnetIds: ['sub-123456'], + publicSubnetNames: ['SubnetName1'], + publicSubnetRouteTableIds: ['rtb-123456'], + vpnGatewayId: 'gw-abcdef', + subnetGroups: undefined, + }); +}); + test('throws when multiple VPCs are found', async () => { // GIVEN const filter = { foo: 'bar' };