From af43218fd936b0079fea30f95d751dd27ceb0f6f Mon Sep 17 00:00:00 2001 From: Chen Date: Wed, 2 Oct 2024 10:04:46 -0700 Subject: [PATCH 01/34] initial skeleton code --- packages/@aws-cdk/aws-ec2-alpha/lib/route.ts | 186 ++++++++++++++++++- 1 file changed, 183 insertions(+), 3 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts b/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts index ad098d68cf950..5020e345f3a97 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts @@ -1,9 +1,29 @@ -import { CfnEIP, CfnEgressOnlyInternetGateway, CfnInternetGateway, CfnNatGateway, CfnRoute, CfnRouteTable, CfnVPCGatewayAttachment, CfnVPNGateway, CfnVPNGatewayRoutePropagation, GatewayVpcEndpoint, IRouteTable, IVpcEndpoint, RouterType } from 'aws-cdk-lib/aws-ec2'; +import { + CfnEIP, + CfnEgressOnlyInternetGateway, + CfnInternetGateway, + CfnNatGateway, + CfnVPCPeeringConnectionProps, + CfnRoute, + CfnRouteTable, + CfnVPCGatewayAttachment, + CfnVPCPeeringConnection, + CfnVPNGateway, + CfnVPNGatewayRoutePropagation, + GatewayVpcEndpoint, IRouteTable, IVpcEndpoint, RouterType } from 'aws-cdk-lib/aws-ec2'; import { Construct, IDependable } from 'constructs'; -import { Annotations, Duration, IResource, Resource } from 'aws-cdk-lib/core'; +import { Annotations, Duration, IResource, Resource, Stack } from 'aws-cdk-lib/core'; import { IVpcV2, VPNGatewayV2Options } from './vpc-v2-base'; -import { NetworkUtils, allRouteTableIds } from './util'; +import { CidrBlock, NetworkUtils, allRouteTableIds } from './util'; import { ISubnetV2 } from './subnet-v2'; +import { + Role, + AccountPrincipal, + PolicyStatement, + Effect, +} from 'aws-cdk-lib/aws-iam'; +import { Fn } from '../../../aws-cdk-lib/core'; + /** * Indicates whether the NAT gateway supports public or private connectivity. @@ -175,6 +195,40 @@ export interface NatGatewayProps extends NatGatewayOptions { readonly vpc?: IVpcV2; } +/** + * Properties to define a VPC Peering Connection. + */ +export interface VPCPeeringConnectionProps { + /** + * Indicates whether this is a cross-account VPC peering connection. + */ + readonly isCrossAccount: boolean; + + /** + * The VPC that is requesting the peering connection. + */ + readonly requestorVpc: IVpcV2; + + /** + * The VPC that is accepting the peering connection. + */ + readonly acceptorVpc: IVpcV2; + + /** + * The AWS account ID of the acceptor VPC owner. + * + * @default - no acceptor account ID needed if not cross account connection + */ + readonly acceptorAccountId?: string; + + /** + * The region of the acceptor VPC. + * + * @default - same region as the requestor VPC + */ + readonly acceptorRegion?: string; +} + /** * Creates an egress-only internet gateway * @resource AWS::EC2::EgressOnlyInternetGateway @@ -402,6 +456,132 @@ export class NatGateway extends Resource implements IRouteTarget { } } + + +export class VPCPeeringConnection extends Resource implements IRouteTarget { + + /** + * The type of router used in the route. + */ + readonly routerType: RouterType; + + /** + * The ID of the route target. + */ + readonly routerTargetId: string; + + /** + * The NAT gateway CFN resource. + */ + public readonly resource: CfnVPCPeeringConnection; + + constructor(scope: Construct, id: string, props: VPCPeeringConnectionProps) { + super(scope, id); + + this.routerType = RouterType.VPC_PEERING_CONNECTION; + + const { isCrossAccount, requestorVpc, acceptorVpc, acceptorAccountId, acceptorRegion } = props; + let peerRole: Role | undefined; + + + if (isCrossAccount && !acceptorAccountId) { + throw new Error('AcceptorAccountId is required for cross-account peering connections'); + } + + const overlap = validateVpcCidrOverlap(requestorVpc, acceptorVpc); + if (overlap) { + throw new Error('CIDR block should not overlap with existing subnet blocks'); + } + + if (isCrossAccount) { + if (!Stack.of(this).region && !acceptorRegion) { + throw new Error('Ensure either AcceptorRegion or requestor region is defined'); + } + let region = acceptorRegion + if (!region) { + region = Stack.of(this).region; + } + + // Create the cross-account role in the acceptor account + peerRole = new Role(this, 'PeerRole', { + assumedBy: new AccountPrincipal(Stack.of(this).account), + roleName: `VPCPeeringRole-${id}`, + }); + + // Add the assume role policy for the requestor account + peerRole.assumeRolePolicy?.addStatements( + new PolicyStatement({ + effect: Effect.ALLOW, + actions: ['sts:AssumeRole'], + principals: [new AccountPrincipal(Stack.of(this).account)], + }) + ); + + // Add highly restrictive policy + peerRole.addToPolicy(new PolicyStatement({ + effect: Effect.ALLOW, + actions: ['ec2:acceptVpcPeeringConnection'], + resources: Fn.sub(`arn:aws:ec2:${region}:${acceptorAccountId}:vpc/${acceptorVpc.vpcId}`), + })); + + peerRole.addToPolicy(new PolicyStatement({ + actions: ['ec2:acceptVpcPeeringConnection'], + effect: Effect.ALLOW, + resources: [ + `arn:aws:ec2:${region}:${acceptorAccountId}:vpc-peering-connection/*` + ], + conditions: { + 'StringEquals': { + 'ec2:AccepterVpc': Fn.sub(`arn:aws:ec2:${region}:${acceptorAccountId}:vpc/${acceptorVpc.vpcId}`) + } + } + })); + } + + this.resource = new CfnVPCPeeringConnection(this, 'PeeringConnection', { + vpcId: requestorVpc.vpcId, + peerVpcId: acceptorVpc.vpcId, + peerOwnerId: isCrossAccount ? acceptorAccountId : undefined, + peerRegion: acceptorRegion, + peerRoleArn: peerRole?.roleArn, + }); + + this.routerTargetId = this.resource.attrId; + this.node.defaultChild = this.resource; + + + } +} + +function validateVpcCidrOverlap(requestorVpc: IVpcV2, acceptorVpc: IVpcV2): boolean { + + const requestorCidrs = [requestorVpc.ipv4CidrBlock]; + const acceptorCidrs = [acceptorVpc.ipv4CidrBlock]; + + if (requestorVpc.secondaryCidrBlock) { + requestorCidrs.push(...requestorVpc.secondaryCidrBlock); + } + + if (acceptorVpc.secondaryCidrBlock) { + acceptorCidrs.push(...acceptorVpc.secondaryCidrBlock); + } + + for (const requestorCidr of requestorCidrs) { + const requestorRange = new CidrBlock(requestorCidr); + const requestorIpRange: [string, string] = [requestorRange.minIp(), requestorRange.maxIp()]; + + for (const acceptorCidr of acceptorCidrs) { + const acceptorRange = new CidrBlock(acceptorCidr); + const acceptorIpRange: [string, string] = [acceptorRange.minIp(), acceptorRange.maxIp()]; + + if (requestorRange.rangesOverlap(acceptorIpRange, requestorIpRange)) { + return true; + } + } + } + return false; +} + /** * The type of endpoint or gateway being targeted by the route. */ From 16c8c3e20ca1c15626a4b4345845b8e7451f150a Mon Sep 17 00:00:00 2001 From: Kailey Chen Date: Thu, 3 Oct 2024 15:23:00 -0700 Subject: [PATCH 02/34] improve readability and update missing params --- packages/@aws-cdk/aws-ec2-alpha/lib/route.ts | 172 +++++++++---------- 1 file changed, 79 insertions(+), 93 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts b/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts index 5020e345f3a97..249066bf97e2c 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts @@ -1,29 +1,10 @@ -import { - CfnEIP, - CfnEgressOnlyInternetGateway, - CfnInternetGateway, - CfnNatGateway, - CfnVPCPeeringConnectionProps, - CfnRoute, - CfnRouteTable, - CfnVPCGatewayAttachment, - CfnVPCPeeringConnection, - CfnVPNGateway, - CfnVPNGatewayRoutePropagation, - GatewayVpcEndpoint, IRouteTable, IVpcEndpoint, RouterType } from 'aws-cdk-lib/aws-ec2'; +import { CfnEIP, CfnEgressOnlyInternetGateway, CfnInternetGateway, CfnNatGateway, CfnVPCPeeringConnection, CfnRoute, CfnRouteTable, CfnVPCGatewayAttachment, CfnVPNGateway, CfnVPNGatewayRoutePropagation, GatewayVpcEndpoint, IRouteTable, IVpcEndpoint, RouterType } from 'aws-cdk-lib/aws-ec2'; import { Construct, IDependable } from 'constructs'; -import { Annotations, Duration, IResource, Resource, Stack } from 'aws-cdk-lib/core'; +import { Aws, Annotations, Duration, IResource, Resource, Stack } from 'aws-cdk-lib/core'; import { IVpcV2, VPNGatewayV2Options } from './vpc-v2-base'; import { CidrBlock, NetworkUtils, allRouteTableIds } from './util'; import { ISubnetV2 } from './subnet-v2'; -import { - Role, - AccountPrincipal, - PolicyStatement, - Effect, -} from 'aws-cdk-lib/aws-iam'; -import { Fn } from '../../../aws-cdk-lib/core'; - +import { AccountPrincipal, Effect, PolicyStatement, Role } from 'aws-cdk-lib/aws-iam'; /** * Indicates whether the NAT gateway supports public or private connectivity. @@ -196,7 +177,7 @@ export interface NatGatewayProps extends NatGatewayOptions { } /** - * Properties to define a VPC Peering Connection. + * Properties to define a VPC peering connection. */ export interface VPCPeeringConnectionProps { /** @@ -216,17 +197,24 @@ export interface VPCPeeringConnectionProps { /** * The AWS account ID of the acceptor VPC owner. - * + * * @default - no acceptor account ID needed if not cross account connection */ readonly acceptorAccountId?: string; /** * The region of the acceptor VPC. - * + * * @default - same region as the requestor VPC */ readonly acceptorRegion?: string; + + /** + * The resource name of the peering connection. + * + * @default - peering connection provisioned without any name + */ + readonly vpcPeeringConnectionName?: string; } /** @@ -456,9 +444,11 @@ export class NatGateway extends Resource implements IRouteTarget { } } - - -export class VPCPeeringConnection extends Resource implements IRouteTarget { +/** + * Creates a peering connection between two VPCs + * @resource AWS::EC2::VPCPeeringConnection + */ +export class VPCPeeringConnection extends Resource implements IRouteTarget { /** * The type of router used in the route. @@ -471,117 +461,71 @@ export class VPCPeeringConnection extends Resource implements IRouteTarget { readonly routerTargetId: string; /** - * The NAT gateway CFN resource. + * The VPC peering connection CFN resource. */ public readonly resource: CfnVPCPeeringConnection; constructor(scope: Construct, id: string, props: VPCPeeringConnectionProps) { super(scope, id); - this.routerType = RouterType.VPC_PEERING_CONNECTION; - - const { isCrossAccount, requestorVpc, acceptorVpc, acceptorAccountId, acceptorRegion } = props; + const region = props.acceptorRegion ? props.acceptorRegion : Stack.of(this).region; let peerRole: Role | undefined; - + this.routerType = RouterType.VPC_PEERING_CONNECTION; - if (isCrossAccount && !acceptorAccountId) { + if (props.isCrossAccount && props.acceptorAccountId === undefined) { throw new Error('AcceptorAccountId is required for cross-account peering connections'); } - const overlap = validateVpcCidrOverlap(requestorVpc, acceptorVpc); + const overlap = validateVpcCidrOverlap(props.requestorVpc, props.acceptorVpc); if (overlap) { throw new Error('CIDR block should not overlap with existing subnet blocks'); } - if (isCrossAccount) { - if (!Stack.of(this).region && !acceptorRegion) { - throw new Error('Ensure either AcceptorRegion or requestor region is defined'); - } - let region = acceptorRegion - if (!region) { - region = Stack.of(this).region; - } - - // Create the cross-account role in the acceptor account + if (props.isCrossAccount) { peerRole = new Role(this, 'PeerRole', { assumedBy: new AccountPrincipal(Stack.of(this).account), roleName: `VPCPeeringRole-${id}`, }); - // Add the assume role policy for the requestor account peerRole.assumeRolePolicy?.addStatements( new PolicyStatement({ effect: Effect.ALLOW, actions: ['sts:AssumeRole'], principals: [new AccountPrincipal(Stack.of(this).account)], - }) + }), ); - // Add highly restrictive policy peerRole.addToPolicy(new PolicyStatement({ effect: Effect.ALLOW, actions: ['ec2:acceptVpcPeeringConnection'], - resources: Fn.sub(`arn:aws:ec2:${region}:${acceptorAccountId}:vpc/${acceptorVpc.vpcId}`), + resources: [`arn:${Aws.PARTITION}:ec2:${region}:${props.acceptorAccountId}:vpc/${props.acceptorVpc.vpcId}`], })); peerRole.addToPolicy(new PolicyStatement({ actions: ['ec2:acceptVpcPeeringConnection'], effect: Effect.ALLOW, - resources: [ - `arn:aws:ec2:${region}:${acceptorAccountId}:vpc-peering-connection/*` - ], + resources: [`arn:${Aws.PARTITION}:ec2:${region}:${props.acceptorAccountId}:vpc-peering-connection/*`], conditions: { - 'StringEquals': { - 'ec2:AccepterVpc': Fn.sub(`arn:aws:ec2:${region}:${acceptorAccountId}:vpc/${acceptorVpc.vpcId}`) - } - } + StringEquals: { + 'ec2:AccepterVpc': `arn:${Aws.PARTITION}:ec2:${region}:${props.acceptorAccountId}:vpc/${props.acceptorVpc.vpcId}`, + }, + }, })); } this.resource = new CfnVPCPeeringConnection(this, 'PeeringConnection', { - vpcId: requestorVpc.vpcId, - peerVpcId: acceptorVpc.vpcId, - peerOwnerId: isCrossAccount ? acceptorAccountId : undefined, - peerRegion: acceptorRegion, + vpcId: props.requestorVpc.vpcId, + peerVpcId: props.acceptorVpc.vpcId, + peerOwnerId: props.acceptorAccountId, + peerRegion: region, peerRoleArn: peerRole?.roleArn, }); - this.routerTargetId = this.resource.attrId; + this.routerTargetId = this.resource.attrId; this.node.defaultChild = this.resource; - - } } -function validateVpcCidrOverlap(requestorVpc: IVpcV2, acceptorVpc: IVpcV2): boolean { - - const requestorCidrs = [requestorVpc.ipv4CidrBlock]; - const acceptorCidrs = [acceptorVpc.ipv4CidrBlock]; - - if (requestorVpc.secondaryCidrBlock) { - requestorCidrs.push(...requestorVpc.secondaryCidrBlock); - } - - if (acceptorVpc.secondaryCidrBlock) { - acceptorCidrs.push(...acceptorVpc.secondaryCidrBlock); - } - - for (const requestorCidr of requestorCidrs) { - const requestorRange = new CidrBlock(requestorCidr); - const requestorIpRange: [string, string] = [requestorRange.minIp(), requestorRange.maxIp()]; - - for (const acceptorCidr of acceptorCidrs) { - const acceptorRange = new CidrBlock(acceptorCidr); - const acceptorIpRange: [string, string] = [acceptorRange.minIp(), acceptorRange.maxIp()]; - - if (requestorRange.rangesOverlap(acceptorIpRange, requestorIpRange)) { - return true; - } - } - } - return false; -} - /** * The type of endpoint or gateway being targeted by the route. */ @@ -714,7 +658,7 @@ export class Route extends Resource implements IRouteV2 { /** * The type of router the route is targetting */ - public readonly targetRouterType: RouterType + public readonly targetRouterType: RouterType; /** * The route CFN resource. @@ -843,4 +787,46 @@ function routerTypeToPropName(routerType: RouterType) { [RouterType.VPC_PEERING_CONNECTION]: 'vpcPeeringConnectionId', [RouterType.VPC_ENDPOINT]: 'vpcEndpointId', })[routerType]; +} + +/** + * Validates if the provided IPv4 CIDR block overlaps with existing subnet CIDR blocks within the given VPC. + * + * @param requestorVpc The VPC of the requestor. + * @param acceptorVpc The VPC of the acceptor. + * @returns True if the IPv4 CIDR block overlaps with existing subnet CIDR blocks, false otherwise. + * @internal + */ +function validateVpcCidrOverlap(requestorVpc: IVpcV2, acceptorVpc: IVpcV2): boolean { + + const requestorCidrs = [requestorVpc.ipv4CidrBlock]; + const acceptorCidrs = [acceptorVpc.ipv4CidrBlock]; + + if (requestorVpc.secondaryCidrBlock) { + requestorCidrs.push(...requestorVpc.secondaryCidrBlock + .map(block => block.cidrBlock) + .filter((cidr): cidr is string => cidr !== undefined)); + } + + if (acceptorVpc.secondaryCidrBlock) { + acceptorCidrs.push(...acceptorVpc.secondaryCidrBlock + .map(block => block.cidrBlock) + .filter((cidr): cidr is string => cidr !== undefined)); + } + + for (const requestorCidr of requestorCidrs) { + const requestorRange = new CidrBlock(requestorCidr); + const requestorIpRange: [string, string] = [requestorRange.minIp(), requestorRange.maxIp()]; + + for (const acceptorCidr of acceptorCidrs) { + const acceptorRange = new CidrBlock(acceptorCidr); + const acceptorIpRange: [string, string] = [acceptorRange.minIp(), acceptorRange.maxIp()]; + + if (requestorRange.rangesOverlap(acceptorIpRange, requestorIpRange)) { + return true; + } + } + } + + return false; } \ No newline at end of file From 7ebbfe58887ba57c4a27a1b4084f90297ef5f0f2 Mon Sep 17 00:00:00 2001 From: Kailey Chen Date: Thu, 3 Oct 2024 15:24:05 -0700 Subject: [PATCH 03/34] add test cases --- .../@aws-cdk/aws-ec2-alpha/test/route.test.ts | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts b/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts index 6504622ae4611..d37a4c1acf561 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts @@ -513,4 +513,124 @@ describe('EC2 Routing', () => { }); }); + describe('VPCPeeringConnection', () => { + test('Cross account peering connection', () => { + const vpc1 = new vpc.VpcV2(stack, 'VPC1', { + primaryAddressBlock: vpc.IpAddresses.ipv4('10.1.0.0/16'), + }); + const vpc2 = new vpc.VpcV2(stack, 'VPC2', { + primaryAddressBlock: vpc.IpAddresses.ipv4('10.2.0.0/16'), + }); + + new route.VPCPeeringConnection(stack, 'TestPeering', { + isCrossAccount: true, + requestorVpc: vpc1, + acceptorVpc: vpc2, + acceptorAccountId: '123456789012', + acceptorRegion: 'us-west-2', + }); + + const template = Template.fromStack(stack); + template.hasResourceProperties('AWS::EC2::VPCPeeringConnection', { + PeerOwnerId: '123456789012', + PeerRegion: 'us-west-2', + VpcId: { + 'Fn::GetAtt': ['VPC17DE2CF87', 'VpcId'], + }, + PeerVpcId: { + 'Fn::GetAtt': ['VPC2C1F0E711', 'VpcId'], + }, + PeerRoleArn: { + 'Fn::GetAtt': ['TestPeeringPeerRole67D845E9', 'Arn'], + }, + }); + }); + + test('CIDR block overlap should throw error', () => { + const vpc1 = new vpc.VpcV2(stack, 'VPC1', { + primaryAddressBlock: vpc.IpAddresses.ipv4('10.0.0.0/16'), + }); + + const vpc2 = new vpc.VpcV2(stack, 'VPC2', { + primaryAddressBlock: vpc.IpAddresses.ipv4('10.0.0.0/16'), + }); + + expect(() => { + new route.VPCPeeringConnection(stack, 'TestPeering', { + isCrossAccount: false, + requestorVpc: vpc1, + acceptorVpc: vpc2, + }); + }).toThrow(/CIDR block should not overlap with existing subnet blocks/); + }); + + test('CIDR block overlap with secondary CIDR block should throw error', () => { + const vpc1 = new vpc.VpcV2(stack, 'VPC1', { + primaryAddressBlock: vpc.IpAddresses.ipv4('10.0.0.0/16'), + secondaryAddressBlocks: [vpc.IpAddresses.ipv4('10.1.0.0/16', { cidrBlockName: 'Temp Block' })], + }); + + const vpc2 = new vpc.VpcV2(stack, 'VPC2', { + primaryAddressBlock: vpc.IpAddresses.ipv4('10.2.0.0/16'), + secondaryAddressBlocks: [vpc.IpAddresses.ipv4('10.1.0.0/16', { cidrBlockName: 'Temp Block' })], + }); + + expect(() => { + new route.VPCPeeringConnection(stack, 'TestPeering', { + isCrossAccount: false, + requestorVpc: vpc1, + acceptorVpc: vpc2, + }); + }).toThrow(/CIDR block should not overlap with existing subnet blocks/); + }); + + test('Non overlapping CIDR blocks should succeed', () => { + const vpc1 = new vpc.VpcV2(stack, 'VPC1', { + primaryAddressBlock: vpc.IpAddresses.ipv4('10.0.0.0/16'), + secondaryAddressBlocks: [vpc.IpAddresses.ipv4('10.1.0.0/16', { cidrBlockName: 'Temp Block' })], + }); + + const vpc2 = new vpc.VpcV2(stack, 'VPC2', { + primaryAddressBlock: vpc.IpAddresses.ipv4('10.2.0.0/16'), + secondaryAddressBlocks: [vpc.IpAddresses.ipv4('10.3.0.0/16', { cidrBlockName: 'Temp Block' })], + }); + + expect(() => { + new route.VPCPeeringConnection(stack, 'TestPeering', { + isCrossAccount: false, + requestorVpc: vpc1, + acceptorVpc: vpc2, + }); + }).not.toThrow(); + }); + + test('Default region handling for same account peering', () => { + const vpc1 = new vpc.VpcV2(stack, 'VPC1', { + primaryAddressBlock: vpc.IpAddresses.ipv4('10.1.0.0/16'), + }); + + const vpc2 = new vpc.VpcV2(stack, 'VPC2', { + primaryAddressBlock: vpc.IpAddresses.ipv4('10.2.0.0/16'), + }); + + new route.VPCPeeringConnection(stack, 'TestPeering', { + isCrossAccount: false, + requestorVpc: vpc1, + acceptorVpc: vpc2, + }); + + const template = Template.fromStack(stack); + template.hasResourceProperties('AWS::EC2::VPCPeeringConnection', { + VpcId: { + 'Fn::GetAtt': ['VPC17DE2CF87', 'VpcId'], + }, + PeerVpcId: { + 'Fn::GetAtt': ['VPC2C1F0E711', 'VpcId'], + }, + PeerRegion: { + Ref: 'AWS::Region', // CDK resolves this as the stack region + }, + }); + }); + }); }); From 9f601032d954b920600e9bf140d73a02a73968cf Mon Sep 17 00:00:00 2001 From: Kailey Chen Date: Thu, 3 Oct 2024 15:24:34 -0700 Subject: [PATCH 04/34] add integration test --- .../aws-cdk-routev2-alpha.assets.json | 2 +- ...routev2-dynamodbendpoint-alpha.assets.json | 2 +- ...dk-routev2-egressonlyigw-alpha.assets.json | 6 +- ...-routev2-egressonlyigw-alpha.template.json | 6 +- .../aws-cdk-routev2-igw-alpha.assets.json | 6 +- .../aws-cdk-routev2-igw-alpha.template.json | 40 +- ...ws-cdk-routev2-networkif-alpha.assets.json | 2 +- ...cdk-routev2-privatenatgw-alpha.assets.json | 6 +- ...k-routev2-privatenatgw-alpha.template.json | 5 +- ...-cdk-routev2-publicnatgw-alpha.assets.json | 6 +- ...dk-routev2-publicnatgw-alpha.template.json | 46 +- ...routev2-virtualprivategw-alpha.assets.json | 6 +- ...utev2-virtualprivategw-alpha.template.json | 56 ++- ...outev2-vpcpeerconnection-alpha.assets.json | 6 +- ...tev2-vpcpeerconnection-alpha.template.json | 191 +++++-- .../test/integ.route-v2.js.snapshot/cdk.out | 2 +- .../integ.route-v2.js.snapshot/integ.json | 2 +- ...efaultTestDeployAssertA16689B0.assets.json | 2 +- ...efaultTestDeployAssert46FEDE40.assets.json | 2 +- ...efaultTestDeployAssert04E3783E.assets.json | 2 +- ...efaultTestDeployAssertF3FA2F74.assets.json | 2 +- ...efaultTestDeployAssert4B12233C.assets.json | 2 +- ...efaultTestDeployAssertC0DDB875.assets.json | 2 +- ...efaultTestDeployAssert90B004F4.assets.json | 2 +- ...efaultTestDeployAssert4C509DCE.assets.json | 2 +- ...efaultTestDeployAssert77221752.assets.json | 2 +- .../integ.route-v2.js.snapshot/manifest.json | 112 +++-- .../test/integ.route-v2.js.snapshot/tree.json | 471 +++++++++++++----- .../aws-ec2-alpha/test/integ.route-v2.ts | 18 +- 29 files changed, 736 insertions(+), 273 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-alpha.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-alpha.assets.json index 953b3a4ae82e9..3aacec615df4b 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-alpha.assets.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-alpha.assets.json @@ -1,5 +1,5 @@ { - "version": "36.0.5", + "version": "38.0.1", "files": { "a963276e8401c096a74f0dc50ac7d80bb5f2bff399fce8c571660a0684ff54b7": { "source": { diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-dynamodbendpoint-alpha.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-dynamodbendpoint-alpha.assets.json index 6f27e2c04e801..9f1bcf2f7d571 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-dynamodbendpoint-alpha.assets.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-dynamodbendpoint-alpha.assets.json @@ -1,5 +1,5 @@ { - "version": "36.0.5", + "version": "38.0.1", "files": { "8b4b159425cc7d11fa6fd993c53e299319dd2fcea18d745e873a18d3ee156a50": { "source": { diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-egressonlyigw-alpha.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-egressonlyigw-alpha.assets.json index d17484319eef3..c1c2915c2db8f 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-egressonlyigw-alpha.assets.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-egressonlyigw-alpha.assets.json @@ -1,7 +1,7 @@ { - "version": "36.0.5", + "version": "38.0.1", "files": { - "b0e303439a83ae17adf592a6599e13f880529abf2f46f433af0742284a224385": { + "59eea98c04eb81e61ad96cf12d5ad30981ba8827c0a6f9329042aaf3b6ab25ae": { "source": { "path": "aws-cdk-routev2-egressonlyigw-alpha.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "b0e303439a83ae17adf592a6599e13f880529abf2f46f433af0742284a224385.json", + "objectKey": "59eea98c04eb81e61ad96cf12d5ad30981ba8827c0a6f9329042aaf3b6ab25ae.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-egressonlyigw-alpha.template.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-egressonlyigw-alpha.template.json index cd3a0c0a42484..fcebef0b91123 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-egressonlyigw-alpha.template.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-egressonlyigw-alpha.template.json @@ -35,7 +35,6 @@ "TestRoottableeigwRouteF867084E": { "Type": "AWS::EC2::Route", "Properties": { - "DestinationCidrBlock": "::/0", "DestinationIpv6CidrBlock": "::/0", "EgressOnlyInternetGatewayId": { "Fn::GetAtt": [ @@ -49,7 +48,10 @@ "RouteTableId" ] } - } + }, + "DependsOn": [ + "testEOIGWEIGW54CCAD37" + ] }, "eigwSubnetCC28B9F9": { "Type": "AWS::EC2::Subnet", diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-igw-alpha.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-igw-alpha.assets.json index a62abd102c23c..a48f00526bfc3 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-igw-alpha.assets.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-igw-alpha.assets.json @@ -1,7 +1,7 @@ { - "version": "36.0.5", + "version": "38.0.1", "files": { - "62f0873928dbdff7cc7c914e7275014da0d4f8e188fb633ea74a8cae7129ea0b": { + "26ace3dfd222102fc0437541ab4b4c0eb03fcd95da132842d7546d8bb568cdd5": { "source": { "path": "aws-cdk-routev2-igw-alpha.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "62f0873928dbdff7cc7c914e7275014da0d4f8e188fb633ea74a8cae7129ea0b.json", + "objectKey": "26ace3dfd222102fc0437541ab4b4c0eb03fcd95da132842d7546d8bb568cdd5.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-igw-alpha.template.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-igw-alpha.template.json index 1e21b3bc2c96f..392a6e1e2e395 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-igw-alpha.template.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-igw-alpha.template.json @@ -48,24 +48,11 @@ "RouteTableId" ] } - } - }, - "TestRoottableigwRouteGWAttachment4B3E8FD9": { - "Type": "AWS::EC2::VPCGatewayAttachment", - "Properties": { - "InternetGatewayId": { - "Fn::GetAtt": [ - "testIGW8D947AF2", - "InternetGatewayId" - ] - }, - "VpcId": { - "Fn::GetAtt": [ - "igw127F1970", - "VpcId" - ] - } - } + }, + "DependsOn": [ + "testIGWGWAttachment682A6782", + "testIGW8D947AF2" + ] }, "igwSubnetF238E402": { "Type": "AWS::EC2::Subnet", @@ -114,6 +101,23 @@ }, "testIGW8D947AF2": { "Type": "AWS::EC2::InternetGateway" + }, + "testIGWGWAttachment682A6782": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "InternetGatewayId": { + "Fn::GetAtt": [ + "testIGW8D947AF2", + "InternetGatewayId" + ] + }, + "VpcId": { + "Fn::GetAtt": [ + "igw127F1970", + "VpcId" + ] + } + } } }, "Parameters": { diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-networkif-alpha.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-networkif-alpha.assets.json index 805e32a041de3..361119ec14756 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-networkif-alpha.assets.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-networkif-alpha.assets.json @@ -1,5 +1,5 @@ { - "version": "36.0.5", + "version": "38.0.1", "files": { "434c826abb6c12fb9eebf4adb6aae43788ba6e2a204ad7eea6f60321e69d3b38": { "source": { diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-privatenatgw-alpha.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-privatenatgw-alpha.assets.json index 6fae013fe0a29..22f5a39f5640f 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-privatenatgw-alpha.assets.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-privatenatgw-alpha.assets.json @@ -1,7 +1,7 @@ { - "version": "36.0.5", + "version": "38.0.1", "files": { - "a4d43e15d95d55923771937ed74a05c6bd09a65f55f0c99a5ba9ca05069d7cbd": { + "39e23e50b17229259428c78d506b45da6f2681804d01ba216b26facaf35f69d6": { "source": { "path": "aws-cdk-routev2-privatenatgw-alpha.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "a4d43e15d95d55923771937ed74a05c6bd09a65f55f0c99a5ba9ca05069d7cbd.json", + "objectKey": "39e23e50b17229259428c78d506b45da6f2681804d01ba216b26facaf35f69d6.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-privatenatgw-alpha.template.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-privatenatgw-alpha.template.json index 654e1e1de840e..98023baef1952 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-privatenatgw-alpha.template.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-privatenatgw-alpha.template.json @@ -48,7 +48,10 @@ "RouteTableId" ] } - } + }, + "DependsOn": [ + "testNATgwNATGateway1533420D" + ] }, "natgwprivSubnetE547C5A0": { "Type": "AWS::EC2::Subnet", diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-publicnatgw-alpha.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-publicnatgw-alpha.assets.json index f59abe7b20923..0a7794b4fb281 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-publicnatgw-alpha.assets.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-publicnatgw-alpha.assets.json @@ -1,7 +1,7 @@ { - "version": "36.0.5", + "version": "38.0.1", "files": { - "85cd968be34ab2030a45e0e808082aa88035954029c2b379b38368ed20327047": { + "895d9a465fd31edd1eaadb22929fc8cf042ad912d272ea411632a6c9f820aba9": { "source": { "path": "aws-cdk-routev2-publicnatgw-alpha.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "85cd968be34ab2030a45e0e808082aa88035954029c2b379b38368ed20327047.json", + "objectKey": "895d9a465fd31edd1eaadb22929fc8cf042ad912d272ea411632a6c9f820aba9.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-publicnatgw-alpha.template.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-publicnatgw-alpha.template.json index 81030e32ede4d..2ae7eceb04166 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-publicnatgw-alpha.template.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-publicnatgw-alpha.template.json @@ -48,24 +48,11 @@ "RouteTableId" ] } - } - }, - "TestRoottablenatGwRouteGWAttachment1D9CDF77": { - "Type": "AWS::EC2::VPCGatewayAttachment", - "Properties": { - "InternetGatewayId": { - "Fn::GetAtt": [ - "testNATgwIGW6AC97E9A", - "InternetGatewayId" - ] - }, - "VpcId": { - "Fn::GetAtt": [ - "natgwpub2FB85986", - "VpcId" - ] - } - } + }, + "DependsOn": [ + "testNATgwIGWGWAttachment63DC9091", + "testNATgwIGW6AC97E9A" + ] }, "TestRoottablenatGwPubRoute0463E2F5": { "Type": "AWS::EC2::Route", @@ -83,7 +70,11 @@ "RouteTableId" ] } - } + }, + "DependsOn": [ + "testNATgwEIP1C260FAD", + "testNATgwNATGateway1533420D" + ] }, "natgwpubSubnet79D316E5": { "Type": "AWS::EC2::Subnet", @@ -133,6 +124,23 @@ "testNATgwIGW6AC97E9A": { "Type": "AWS::EC2::InternetGateway" }, + "testNATgwIGWGWAttachment63DC9091": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "InternetGatewayId": { + "Fn::GetAtt": [ + "testNATgwIGW6AC97E9A", + "InternetGatewayId" + ] + }, + "VpcId": { + "Fn::GetAtt": [ + "natgwpub2FB85986", + "VpcId" + ] + } + } + }, "testNATgwEIP1C260FAD": { "Type": "AWS::EC2::EIP", "Properties": { diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-virtualprivategw-alpha.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-virtualprivategw-alpha.assets.json index 0cd2e52e78a44..345f3924a3e83 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-virtualprivategw-alpha.assets.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-virtualprivategw-alpha.assets.json @@ -1,7 +1,7 @@ { - "version": "36.0.5", + "version": "38.0.1", "files": { - "fa2b156112be3f11361259d8aaafcd552d28499bba4cc881642fdc98bc04c924": { + "6d2e4cfbc5e7bfd23a115ae098e231aa3f8f68fc66cf9834642b374c23457ca7": { "source": { "path": "aws-cdk-routev2-virtualprivategw-alpha.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "fa2b156112be3f11361259d8aaafcd552d28499bba4cc881642fdc98bc04c924.json", + "objectKey": "6d2e4cfbc5e7bfd23a115ae098e231aa3f8f68fc66cf9834642b374c23457ca7.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-virtualprivategw-alpha.template.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-virtualprivategw-alpha.template.json index b25f6ff502905..00b2d94c9e5c7 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-virtualprivategw-alpha.template.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-virtualprivategw-alpha.template.json @@ -48,24 +48,12 @@ "RouteTableId" ] } - } - }, - "TestRoottablevpgwRouteGWAttachmentDD0077EE": { - "Type": "AWS::EC2::VPCGatewayAttachment", - "Properties": { - "VpcId": { - "Fn::GetAtt": [ - "vpgw2AB64B6B", - "VpcId" - ] - }, - "VpnGatewayId": { - "Fn::GetAtt": [ - "testVPGWIGW816C7C4F", - "VPNGatewayId" - ] - } - } + }, + "DependsOn": [ + "testVPGWIGW816C7C4F", + "testVPGWRoutePropagationD01C7942", + "testVPGWVPCVPNGWF1D3DC88" + ] }, "vpgwSubnet5E7F36AD": { "Type": "AWS::EC2::Subnet", @@ -117,6 +105,38 @@ "Properties": { "Type": "ipsec.1" } + }, + "testVPGWVPCVPNGWF1D3DC88": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "VpcId": { + "Fn::GetAtt": [ + "vpgw2AB64B6B", + "VpcId" + ] + }, + "VpnGatewayId": { + "Fn::GetAtt": [ + "testVPGWIGW816C7C4F", + "VPNGatewayId" + ] + } + } + }, + "testVPGWRoutePropagationD01C7942": { + "Type": "AWS::EC2::VPNGatewayRoutePropagation", + "Properties": { + "RouteTableIds": [], + "VpnGatewayId": { + "Fn::GetAtt": [ + "testVPGWIGW816C7C4F", + "VPNGatewayId" + ] + } + }, + "DependsOn": [ + "testVPGWVPCVPNGWF1D3DC88" + ] } }, "Parameters": { diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-vpcpeerconnection-alpha.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-vpcpeerconnection-alpha.assets.json index 94cc48acf6542..47f4987a1309b 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-vpcpeerconnection-alpha.assets.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-vpcpeerconnection-alpha.assets.json @@ -1,7 +1,7 @@ { - "version": "36.0.5", + "version": "38.0.1", "files": { - "fa56ca630709a15070b4208becd94454c974906d445fd83b73389524957f89e8": { + "4fc8e38f9f8c75b7937e32a2d8924346cf1648878ab74ccf8083f3c7958cf89a": { "source": { "path": "aws-cdk-routev2-vpcpeerconnection-alpha.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "fa56ca630709a15070b4208becd94454c974906d445fd83b73389524957f89e8.json", + "objectKey": "4fc8e38f9f8c75b7937e32a2d8924346cf1648878ab74ccf8083f3c7958cf89a.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-vpcpeerconnection-alpha.template.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-vpcpeerconnection-alpha.template.json index 7f195e58f758f..13d920985631c 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-vpcpeerconnection-alpha.template.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-vpcpeerconnection-alpha.template.json @@ -32,50 +32,183 @@ } } }, - "vpcpcSubnet1DD6CE35": { - "Type": "AWS::EC2::Subnet", + "TestRoottablevpcPeeringRouteA5DE3C21": { + "Type": "AWS::EC2::Route", "Properties": { - "AssignIpv6AddressOnCreation": false, - "AvailabilityZone": "us-east-1a", - "CidrBlock": "10.0.0.0/24", - "Ipv6CidrBlock": { - "Fn::Select": [ - 0, - { - "Fn::GetAtt": [ - "vpcpc6CAE1A04", - "Ipv6CidrBlocks" - ] - } + "DestinationCidrBlock": "0.0.0.0/0", + "RouteTableId": { + "Fn::GetAtt": [ + "TestRoottableRouteTableFA28AA38", + "RouteTableId" ] }, - "VpcId": { + "VpcPeeringConnectionId": { "Fn::GetAtt": [ - "vpcpc6CAE1A04", - "VpcId" + "crossAccountCrossRegionPeeringPeeringConnection1503A608", + "Id" ] } }, "DependsOn": [ - "vpcpcAmazonIpv66504EEB2" + "crossAccountCrossRegionPeeringPeeringConnection1503A608", + "crossAccountCrossRegionPeeringPeerRoleDefaultPolicy4F428B82", + "crossAccountCrossRegionPeeringPeerRoleA26F8D4F" ] }, - "vpcpcSubnetRouteTableAssociation8531BF5C": { - "Type": "AWS::EC2::SubnetRouteTableAssociation", + "secondVPCFBB45262": { + "Type": "AWS::EC2::VPC", "Properties": { - "RouteTableId": { + "CidrBlock": "10.1.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default" + } + }, + "secondVPCTempBlock7F6107B6": { + "Type": "AWS::EC2::VPCCidrBlock", + "Properties": { + "CidrBlock": "10.2.0.0/16", + "VpcId": { "Fn::GetAtt": [ - "TestRoottableRouteTableFA28AA38", - "RouteTableId" + "secondVPCFBB45262", + "VpcId" + ] + } + } + }, + "crossAccountCrossRegionPeeringPeerRoleA26F8D4F": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + }, + "RoleName": "VPCPeeringRole-crossAccountCrossRegionPeering" + } + }, + "crossAccountCrossRegionPeeringPeerRoleDefaultPolicy4F428B82": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "ec2:acceptVpcPeeringConnection", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":ec2:us-west-2:123456789012:vpc/", + { + "Fn::GetAtt": [ + "secondVPCFBB45262", + "VpcId" + ] + } + ] + ] + } + }, + { + "Action": "ec2:acceptVpcPeeringConnection", + "Condition": { + "StringEquals": { + "ec2:AccepterVpc": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":ec2:us-west-2:123456789012:vpc/", + { + "Fn::GetAtt": [ + "secondVPCFBB45262", + "VpcId" + ] + } + ] + ] + } + } + }, + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":ec2:us-west-2:123456789012:vpc-peering-connection/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "crossAccountCrossRegionPeeringPeerRoleDefaultPolicy4F428B82", + "Roles": [ + { + "Ref": "crossAccountCrossRegionPeeringPeerRoleA26F8D4F" + } + ] + } + }, + "crossAccountCrossRegionPeeringPeeringConnection1503A608": { + "Type": "AWS::EC2::VPCPeeringConnection", + "Properties": { + "PeerOwnerId": "123456789012", + "PeerRegion": "us-west-2", + "PeerRoleArn": { + "Fn::GetAtt": [ + "crossAccountCrossRegionPeeringPeerRoleA26F8D4F", + "Arn" + ] + }, + "PeerVpcId": { + "Fn::GetAtt": [ + "secondVPCFBB45262", + "VpcId" ] }, - "SubnetId": { - "Ref": "vpcpcSubnet1DD6CE35" + "VpcId": { + "Fn::GetAtt": [ + "vpcpc6CAE1A04", + "VpcId" + ] } - }, - "DependsOn": [ - "vpcpcAmazonIpv66504EEB2" - ] + } } }, "Parameters": { diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/cdk.out b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/cdk.out index bd5311dc372de..c6e612584e352 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/cdk.out +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"36.0.5"} \ No newline at end of file +{"version":"38.0.1"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integ.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integ.json index 488691ab97ceb..1454dfacdafeb 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integ.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "36.0.5", + "version": "38.0.1", "testCases": { "integtest-model-8/DefaultTest": { "stacks": [ diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel0DefaultTestDeployAssertA16689B0.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel0DefaultTestDeployAssertA16689B0.assets.json index 6f5363d26cf89..a11f7522ff2c1 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel0DefaultTestDeployAssertA16689B0.assets.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel0DefaultTestDeployAssertA16689B0.assets.json @@ -1,5 +1,5 @@ { - "version": "36.0.5", + "version": "38.0.1", "files": { "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { "source": { diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel1DefaultTestDeployAssert46FEDE40.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel1DefaultTestDeployAssert46FEDE40.assets.json index 9094ce35beea5..26d3a67e90f8e 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel1DefaultTestDeployAssert46FEDE40.assets.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel1DefaultTestDeployAssert46FEDE40.assets.json @@ -1,5 +1,5 @@ { - "version": "36.0.5", + "version": "38.0.1", "files": { "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { "source": { diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel2DefaultTestDeployAssert04E3783E.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel2DefaultTestDeployAssert04E3783E.assets.json index 29387894579ea..879ae61de4a92 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel2DefaultTestDeployAssert04E3783E.assets.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel2DefaultTestDeployAssert04E3783E.assets.json @@ -1,5 +1,5 @@ { - "version": "36.0.5", + "version": "38.0.1", "files": { "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { "source": { diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel3DefaultTestDeployAssertF3FA2F74.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel3DefaultTestDeployAssertF3FA2F74.assets.json index 6afa1f9195a7b..8c85a8079f81a 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel3DefaultTestDeployAssertF3FA2F74.assets.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel3DefaultTestDeployAssertF3FA2F74.assets.json @@ -1,5 +1,5 @@ { - "version": "36.0.5", + "version": "38.0.1", "files": { "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { "source": { diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel4DefaultTestDeployAssert4B12233C.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel4DefaultTestDeployAssert4B12233C.assets.json index 2170d2cd526f2..3be51680402a3 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel4DefaultTestDeployAssert4B12233C.assets.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel4DefaultTestDeployAssert4B12233C.assets.json @@ -1,5 +1,5 @@ { - "version": "36.0.5", + "version": "38.0.1", "files": { "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { "source": { diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel5DefaultTestDeployAssertC0DDB875.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel5DefaultTestDeployAssertC0DDB875.assets.json index aed458dfb9b1f..0ea575ebff5fb 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel5DefaultTestDeployAssertC0DDB875.assets.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel5DefaultTestDeployAssertC0DDB875.assets.json @@ -1,5 +1,5 @@ { - "version": "36.0.5", + "version": "38.0.1", "files": { "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { "source": { diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel6DefaultTestDeployAssert90B004F4.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel6DefaultTestDeployAssert90B004F4.assets.json index 29423943325fc..a0150ed0c4e0c 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel6DefaultTestDeployAssert90B004F4.assets.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel6DefaultTestDeployAssert90B004F4.assets.json @@ -1,5 +1,5 @@ { - "version": "36.0.5", + "version": "38.0.1", "files": { "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { "source": { diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel7DefaultTestDeployAssert4C509DCE.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel7DefaultTestDeployAssert4C509DCE.assets.json index 6fe2b5a955f17..f38ecf622deca 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel7DefaultTestDeployAssert4C509DCE.assets.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel7DefaultTestDeployAssert4C509DCE.assets.json @@ -1,5 +1,5 @@ { - "version": "36.0.5", + "version": "38.0.1", "files": { "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { "source": { diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel8DefaultTestDeployAssert77221752.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel8DefaultTestDeployAssert77221752.assets.json index d9fd3cff95553..70e2f461020b3 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel8DefaultTestDeployAssert77221752.assets.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/integtestmodel8DefaultTestDeployAssert77221752.assets.json @@ -1,5 +1,5 @@ { - "version": "36.0.5", + "version": "38.0.1", "files": { "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { "source": { diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/manifest.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/manifest.json index 2e922475b66bf..6a6473586d703 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "36.0.5", + "version": "38.0.1", "artifacts": { "aws-cdk-routev2-alpha.assets": { "type": "cdk:asset-manifest", @@ -16,6 +16,7 @@ "templateFile": "aws-cdk-routev2-alpha.template.json", "terminationProtection": false, "validateOnSynth": false, + "notificationArns": [], "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/a963276e8401c096a74f0dc50ac7d80bb5f2bff399fce8c571660a0684ff54b7.json", @@ -95,9 +96,10 @@ "templateFile": "aws-cdk-routev2-egressonlyigw-alpha.template.json", "terminationProtection": false, "validateOnSynth": false, + "notificationArns": [], "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/b0e303439a83ae17adf592a6599e13f880529abf2f46f433af0742284a224385.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/59eea98c04eb81e61ad96cf12d5ad30981ba8827c0a6f9329042aaf3b6ab25ae.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -186,9 +188,10 @@ "templateFile": "aws-cdk-routev2-igw-alpha.template.json", "terminationProtection": false, "validateOnSynth": false, + "notificationArns": [], "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/62f0873928dbdff7cc7c914e7275014da0d4f8e188fb633ea74a8cae7129ea0b.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/26ace3dfd222102fc0437541ab4b4c0eb03fcd95da132842d7546d8bb568cdd5.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -229,12 +232,6 @@ "data": "TestRoottableigwRouteC52EF731" } ], - "/aws-cdk-routev2-igw-alpha/TestRoottable/igwRoute/GWAttachment": [ - { - "type": "aws:cdk:logicalId", - "data": "TestRoottableigwRouteGWAttachment4B3E8FD9" - } - ], "/aws-cdk-routev2-igw-alpha/igwSubnet/Subnet": [ { "type": "aws:cdk:logicalId", @@ -253,6 +250,12 @@ "data": "testIGW8D947AF2" } ], + "/aws-cdk-routev2-igw-alpha/testIGW/GWAttachment": [ + { + "type": "aws:cdk:logicalId", + "data": "testIGWGWAttachment682A6782" + } + ], "/aws-cdk-routev2-igw-alpha/BootstrapVersion": [ { "type": "aws:cdk:logicalId", @@ -283,9 +286,10 @@ "templateFile": "aws-cdk-routev2-virtualprivategw-alpha.template.json", "terminationProtection": false, "validateOnSynth": false, + "notificationArns": [], "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/fa2b156112be3f11361259d8aaafcd552d28499bba4cc881642fdc98bc04c924.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/6d2e4cfbc5e7bfd23a115ae098e231aa3f8f68fc66cf9834642b374c23457ca7.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -326,12 +330,6 @@ "data": "TestRoottablevpgwRouteAD510A2A" } ], - "/aws-cdk-routev2-virtualprivategw-alpha/TestRoottable/vpgwRoute/GWAttachment": [ - { - "type": "aws:cdk:logicalId", - "data": "TestRoottablevpgwRouteGWAttachmentDD0077EE" - } - ], "/aws-cdk-routev2-virtualprivategw-alpha/vpgwSubnet/Subnet": [ { "type": "aws:cdk:logicalId", @@ -344,12 +342,30 @@ "data": "vpgwSubnetRouteTableAssociation49921F90" } ], + "/aws-cdk-routev2-virtualprivategw-alpha/testVPGW": [ + { + "type": "aws:cdk:warning", + "data": "No subnets matching selection: '[]'. Select other subnets to add routes to. [ack: @aws-cdk:aws-ec2-elpha:enableVpnGatewayV2]" + } + ], "/aws-cdk-routev2-virtualprivategw-alpha/testVPGW/IGW": [ { "type": "aws:cdk:logicalId", "data": "testVPGWIGW816C7C4F" } ], + "/aws-cdk-routev2-virtualprivategw-alpha/testVPGW/VPCVPNGW": [ + { + "type": "aws:cdk:logicalId", + "data": "testVPGWVPCVPNGWF1D3DC88" + } + ], + "/aws-cdk-routev2-virtualprivategw-alpha/testVPGW/RoutePropagation": [ + { + "type": "aws:cdk:logicalId", + "data": "testVPGWRoutePropagationD01C7942" + } + ], "/aws-cdk-routev2-virtualprivategw-alpha/BootstrapVersion": [ { "type": "aws:cdk:logicalId", @@ -380,9 +396,10 @@ "templateFile": "aws-cdk-routev2-publicnatgw-alpha.template.json", "terminationProtection": false, "validateOnSynth": false, + "notificationArns": [], "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/85cd968be34ab2030a45e0e808082aa88035954029c2b379b38368ed20327047.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/895d9a465fd31edd1eaadb22929fc8cf042ad912d272ea411632a6c9f820aba9.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -423,12 +440,6 @@ "data": "TestRoottablenatGwRoute31868FBF" } ], - "/aws-cdk-routev2-publicnatgw-alpha/TestRoottable/natGwRoute/GWAttachment": [ - { - "type": "aws:cdk:logicalId", - "data": "TestRoottablenatGwRouteGWAttachment1D9CDF77" - } - ], "/aws-cdk-routev2-publicnatgw-alpha/TestRoottable/natGwPubRoute/Route": [ { "type": "aws:cdk:logicalId", @@ -453,6 +464,12 @@ "data": "testNATgwIGW6AC97E9A" } ], + "/aws-cdk-routev2-publicnatgw-alpha/testNATgwIGW/GWAttachment": [ + { + "type": "aws:cdk:logicalId", + "data": "testNATgwIGWGWAttachment63DC9091" + } + ], "/aws-cdk-routev2-publicnatgw-alpha/testNATgw/EIP": [ { "type": "aws:cdk:logicalId", @@ -495,9 +512,10 @@ "templateFile": "aws-cdk-routev2-privatenatgw-alpha.template.json", "terminationProtection": false, "validateOnSynth": false, + "notificationArns": [], "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/a4d43e15d95d55923771937ed74a05c6bd09a65f55f0c99a5ba9ca05069d7cbd.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/39e23e50b17229259428c78d506b45da6f2681804d01ba216b26facaf35f69d6.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -586,6 +604,7 @@ "templateFile": "aws-cdk-routev2-networkif-alpha.template.json", "terminationProtection": false, "validateOnSynth": false, + "notificationArns": [], "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/434c826abb6c12fb9eebf4adb6aae43788ba6e2a204ad7eea6f60321e69d3b38.json", @@ -665,9 +684,10 @@ "templateFile": "aws-cdk-routev2-vpcpeerconnection-alpha.template.json", "terminationProtection": false, "validateOnSynth": false, + "notificationArns": [], "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/fa56ca630709a15070b4208becd94454c974906d445fd83b73389524957f89e8.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/4fc8e38f9f8c75b7937e32a2d8924346cf1648878ab74ccf8083f3c7958cf89a.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -702,16 +722,40 @@ "data": "TestRoottableRouteTableFA28AA38" } ], - "/aws-cdk-routev2-vpcpeerconnection-alpha/vpcpcSubnet/Subnet": [ + "/aws-cdk-routev2-vpcpeerconnection-alpha/TestRoottable/vpcPeeringRoute/Route": [ + { + "type": "aws:cdk:logicalId", + "data": "TestRoottablevpcPeeringRouteA5DE3C21" + } + ], + "/aws-cdk-routev2-vpcpeerconnection-alpha/secondVPC/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "secondVPCFBB45262" + } + ], + "/aws-cdk-routev2-vpcpeerconnection-alpha/secondVPC/Temp Block": [ + { + "type": "aws:cdk:logicalId", + "data": "secondVPCTempBlock7F6107B6" + } + ], + "/aws-cdk-routev2-vpcpeerconnection-alpha/crossAccountCrossRegionPeering/PeerRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "crossAccountCrossRegionPeeringPeerRoleA26F8D4F" + } + ], + "/aws-cdk-routev2-vpcpeerconnection-alpha/crossAccountCrossRegionPeering/PeerRole/DefaultPolicy/Resource": [ { "type": "aws:cdk:logicalId", - "data": "vpcpcSubnet1DD6CE35" + "data": "crossAccountCrossRegionPeeringPeerRoleDefaultPolicy4F428B82" } ], - "/aws-cdk-routev2-vpcpeerconnection-alpha/vpcpcSubnet/RouteTableAssociation": [ + "/aws-cdk-routev2-vpcpeerconnection-alpha/crossAccountCrossRegionPeering/PeeringConnection": [ { "type": "aws:cdk:logicalId", - "data": "vpcpcSubnetRouteTableAssociation8531BF5C" + "data": "crossAccountCrossRegionPeeringPeeringConnection1503A608" } ], "/aws-cdk-routev2-vpcpeerconnection-alpha/BootstrapVersion": [ @@ -744,6 +788,7 @@ "templateFile": "aws-cdk-routev2-dynamodbendpoint-alpha.template.json", "terminationProtection": false, "validateOnSynth": false, + "notificationArns": [], "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/8b4b159425cc7d11fa6fd993c53e299319dd2fcea18d745e873a18d3ee156a50.json", @@ -829,6 +874,7 @@ "templateFile": "integtestmodel0DefaultTestDeployAssertA16689B0.template.json", "terminationProtection": false, "validateOnSynth": false, + "notificationArns": [], "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", @@ -877,6 +923,7 @@ "templateFile": "integtestmodel1DefaultTestDeployAssert46FEDE40.template.json", "terminationProtection": false, "validateOnSynth": false, + "notificationArns": [], "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", @@ -925,6 +972,7 @@ "templateFile": "integtestmodel2DefaultTestDeployAssert04E3783E.template.json", "terminationProtection": false, "validateOnSynth": false, + "notificationArns": [], "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", @@ -973,6 +1021,7 @@ "templateFile": "integtestmodel3DefaultTestDeployAssertF3FA2F74.template.json", "terminationProtection": false, "validateOnSynth": false, + "notificationArns": [], "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", @@ -1021,6 +1070,7 @@ "templateFile": "integtestmodel4DefaultTestDeployAssert4B12233C.template.json", "terminationProtection": false, "validateOnSynth": false, + "notificationArns": [], "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", @@ -1069,6 +1119,7 @@ "templateFile": "integtestmodel5DefaultTestDeployAssertC0DDB875.template.json", "terminationProtection": false, "validateOnSynth": false, + "notificationArns": [], "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", @@ -1117,6 +1168,7 @@ "templateFile": "integtestmodel6DefaultTestDeployAssert90B004F4.template.json", "terminationProtection": false, "validateOnSynth": false, + "notificationArns": [], "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", @@ -1165,6 +1217,7 @@ "templateFile": "integtestmodel7DefaultTestDeployAssert4C509DCE.template.json", "terminationProtection": false, "validateOnSynth": false, + "notificationArns": [], "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", @@ -1213,6 +1266,7 @@ "templateFile": "integtestmodel8DefaultTestDeployAssert77221752.template.json", "terminationProtection": false, "validateOnSynth": false, + "notificationArns": [], "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/tree.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/tree.json index 68cca1ffdc6ab..64125ce6f223f 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/tree.json @@ -263,7 +263,6 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::Route", "aws:cdk:cloudformation:props": { - "destinationCidrBlock": "::/0", "destinationIpv6CidrBlock": "::/0", "egressOnlyInternetGatewayId": { "Fn::GetAtt": [ @@ -286,7 +285,7 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.Resource", + "fqn": "@aws-cdk/aws-ec2-alpha.Route", "version": "0.0.0" } } @@ -512,35 +511,10 @@ "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", "version": "0.0.0" } - }, - "GWAttachment": { - "id": "GWAttachment", - "path": "aws-cdk-routev2-igw-alpha/TestRoottable/igwRoute/GWAttachment", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::EC2::VPCGatewayAttachment", - "aws:cdk:cloudformation:props": { - "internetGatewayId": { - "Fn::GetAtt": [ - "testIGW8D947AF2", - "InternetGatewayId" - ] - }, - "vpcId": { - "Fn::GetAtt": [ - "igw127F1970", - "VpcId" - ] - } - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_ec2.CfnVPCGatewayAttachment", - "version": "0.0.0" - } } }, "constructInfo": { - "fqn": "aws-cdk-lib.Resource", + "fqn": "@aws-cdk/aws-ec2-alpha.Route", "version": "0.0.0" } } @@ -638,6 +612,31 @@ "fqn": "aws-cdk-lib.aws_ec2.CfnInternetGateway", "version": "0.0.0" } + }, + "GWAttachment": { + "id": "GWAttachment", + "path": "aws-cdk-routev2-igw-alpha/testIGW/GWAttachment", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPCGatewayAttachment", + "aws:cdk:cloudformation:props": { + "internetGatewayId": { + "Fn::GetAtt": [ + "testIGW8D947AF2", + "InternetGatewayId" + ] + }, + "vpcId": { + "Fn::GetAtt": [ + "igw127F1970", + "VpcId" + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnVPCGatewayAttachment", + "version": "0.0.0" + } } }, "constructInfo": { @@ -770,35 +769,10 @@ "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", "version": "0.0.0" } - }, - "GWAttachment": { - "id": "GWAttachment", - "path": "aws-cdk-routev2-virtualprivategw-alpha/TestRoottable/vpgwRoute/GWAttachment", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::EC2::VPCGatewayAttachment", - "aws:cdk:cloudformation:props": { - "vpcId": { - "Fn::GetAtt": [ - "vpgw2AB64B6B", - "VpcId" - ] - }, - "vpnGatewayId": { - "Fn::GetAtt": [ - "testVPGWIGW816C7C4F", - "VPNGatewayId" - ] - } - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_ec2.CfnVPCGatewayAttachment", - "version": "0.0.0" - } } }, "constructInfo": { - "fqn": "aws-cdk-lib.Resource", + "fqn": "@aws-cdk/aws-ec2-alpha.Route", "version": "0.0.0" } } @@ -898,10 +872,55 @@ "fqn": "aws-cdk-lib.aws_ec2.CfnVPNGateway", "version": "0.0.0" } + }, + "VPCVPNGW": { + "id": "VPCVPNGW", + "path": "aws-cdk-routev2-virtualprivategw-alpha/testVPGW/VPCVPNGW", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPCGatewayAttachment", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Fn::GetAtt": [ + "vpgw2AB64B6B", + "VpcId" + ] + }, + "vpnGatewayId": { + "Fn::GetAtt": [ + "testVPGWIGW816C7C4F", + "VPNGatewayId" + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnVPCGatewayAttachment", + "version": "0.0.0" + } + }, + "RoutePropagation": { + "id": "RoutePropagation", + "path": "aws-cdk-routev2-virtualprivategw-alpha/testVPGW/RoutePropagation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPNGatewayRoutePropagation", + "aws:cdk:cloudformation:props": { + "routeTableIds": [], + "vpnGatewayId": { + "Fn::GetAtt": [ + "testVPGWIGW816C7C4F", + "VPNGatewayId" + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnVPNGatewayRoutePropagation", + "version": "0.0.0" + } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2-alpha.VPNGateway", + "fqn": "@aws-cdk/aws-ec2-alpha.VPNGatewayV2", "version": "0.0.0" } }, @@ -1030,35 +1049,10 @@ "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", "version": "0.0.0" } - }, - "GWAttachment": { - "id": "GWAttachment", - "path": "aws-cdk-routev2-publicnatgw-alpha/TestRoottable/natGwRoute/GWAttachment", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::EC2::VPCGatewayAttachment", - "aws:cdk:cloudformation:props": { - "internetGatewayId": { - "Fn::GetAtt": [ - "testNATgwIGW6AC97E9A", - "InternetGatewayId" - ] - }, - "vpcId": { - "Fn::GetAtt": [ - "natgwpub2FB85986", - "VpcId" - ] - } - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_ec2.CfnVPCGatewayAttachment", - "version": "0.0.0" - } } }, "constructInfo": { - "fqn": "aws-cdk-lib.Resource", + "fqn": "@aws-cdk/aws-ec2-alpha.Route", "version": "0.0.0" } }, @@ -1094,7 +1088,7 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.Resource", + "fqn": "@aws-cdk/aws-ec2-alpha.Route", "version": "0.0.0" } } @@ -1192,6 +1186,31 @@ "fqn": "aws-cdk-lib.aws_ec2.CfnInternetGateway", "version": "0.0.0" } + }, + "GWAttachment": { + "id": "GWAttachment", + "path": "aws-cdk-routev2-publicnatgw-alpha/testNATgwIGW/GWAttachment", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPCGatewayAttachment", + "aws:cdk:cloudformation:props": { + "internetGatewayId": { + "Fn::GetAtt": [ + "testNATgwIGW6AC97E9A", + "InternetGatewayId" + ] + }, + "vpcId": { + "Fn::GetAtt": [ + "natgwpub2FB85986", + "VpcId" + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnVPCGatewayAttachment", + "version": "0.0.0" + } } }, "constructInfo": { @@ -1378,7 +1397,7 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.Resource", + "fqn": "@aws-cdk/aws-ec2-alpha.Route", "version": "0.0.0" } } @@ -1764,6 +1783,42 @@ "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable", "version": "0.0.0" } + }, + "vpcPeeringRoute": { + "id": "vpcPeeringRoute", + "path": "aws-cdk-routev2-vpcpeerconnection-alpha/TestRoottable/vpcPeeringRoute", + "children": { + "Route": { + "id": "Route", + "path": "aws-cdk-routev2-vpcpeerconnection-alpha/TestRoottable/vpcPeeringRoute/Route", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "destinationCidrBlock": "0.0.0.0/0", + "routeTableId": { + "Fn::GetAtt": [ + "TestRoottableRouteTableFA28AA38", + "RouteTableId" + ] + }, + "vpcPeeringConnectionId": { + "Fn::GetAtt": [ + "crossAccountCrossRegionPeeringPeeringConnection1503A608", + "Id" + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2-alpha.Route", + "version": "0.0.0" + } } }, "constructInfo": { @@ -1771,76 +1826,246 @@ "version": "0.0.0" } }, - "vpcpcSubnet": { - "id": "vpcpcSubnet", - "path": "aws-cdk-routev2-vpcpeerconnection-alpha/vpcpcSubnet", + "secondVPC": { + "id": "secondVPC", + "path": "aws-cdk-routev2-vpcpeerconnection-alpha/secondVPC", "children": { - "Subnet": { - "id": "Subnet", - "path": "aws-cdk-routev2-vpcpeerconnection-alpha/vpcpcSubnet/Subnet", + "Resource": { + "id": "Resource", + "path": "aws-cdk-routev2-vpcpeerconnection-alpha/secondVPC/Resource", "attributes": { - "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:type": "AWS::EC2::VPC", "aws:cdk:cloudformation:props": { - "assignIpv6AddressOnCreation": false, - "availabilityZone": "us-east-1a", - "cidrBlock": "10.0.0.0/24", - "ipv6CidrBlock": { - "Fn::Select": [ - 0, - { - "Fn::GetAtt": [ - "vpcpc6CAE1A04", - "Ipv6CidrBlocks" - ] - } - ] - }, + "cidrBlock": "10.1.0.0/16", + "enableDnsHostnames": true, + "enableDnsSupport": true, + "instanceTenancy": "default" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnVPC", + "version": "0.0.0" + } + }, + "Temp Block": { + "id": "Temp Block", + "path": "aws-cdk-routev2-vpcpeerconnection-alpha/secondVPC/Temp Block", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPCCidrBlock", + "aws:cdk:cloudformation:props": { + "cidrBlock": "10.2.0.0/16", "vpcId": { "Fn::GetAtt": [ - "vpcpc6CAE1A04", + "secondVPCFBB45262", "VpcId" ] } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet", + "fqn": "aws-cdk-lib.aws_ec2.CfnVPCCidrBlock", "version": "0.0.0" } - }, - "Acl": { - "id": "Acl", - "path": "aws-cdk-routev2-vpcpeerconnection-alpha/vpcpcSubnet/Acl", + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2-alpha.VpcV2", + "version": "0.0.0" + } + }, + "crossAccountCrossRegionPeering": { + "id": "crossAccountCrossRegionPeering", + "path": "aws-cdk-routev2-vpcpeerconnection-alpha/crossAccountCrossRegionPeering", + "children": { + "PeerRole": { + "id": "PeerRole", + "path": "aws-cdk-routev2-vpcpeerconnection-alpha/crossAccountCrossRegionPeering/PeerRole", + "children": { + "ImportPeerRole": { + "id": "ImportPeerRole", + "path": "aws-cdk-routev2-vpcpeerconnection-alpha/crossAccountCrossRegionPeering/PeerRole/ImportPeerRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-routev2-vpcpeerconnection-alpha/crossAccountCrossRegionPeering/PeerRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + }, + "roleName": "VPCPeeringRole-crossAccountCrossRegionPeering" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "aws-cdk-routev2-vpcpeerconnection-alpha/crossAccountCrossRegionPeering/PeerRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-routev2-vpcpeerconnection-alpha/crossAccountCrossRegionPeering/PeerRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": "ec2:acceptVpcPeeringConnection", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":ec2:us-west-2:123456789012:vpc/", + { + "Fn::GetAtt": [ + "secondVPCFBB45262", + "VpcId" + ] + } + ] + ] + } + }, + { + "Action": "ec2:acceptVpcPeeringConnection", + "Condition": { + "StringEquals": { + "ec2:AccepterVpc": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":ec2:us-west-2:123456789012:vpc/", + { + "Fn::GetAtt": [ + "secondVPCFBB45262", + "VpcId" + ] + } + ] + ] + } + } + }, + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":ec2:us-west-2:123456789012:vpc-peering-connection/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "policyName": "crossAccountCrossRegionPeeringPeerRoleDefaultPolicy4F428B82", + "roles": [ + { + "Ref": "crossAccountCrossRegionPeeringPeerRoleA26F8D4F" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "0.0.0" + } + } + }, "constructInfo": { - "fqn": "aws-cdk-lib.Resource", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } }, - "RouteTableAssociation": { - "id": "RouteTableAssociation", - "path": "aws-cdk-routev2-vpcpeerconnection-alpha/vpcpcSubnet/RouteTableAssociation", + "PeeringConnection": { + "id": "PeeringConnection", + "path": "aws-cdk-routev2-vpcpeerconnection-alpha/crossAccountCrossRegionPeering/PeeringConnection", "attributes": { - "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:type": "AWS::EC2::VPCPeeringConnection", "aws:cdk:cloudformation:props": { - "routeTableId": { + "peerOwnerId": "123456789012", + "peerRegion": "us-west-2", + "peerRoleArn": { "Fn::GetAtt": [ - "TestRoottableRouteTableFA28AA38", - "RouteTableId" + "crossAccountCrossRegionPeeringPeerRoleA26F8D4F", + "Arn" ] }, - "subnetId": { - "Ref": "vpcpcSubnet1DD6CE35" + "peerVpcId": { + "Fn::GetAtt": [ + "secondVPCFBB45262", + "VpcId" + ] + }, + "vpcId": { + "Fn::GetAtt": [ + "vpcpc6CAE1A04", + "VpcId" + ] } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation", + "fqn": "aws-cdk-lib.aws_ec2.CfnVPCPeeringConnection", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2-alpha.SubnetV2", + "fqn": "@aws-cdk/aws-ec2-alpha.VPCPeeringConnection", "version": "0.0.0" } }, @@ -1944,7 +2169,7 @@ "id": "dynamoRoute", "path": "aws-cdk-routev2-dynamodbendpoint-alpha/TestRoottable/dynamoRoute", "constructInfo": { - "fqn": "aws-cdk-lib.Resource", + "fqn": "@aws-cdk/aws-ec2-alpha.Route", "version": "0.0.0" } } diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.ts b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.ts index 4f9d98b92471f..ea8046ef4dc89 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.ts @@ -12,7 +12,7 @@ import * as vpc_v2 from '../lib/vpc-v2'; import { IntegTest } from '@aws-cdk/integ-tests-alpha'; import * as cdk from 'aws-cdk-lib'; import { IpCidr, SubnetV2 } from '../lib/subnet-v2'; -import { EgressOnlyInternetGateway, InternetGateway, NatConnectivityType, NatGateway, RouteTable, VPNGatewayV2 } from '../lib/route'; +import { EgressOnlyInternetGateway, InternetGateway, NatConnectivityType, NatGateway, RouteTable, VPCPeeringConnection, VPNGatewayV2 } from '../lib/route'; import { GatewayVpcEndpoint, GatewayVpcEndpointAwsService, SubnetType, VpnConnectionType } from 'aws-cdk-lib/aws-ec2'; import { Fn } from 'aws-cdk-lib'; @@ -57,7 +57,7 @@ for (const stackName in stacks) { routeTable: routeTables[stackName], }); subnets[stackName] = subnet; - } else { + } else if (stackName != 'vpcpc') { // use empty ipv6 that doesn't overlap const subnet = new SubnetV2(stacks[stackName], stackName + 'Subnet', { vpc: vpc, @@ -115,6 +115,20 @@ const dynamoEndpoint = new GatewayVpcEndpoint(stacks.dynamodb, 'testDynamoEndpoi }); routeTables.dynamodb.addRoute('dynamoRoute', '0.0.0.0/0', { endpoint: dynamoEndpoint }); +const vpc2 = new vpc_v2.VpcV2(stacks.vpcpc, 'secondVPC', { + primaryAddressBlock: vpc_v2.IpAddresses.ipv4('10.1.0.0/16'), + secondaryAddressBlocks: [vpc_v2.IpAddresses.ipv4('10.2.0.0/16', { cidrBlockName: 'Temp Block' })], +}); + +const peeringConnection = new VPCPeeringConnection(stacks.vpcpc, 'crossAccountCrossRegionPeering', { + isCrossAccount: true, + requestorVpc: vpcs.vpcpc, + acceptorVpc: vpc2, + acceptorAccountId: '123456789012', + acceptorRegion: 'us-west-2', +}); +routeTables.vpcpc.addRoute('vpcPeeringRoute', '0.0.0.0/0', { gateway: peeringConnection }); + var i = 0; for (const stackName in stacks) { new IntegTest(app, 'integtest-model-' + i, { From 7222bf403933dd6de056d5687864bf5a4263115e Mon Sep 17 00:00:00 2001 From: Kailey Chen Date: Thu, 3 Oct 2024 15:41:57 -0700 Subject: [PATCH 05/34] additional test coverage --- .../@aws-cdk/aws-ec2-alpha/test/route.test.ts | 70 ++++++++++++------- 1 file changed, 45 insertions(+), 25 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts b/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts index d37a4c1acf561..cf229a9ead0c7 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts @@ -546,7 +546,36 @@ describe('EC2 Routing', () => { }); }); - test('CIDR block overlap should throw error', () => { + test('Default region handling for same account peering', () => { + const vpc1 = new vpc.VpcV2(stack, 'VPC1', { + primaryAddressBlock: vpc.IpAddresses.ipv4('10.1.0.0/16'), + }); + + const vpc2 = new vpc.VpcV2(stack, 'VPC2', { + primaryAddressBlock: vpc.IpAddresses.ipv4('10.2.0.0/16'), + }); + + new route.VPCPeeringConnection(stack, 'TestPeering', { + isCrossAccount: false, + requestorVpc: vpc1, + acceptorVpc: vpc2, + }); + + const template = Template.fromStack(stack); + template.hasResourceProperties('AWS::EC2::VPCPeeringConnection', { + VpcId: { + 'Fn::GetAtt': ['VPC17DE2CF87', 'VpcId'], + }, + PeerVpcId: { + 'Fn::GetAtt': ['VPC2C1F0E711', 'VpcId'], + }, + PeerRegion: { + Ref: 'AWS::Region', + }, + }); + }); + + test('Overlap with primary CIDR block should throw error', () => { const vpc1 = new vpc.VpcV2(stack, 'VPC1', { primaryAddressBlock: vpc.IpAddresses.ipv4('10.0.0.0/16'), }); @@ -564,7 +593,7 @@ describe('EC2 Routing', () => { }).toThrow(/CIDR block should not overlap with existing subnet blocks/); }); - test('CIDR block overlap with secondary CIDR block should throw error', () => { + test('Overlap with secondary CIDR block should throw error', () => { const vpc1 = new vpc.VpcV2(stack, 'VPC1', { primaryAddressBlock: vpc.IpAddresses.ipv4('10.0.0.0/16'), secondaryAddressBlocks: [vpc.IpAddresses.ipv4('10.1.0.0/16', { cidrBlockName: 'Temp Block' })], @@ -584,9 +613,9 @@ describe('EC2 Routing', () => { }).toThrow(/CIDR block should not overlap with existing subnet blocks/); }); - test('Non overlapping CIDR blocks should succeed', () => { + test('Overlap with primary and secondary CIDR block should throw error', () => { const vpc1 = new vpc.VpcV2(stack, 'VPC1', { - primaryAddressBlock: vpc.IpAddresses.ipv4('10.0.0.0/16'), + primaryAddressBlock: vpc.IpAddresses.ipv4('10.3.0.0/16'), secondaryAddressBlocks: [vpc.IpAddresses.ipv4('10.1.0.0/16', { cidrBlockName: 'Temp Block' })], }); @@ -601,36 +630,27 @@ describe('EC2 Routing', () => { requestorVpc: vpc1, acceptorVpc: vpc2, }); - }).not.toThrow(); + }).toThrow(/CIDR block should not overlap with existing subnet blocks/); }); - test('Default region handling for same account peering', () => { + test('Non overlapping CIDR blocks should succeed', () => { const vpc1 = new vpc.VpcV2(stack, 'VPC1', { - primaryAddressBlock: vpc.IpAddresses.ipv4('10.1.0.0/16'), + primaryAddressBlock: vpc.IpAddresses.ipv4('10.0.0.0/16'), + secondaryAddressBlocks: [vpc.IpAddresses.ipv4('10.1.0.0/16', { cidrBlockName: 'Temp Block' })], }); const vpc2 = new vpc.VpcV2(stack, 'VPC2', { primaryAddressBlock: vpc.IpAddresses.ipv4('10.2.0.0/16'), + secondaryAddressBlocks: [vpc.IpAddresses.ipv4('10.3.0.0/16', { cidrBlockName: 'Temp Block' })], }); - new route.VPCPeeringConnection(stack, 'TestPeering', { - isCrossAccount: false, - requestorVpc: vpc1, - acceptorVpc: vpc2, - }); - - const template = Template.fromStack(stack); - template.hasResourceProperties('AWS::EC2::VPCPeeringConnection', { - VpcId: { - 'Fn::GetAtt': ['VPC17DE2CF87', 'VpcId'], - }, - PeerVpcId: { - 'Fn::GetAtt': ['VPC2C1F0E711', 'VpcId'], - }, - PeerRegion: { - Ref: 'AWS::Region', // CDK resolves this as the stack region - }, - }); + expect(() => { + new route.VPCPeeringConnection(stack, 'TestPeering', { + isCrossAccount: false, + requestorVpc: vpc1, + acceptorVpc: vpc2, + }); + }).not.toThrow(); }); }); }); From d920b57dc77adfb00bdf155c79f44c5091e16f41 Mon Sep 17 00:00:00 2001 From: Kailey Chen Date: Thu, 3 Oct 2024 16:14:26 -0700 Subject: [PATCH 06/34] add vpc peering connection into readme --- packages/@aws-cdk/aws-ec2-alpha/README.md | 32 +++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/packages/@aws-cdk/aws-ec2-alpha/README.md b/packages/@aws-cdk/aws-ec2-alpha/README.md index 32852b802bb05..3f1dfdbc7449d 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/README.md +++ b/packages/@aws-cdk/aws-ec2-alpha/README.md @@ -231,6 +231,38 @@ new Route(this, 'DynamoDBRoute', { }); ``` +## VPC Peering Connection + +VPC peering connection allows you to connect two VPCs and route traffic between them using private IP addresses. The VpcV2 construct supports creating VPC peering connections through the `VPCPeeringConnection` construct from the `route` module. + +Here's an example of how to create a VPC peering connection between two VPCs: + +```ts +const vpcA = new VpcV2(this, 'VpcA', { + primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/16'), +}); + +const vpcB = new VpcV2(this, 'VpcB', { + primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'), +}); + +const peeringConnection = new VPCPeeringConnection(stacks.vpcpc, 'crossAccountCrossRegionPeering', { + isCrossAccount: true, + requestorVpc: vpcA, + acceptorVpc: vpcB, + acceptorAccountId: '123456789012', + acceptorRegion: 'us-west-2', +}); +``` + +Note that for cross-account peering, you'll need to ensure that the peering request is accepted in the peer account. For more information see [Accept or reject a VPC peering connection](https://docs.aws.amazon.com/vpc/latest/peering/accept-vpc-peering-connection.html). + +To add routes for the peering connection to specific subnets, you can use the addRoute method of the RouteTable construct: + +```ts +routeTables.addRoute('vpcPeeringRoute', '10.0.0.0/16', { gateway: peeringConnection }); +``` + ## Adding Egress-Only Internet Gateway to VPC An egress-only internet gateway is a horizontally scaled, redundant, and highly available VPC component that allows outbound communication over IPv6 from instances in your VPC to the internet, and prevents the internet from initiating an IPv6 connection with your instances. From b21736efcd19d25724351f89df1decd9b6b4f9ce Mon Sep 17 00:00:00 2001 From: Kailey Chen Date: Fri, 4 Oct 2024 11:46:32 -0700 Subject: [PATCH 07/34] fix rosetta readme errors --- packages/@aws-cdk/aws-ec2-alpha/README.md | 16 ++++++++++------ .../aws-ec2-alpha/rosetta/default.ts-fixture | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/README.md b/packages/@aws-cdk/aws-ec2-alpha/README.md index 3f1dfdbc7449d..98b39f05442da 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/README.md +++ b/packages/@aws-cdk/aws-ec2-alpha/README.md @@ -238,6 +238,8 @@ VPC peering connection allows you to connect two VPCs and route traffic between Here's an example of how to create a VPC peering connection between two VPCs: ```ts +const stack = new Stack(); + const vpcA = new VpcV2(this, 'VpcA', { primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/16'), }); @@ -246,22 +248,24 @@ const vpcB = new VpcV2(this, 'VpcB', { primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'), }); -const peeringConnection = new VPCPeeringConnection(stacks.vpcpc, 'crossAccountCrossRegionPeering', { +const peeringConnection = new VPCPeeringConnection(this, 'crossAccountCrossRegionPeering', { isCrossAccount: true, requestorVpc: vpcA, acceptorVpc: vpcB, acceptorAccountId: '123456789012', acceptorRegion: 'us-west-2', }); + +const routeTable = new RouteTable(this, 'RouteTable', { + vpc: vpcA, +}); + +routeTable.addRoute('vpcPeeringRoute', '10.0.0.0/16', { gateway: peeringConnection }); ``` Note that for cross-account peering, you'll need to ensure that the peering request is accepted in the peer account. For more information see [Accept or reject a VPC peering connection](https://docs.aws.amazon.com/vpc/latest/peering/accept-vpc-peering-connection.html). -To add routes for the peering connection to specific subnets, you can use the addRoute method of the RouteTable construct: - -```ts -routeTables.addRoute('vpcPeeringRoute', '10.0.0.0/16', { gateway: peeringConnection }); -``` +To add routes for the peering connection to specific subnets, you can use the addRoute method of the RouteTable construct. ## Adding Egress-Only Internet Gateway to VPC diff --git a/packages/@aws-cdk/aws-ec2-alpha/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-ec2-alpha/rosetta/default.ts-fixture index 9643806d2973b..d48ffb9f1330b 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/rosetta/default.ts-fixture +++ b/packages/@aws-cdk/aws-ec2-alpha/rosetta/default.ts-fixture @@ -1,7 +1,7 @@ // Fixture with packages imported, but nothing else import { Construct } from 'constructs'; import { Stack, App, Fn } from 'aws-cdk-lib'; -import { VpcV2, SubnetV2, IpAddresses, IpamPoolPublicIpSource, RouteTable, InternetGateway, Route, NatGateway, EgressOnlyInternetGateway } from '@aws-cdk/aws-ec2-alpha'; +import { VpcV2, SubnetV2, IpAddresses, IpamPoolPublicIpSource, RouteTable, InternetGateway, Route, NatGateway, EgressOnlyInternetGateway, VPCPeeringConnection } from '@aws-cdk/aws-ec2-alpha'; import { Ipam, AwsServiceName, IpCidr, AddressFamily } from '@aws-cdk/aws-ec2-alpha'; import { NatConnectivityType } from '@aws-cdk/aws-ec2-alpha'; import { SubnetType, VpnConnectionType } from 'aws-cdk-lib/aws-ec2'; From 39f70723baf4794755f498bc2a8ad59747f10011 Mon Sep 17 00:00:00 2001 From: Kailey Chen Date: Mon, 7 Oct 2024 10:09:40 -0700 Subject: [PATCH 08/34] move validateVpcCidrOverlap to utils file --- packages/@aws-cdk/aws-ec2-alpha/lib/route.ts | 44 +------------------- packages/@aws-cdk/aws-ec2-alpha/lib/util.ts | 42 +++++++++++++++++++ 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts b/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts index 249066bf97e2c..a8fdc39664e79 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts @@ -2,7 +2,7 @@ import { CfnEIP, CfnEgressOnlyInternetGateway, CfnInternetGateway, CfnNatGateway import { Construct, IDependable } from 'constructs'; import { Aws, Annotations, Duration, IResource, Resource, Stack } from 'aws-cdk-lib/core'; import { IVpcV2, VPNGatewayV2Options } from './vpc-v2-base'; -import { CidrBlock, NetworkUtils, allRouteTableIds } from './util'; +import { NetworkUtils, allRouteTableIds, validateVpcCidrOverlap } from './util'; import { ISubnetV2 } from './subnet-v2'; import { AccountPrincipal, Effect, PolicyStatement, Role } from 'aws-cdk-lib/aws-iam'; @@ -787,46 +787,4 @@ function routerTypeToPropName(routerType: RouterType) { [RouterType.VPC_PEERING_CONNECTION]: 'vpcPeeringConnectionId', [RouterType.VPC_ENDPOINT]: 'vpcEndpointId', })[routerType]; -} - -/** - * Validates if the provided IPv4 CIDR block overlaps with existing subnet CIDR blocks within the given VPC. - * - * @param requestorVpc The VPC of the requestor. - * @param acceptorVpc The VPC of the acceptor. - * @returns True if the IPv4 CIDR block overlaps with existing subnet CIDR blocks, false otherwise. - * @internal - */ -function validateVpcCidrOverlap(requestorVpc: IVpcV2, acceptorVpc: IVpcV2): boolean { - - const requestorCidrs = [requestorVpc.ipv4CidrBlock]; - const acceptorCidrs = [acceptorVpc.ipv4CidrBlock]; - - if (requestorVpc.secondaryCidrBlock) { - requestorCidrs.push(...requestorVpc.secondaryCidrBlock - .map(block => block.cidrBlock) - .filter((cidr): cidr is string => cidr !== undefined)); - } - - if (acceptorVpc.secondaryCidrBlock) { - acceptorCidrs.push(...acceptorVpc.secondaryCidrBlock - .map(block => block.cidrBlock) - .filter((cidr): cidr is string => cidr !== undefined)); - } - - for (const requestorCidr of requestorCidrs) { - const requestorRange = new CidrBlock(requestorCidr); - const requestorIpRange: [string, string] = [requestorRange.minIp(), requestorRange.maxIp()]; - - for (const acceptorCidr of acceptorCidrs) { - const acceptorRange = new CidrBlock(acceptorCidr); - const acceptorIpRange: [string, string] = [acceptorRange.minIp(), acceptorRange.maxIp()]; - - if (requestorRange.rangesOverlap(acceptorIpRange, requestorIpRange)) { - return true; - } - } - } - - return false; } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2-alpha/lib/util.ts b/packages/@aws-cdk/aws-ec2-alpha/lib/util.ts index ed8ae62342ded..0f6414b11d876 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/lib/util.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/lib/util.ts @@ -1,6 +1,7 @@ /*eslint no-bitwise: ["error", { "allow": ["~", "|", "<<", "&"] }] */ import { ISubnet } from 'aws-cdk-lib/aws-ec2'; +import { IVpcV2 } from './vpc-v2-base'; /** * Return a subnet name from its construct ID @@ -380,3 +381,44 @@ export class CidrBlockIpv6 { } } +/** + * Validates if the provided IPv4 CIDR block overlaps with existing subnet CIDR blocks within the given VPC. + * + * @param requestorVpc The VPC of the requestor. + * @param acceptorVpc The VPC of the acceptor. + * @returns True if the IPv4 CIDR block overlaps with existing subnet CIDR blocks, false otherwise. + * @internal + */ +export function validateVpcCidrOverlap(requestorVpc: IVpcV2, acceptorVpc: IVpcV2): boolean { + + const requestorCidrs = [requestorVpc.ipv4CidrBlock]; + const acceptorCidrs = [acceptorVpc.ipv4CidrBlock]; + + if (requestorVpc.secondaryCidrBlock) { + requestorCidrs.push(...requestorVpc.secondaryCidrBlock + .map(block => block.cidrBlock) + .filter((cidr): cidr is string => cidr !== undefined)); + } + + if (acceptorVpc.secondaryCidrBlock) { + acceptorCidrs.push(...acceptorVpc.secondaryCidrBlock + .map(block => block.cidrBlock) + .filter((cidr): cidr is string => cidr !== undefined)); + } + + for (const requestorCidr of requestorCidrs) { + const requestorRange = new CidrBlock(requestorCidr); + const requestorIpRange: [string, string] = [requestorRange.minIp(), requestorRange.maxIp()]; + + for (const acceptorCidr of acceptorCidrs) { + const acceptorRange = new CidrBlock(acceptorCidr); + const acceptorIpRange: [string, string] = [acceptorRange.minIp(), acceptorRange.maxIp()]; + + if (requestorRange.rangesOverlap(acceptorIpRange, requestorIpRange)) { + return true; + } + } + } + + return false; +} \ No newline at end of file From 2b4c5c6a80d0bb26306b6d94826113a1580e6846 Mon Sep 17 00:00:00 2001 From: Kailey Chen Date: Thu, 10 Oct 2024 14:30:18 -0700 Subject: [PATCH 09/34] initial design change implementation --- packages/@aws-cdk/aws-ec2-alpha/README.md | 4 +- packages/@aws-cdk/aws-ec2-alpha/lib/route.ts | 140 ++++++++++-------- packages/@aws-cdk/aws-ec2-alpha/lib/util.ts | 43 ------ .../@aws-cdk/aws-ec2-alpha/lib/vpc-v2-base.ts | 81 +++++++++- packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2.ts | 14 +- 5 files changed, 169 insertions(+), 113 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/README.md b/packages/@aws-cdk/aws-ec2-alpha/README.md index 98b39f05442da..f651fbb47b765 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/README.md +++ b/packages/@aws-cdk/aws-ec2-alpha/README.md @@ -236,7 +236,7 @@ new Route(this, 'DynamoDBRoute', { VPC peering connection allows you to connect two VPCs and route traffic between them using private IP addresses. The VpcV2 construct supports creating VPC peering connections through the `VPCPeeringConnection` construct from the `route` module. Here's an example of how to create a VPC peering connection between two VPCs: - + Note that for cross-account peering, you'll need to ensure that the peering request is accepted in the peer account. For more information see [Accept or reject a VPC peering connection](https://docs.aws.amazon.com/vpc/latest/peering/accept-vpc-peering-connection.html). diff --git a/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts b/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts index a8fdc39664e79..fbde39355c791 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts @@ -1,10 +1,9 @@ import { CfnEIP, CfnEgressOnlyInternetGateway, CfnInternetGateway, CfnNatGateway, CfnVPCPeeringConnection, CfnRoute, CfnRouteTable, CfnVPCGatewayAttachment, CfnVPNGateway, CfnVPNGatewayRoutePropagation, GatewayVpcEndpoint, IRouteTable, IVpcEndpoint, RouterType } from 'aws-cdk-lib/aws-ec2'; import { Construct, IDependable } from 'constructs'; -import { Aws, Annotations, Duration, IResource, Resource, Stack } from 'aws-cdk-lib/core'; +import { Annotations, Duration, IResource, Resource, Stack } from 'aws-cdk-lib/core'; import { IVpcV2, VPNGatewayV2Options } from './vpc-v2-base'; -import { NetworkUtils, allRouteTableIds, validateVpcCidrOverlap } from './util'; +import { NetworkUtils, allRouteTableIds, CidrBlock } from './util'; import { ISubnetV2 } from './subnet-v2'; -import { AccountPrincipal, Effect, PolicyStatement, Role } from 'aws-cdk-lib/aws-iam'; /** * Indicates whether the NAT gateway supports public or private connectivity. @@ -177,19 +176,9 @@ export interface NatGatewayProps extends NatGatewayOptions { } /** - * Properties to define a VPC peering connection. + * Options to define a VPC peering connection. */ -export interface VPCPeeringConnectionProps { - /** - * Indicates whether this is a cross-account VPC peering connection. - */ - readonly isCrossAccount: boolean; - - /** - * The VPC that is requesting the peering connection. - */ - readonly requestorVpc: IVpcV2; - +export interface VPCPeeringConnectionOptions { /** * The VPC that is accepting the peering connection. */ @@ -198,16 +187,9 @@ export interface VPCPeeringConnectionProps { /** * The AWS account ID of the acceptor VPC owner. * - * @default - no acceptor account ID needed if not cross account connection - */ - readonly acceptorAccountId?: string; - - /** - * The region of the acceptor VPC. - * - * @default - same region as the requestor VPC + * @default - no roleArn needed if not cross account connection */ - readonly acceptorRegion?: string; + readonly peerRoleArn?: string; /** * The resource name of the peering connection. @@ -217,6 +199,16 @@ export interface VPCPeeringConnectionProps { readonly vpcPeeringConnectionName?: string; } +/** + * Properties to define a VPC peering connection. + */ +export interface VPCPeeringConnectionProps extends VPCPeeringConnectionOptions { + /** + * The VPC that is requesting the peering connection. + */ + readonly requestorVpc: IVpcV2; +} + /** * Creates an egress-only internet gateway * @resource AWS::EC2::EgressOnlyInternetGateway @@ -468,62 +460,80 @@ export class VPCPeeringConnection extends Resource implements IRouteTarget { constructor(scope: Construct, id: string, props: VPCPeeringConnectionProps) { super(scope, id); - const region = props.acceptorRegion ? props.acceptorRegion : Stack.of(this).region; - let peerRole: Role | undefined; this.routerType = RouterType.VPC_PEERING_CONNECTION; - if (props.isCrossAccount && props.acceptorAccountId === undefined) { - throw new Error('AcceptorAccountId is required for cross-account peering connections'); - } + const isCrossAccount = Stack.of(props.requestorVpc).account !== Stack.of(props.acceptorVpc).account; - const overlap = validateVpcCidrOverlap(props.requestorVpc, props.acceptorVpc); - if (overlap) { - throw new Error('CIDR block should not overlap with existing subnet blocks'); + if (!isCrossAccount && props.peerRoleArn) { + Annotations.of(this).addWarning( + 'This is a same account peering, peerRoleArn is not needed and will be ignored', + ); } - if (props.isCrossAccount) { - peerRole = new Role(this, 'PeerRole', { - assumedBy: new AccountPrincipal(Stack.of(this).account), - roleName: `VPCPeeringRole-${id}`, - }); - - peerRole.assumeRolePolicy?.addStatements( - new PolicyStatement({ - effect: Effect.ALLOW, - actions: ['sts:AssumeRole'], - principals: [new AccountPrincipal(Stack.of(this).account)], - }), - ); + if (isCrossAccount && !props.peerRoleArn) { + throw new Error('Cross account VPC peering requires a peerArnId'); + } - peerRole.addToPolicy(new PolicyStatement({ - effect: Effect.ALLOW, - actions: ['ec2:acceptVpcPeeringConnection'], - resources: [`arn:${Aws.PARTITION}:ec2:${region}:${props.acceptorAccountId}:vpc/${props.acceptorVpc.vpcId}`], - })); - - peerRole.addToPolicy(new PolicyStatement({ - actions: ['ec2:acceptVpcPeeringConnection'], - effect: Effect.ALLOW, - resources: [`arn:${Aws.PARTITION}:ec2:${region}:${props.acceptorAccountId}:vpc-peering-connection/*`], - conditions: { - StringEquals: { - 'ec2:AccepterVpc': `arn:${Aws.PARTITION}:ec2:${region}:${props.acceptorAccountId}:vpc/${props.acceptorVpc.vpcId}`, - }, - }, - })); + // TODO: do we still want to validate? already have this check in the vpc peering + const overlap = this.validateVpcCidrOverlap(props.requestorVpc, props.acceptorVpc); + if (overlap) { + throw new Error('CIDR block should not overlap with existing subnet blocks'); } - this.resource = new CfnVPCPeeringConnection(this, 'PeeringConnection', { + this.resource = new CfnVPCPeeringConnection(this, 'VPCPeeringConnection', { vpcId: props.requestorVpc.vpcId, peerVpcId: props.acceptorVpc.vpcId, - peerOwnerId: props.acceptorAccountId, - peerRegion: region, - peerRoleArn: peerRole?.roleArn, + peerOwnerId: props.acceptorVpc.ownerAccountId, + peerRegion: props.acceptorVpc.region, + peerRoleArn: isCrossAccount ? props.peerRoleArn : undefined, }); this.routerTargetId = this.resource.attrId; this.node.defaultChild = this.resource; } + + /** + * Validates if the provided IPv4 CIDR block overlaps with existing subnet CIDR blocks within the given VPC. + * + * @param requestorVpc The VPC of the requestor. + * @param acceptorVpc The VPC of the acceptor. + * @returns True if the IPv4 CIDR block overlaps with existing subnet CIDR blocks, false otherwise. + * @internal + */ + private validateVpcCidrOverlap(requestorVpc: IVpcV2, acceptorVpc: IVpcV2): boolean { + + const requestorCidrs = [requestorVpc.ipv4CidrBlock]; + const acceptorCidrs = [acceptorVpc.ipv4CidrBlock]; + + if (requestorVpc.secondaryCidrBlock) { + requestorCidrs.push(...requestorVpc.secondaryCidrBlock + .map(block => block.cidrBlock) + .filter((cidr): cidr is string => cidr !== undefined)); + } + + if (acceptorVpc.secondaryCidrBlock) { + acceptorCidrs.push(...acceptorVpc.secondaryCidrBlock + .map(block => block.cidrBlock) + .filter((cidr): cidr is string => cidr !== undefined)); + } + + for (const requestorCidr of requestorCidrs) { + const requestorRange = new CidrBlock(requestorCidr); + const requestorIpRange: [string, string] = [requestorRange.minIp(), requestorRange.maxIp()]; + + for (const acceptorCidr of acceptorCidrs) { + const acceptorRange = new CidrBlock(acceptorCidr); + const acceptorIpRange: [string, string] = [acceptorRange.minIp(), acceptorRange.maxIp()]; + + if (requestorRange.rangesOverlap(acceptorIpRange, requestorIpRange)) { + return true; + } + } + } + + return false; + } + } /** diff --git a/packages/@aws-cdk/aws-ec2-alpha/lib/util.ts b/packages/@aws-cdk/aws-ec2-alpha/lib/util.ts index 0f6414b11d876..8cbed53f9b919 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/lib/util.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/lib/util.ts @@ -1,7 +1,6 @@ /*eslint no-bitwise: ["error", { "allow": ["~", "|", "<<", "&"] }] */ import { ISubnet } from 'aws-cdk-lib/aws-ec2'; -import { IVpcV2 } from './vpc-v2-base'; /** * Return a subnet name from its construct ID @@ -379,46 +378,4 @@ export class CidrBlockIpv6 { } return ipv6Number; } -} - -/** - * Validates if the provided IPv4 CIDR block overlaps with existing subnet CIDR blocks within the given VPC. - * - * @param requestorVpc The VPC of the requestor. - * @param acceptorVpc The VPC of the acceptor. - * @returns True if the IPv4 CIDR block overlaps with existing subnet CIDR blocks, false otherwise. - * @internal - */ -export function validateVpcCidrOverlap(requestorVpc: IVpcV2, acceptorVpc: IVpcV2): boolean { - - const requestorCidrs = [requestorVpc.ipv4CidrBlock]; - const acceptorCidrs = [acceptorVpc.ipv4CidrBlock]; - - if (requestorVpc.secondaryCidrBlock) { - requestorCidrs.push(...requestorVpc.secondaryCidrBlock - .map(block => block.cidrBlock) - .filter((cidr): cidr is string => cidr !== undefined)); - } - - if (acceptorVpc.secondaryCidrBlock) { - acceptorCidrs.push(...acceptorVpc.secondaryCidrBlock - .map(block => block.cidrBlock) - .filter((cidr): cidr is string => cidr !== undefined)); - } - - for (const requestorCidr of requestorCidrs) { - const requestorRange = new CidrBlock(requestorCidr); - const requestorIpRange: [string, string] = [requestorRange.minIp(), requestorRange.maxIp()]; - - for (const acceptorCidr of acceptorCidrs) { - const acceptorRange = new CidrBlock(acceptorCidr); - const acceptorIpRange: [string, string] = [acceptorRange.minIp(), acceptorRange.maxIp()]; - - if (requestorRange.rangesOverlap(acceptorIpRange, requestorIpRange)) { - return true; - } - } - } - - return false; } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2-base.ts b/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2-base.ts index 013bcfd501243..837b7a88eb90c 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2-base.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2-base.ts @@ -1,9 +1,10 @@ -import { Resource, Annotations } from 'aws-cdk-lib'; +import { Aws, Resource, Annotations } from 'aws-cdk-lib'; import { IVpc, ISubnet, SubnetSelection, SelectedSubnets, EnableVpnGatewayOptions, VpnGateway, VpnConnectionType, CfnVPCGatewayAttachment, CfnVPNGatewayRoutePropagation, VpnConnectionOptions, VpnConnection, ClientVpnEndpointOptions, ClientVpnEndpoint, InterfaceVpcEndpointOptions, InterfaceVpcEndpoint, GatewayVpcEndpointOptions, GatewayVpcEndpoint, FlowLogOptions, FlowLog, FlowLogResourceType, SubnetType, SubnetFilter, CfnVPCCidrBlock } from 'aws-cdk-lib/aws-ec2'; import { allRouteTableIds, flatten, subnetGroupNameFromConstructId } from './util'; import { IDependable, Dependable, IConstruct, DependencyGroup } from 'constructs'; -import { EgressOnlyInternetGateway, InternetGateway, NatConnectivityType, NatGateway, NatGatewayOptions, Route, VPNGatewayV2 } from './route'; +import { EgressOnlyInternetGateway, InternetGateway, NatConnectivityType, NatGateway, NatGatewayOptions, Route, VPCPeeringConnection, VPCPeeringConnectionOptions, VPNGatewayV2 } from './route'; import { ISubnetV2 } from './subnet-v2'; +import { AccountPrincipal, Effect, PolicyStatement, Role } from 'aws-cdk-lib/aws-iam'; /** * Options to define EgressOnlyInternetGateway for VPC @@ -96,6 +97,20 @@ export interface IVpcV2 extends IVpc { */ readonly ipv4CidrBlock: string; + /** + * Optional to override inferred region + * + * @default - current stack's environment region + */ + readonly region?: string; + + /** + * The ID of the AWS account that owns the VPC + * + * @default - the account id of the parent stack + */ + readonly ownerAccountId?: string; + /** * Add an Egress only Internet Gateway to current VPC. * Can only be used for ipv6 enabled VPCs. @@ -128,6 +143,19 @@ export interface IVpcV2 extends IVpc { */ addNatGateway(options: NatGatewayOptions): NatGateway; + /** + * Adds a new role to VPC account + * A cross account role is required for the VPC to peer with another account. + * For more information, see the {@link https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/peer-with-vpc-in-another-account.html}. + */ + createAcceptorVpcRole(requestorAccountId: string, acceptorAccountId: string, acceptorVpcRegion: string): Role; + + /** + * Creates a new peering connection + * A peering connection is a private virtual network established between two VPCs. + * For more information, see the {@link https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html}. + */ + createPeeringConnection(id: string, options: VPCPeeringConnectionOptions): VPCPeeringConnection; } /** @@ -167,6 +195,16 @@ export abstract class VpcV2Base extends Resource implements IVpcV2 { */ public abstract readonly isolatedSubnets: ISubnet[]; + /** + * Region for this VPC + */ + public abstract readonly region?: string; + + /** + * Identifier of the owner for this VPC + */ + public abstract readonly ownerAccountId?: string; + /** * AZs for this VPC */ @@ -445,6 +483,45 @@ export abstract class VpcV2Base extends Resource implements IVpcV2 { }); } + /** + * Creates peering connection role for acceptor VPC + */ + public createAcceptorVpcRole(requestorAccountId: string, acceptorAccountId: string, acceptorVpcRegion: string): Role { + const peeringRole = new Role(this, 'VpcPeeringRole', { + assumedBy: new AccountPrincipal(requestorAccountId), + description: 'Restrictive role for VPC peering', + }); + + peeringRole.addToPolicy(new PolicyStatement({ + effect: Effect.ALLOW, + actions: ['ec2:AcceptVpcPeeringConnection'], + resources: [`arn:${Aws.PARTITION}:ec2:${acceptorVpcRegion}:${requestorAccountId}:vpc/${acceptorAccountId}`], + })); + + peeringRole.addToPolicy(new PolicyStatement({ + actions: ['ec2:AcceptVpcPeeringConnection'], + effect: Effect.ALLOW, + resources: [`arn:${Aws.PARTITION}:ec2:${acceptorVpcRegion}:${requestorAccountId}:vpc-peering-connection/*`], + conditions: { + StringEquals: { + 'ec2:AccepterVpc': `arn:${Aws.PARTITION}:ec2:${acceptorVpcRegion}:${requestorAccountId}:vpc/${acceptorAccountId}`, + }, + }, + })); + + return peeringRole; + } + + /** + * Creates a peering connection + */ + public createPeeringConnection(id: string, options: VPCPeeringConnectionOptions): VPCPeeringConnection { + return new VPCPeeringConnection(this, id, { + requestorVpc: this, + ...options, + }); + } + /** * Returns the id of the VPN Gateway (if enabled) */ diff --git a/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2.ts b/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2.ts index a4477c69a6587..eee969f8e1010 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2.ts @@ -243,10 +243,20 @@ export class VpcV2 extends VpcV2Base { public readonly publicSubnets: ISubnet[]; /** - * Pbulic Subnets that are part of this VPC. + * Public Subnets that are part of this VPC. */ public readonly privateSubnets: ISubnet[]; + /** + * Region for this VPC + */ + public readonly region?: string; + + /** + * Identifier of the owner for this VPC + */ + public readonly ownerAccountId?: string; + /** * To define dependency on internet connectivity */ @@ -302,6 +312,8 @@ export class VpcV2 extends VpcV2Base { resource: 'vpc', resourceName: this.vpcId, }, this.stack); + this.region = this.stack.region; + this.ownerAccountId = this.stack.account; if (props.secondaryAddressBlocks) { const secondaryAddressBlocks: IIpAddresses[] = props.secondaryAddressBlocks; From 0c3bc8bd85e06b53c7862599b6d8ba1846914057 Mon Sep 17 00:00:00 2001 From: Kailey Chen Date: Thu, 10 Oct 2024 14:52:35 -0700 Subject: [PATCH 10/34] add region & ownerAccountId to VpcV2Props --- packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2.ts b/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2.ts index eee969f8e1010..7ee2e841b6c00 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2.ts @@ -180,6 +180,20 @@ export interface VpcV2Props { * @default - autogenerated by CDK */ readonly vpcName?: string; + + /** + * Optional to override inferred region + * + * @default - current stack's environment region + */ + readonly region?: string; + + /** + * The ID of the AWS account that owns the VPC + * + * @default - the account id of the parent stack + */ + readonly ownerAccountId?: string; } /** @@ -312,8 +326,8 @@ export class VpcV2 extends VpcV2Base { resource: 'vpc', resourceName: this.vpcId, }, this.stack); - this.region = this.stack.region; - this.ownerAccountId = this.stack.account; + this.region = props.region ?? this.stack.region; + this.ownerAccountId = props.ownerAccountId ?? this.stack.account; if (props.secondaryAddressBlocks) { const secondaryAddressBlocks: IIpAddresses[] = props.secondaryAddressBlocks; From ac630887481e8b04ff6359c8a1dbabc85cefc8bc Mon Sep 17 00:00:00 2001 From: Kailey Chen Date: Thu, 10 Oct 2024 14:56:10 -0700 Subject: [PATCH 11/34] remove old tests --- .../aws-ec2-alpha/test/integ.route-v2.ts | 26 +-- .../@aws-cdk/aws-ec2-alpha/test/route.test.ts | 163 ++++-------------- 2 files changed, 45 insertions(+), 144 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.ts b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.ts index ea8046ef4dc89..e475968219533 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.ts @@ -12,7 +12,7 @@ import * as vpc_v2 from '../lib/vpc-v2'; import { IntegTest } from '@aws-cdk/integ-tests-alpha'; import * as cdk from 'aws-cdk-lib'; import { IpCidr, SubnetV2 } from '../lib/subnet-v2'; -import { EgressOnlyInternetGateway, InternetGateway, NatConnectivityType, NatGateway, RouteTable, VPCPeeringConnection, VPNGatewayV2 } from '../lib/route'; +import { EgressOnlyInternetGateway, InternetGateway, NatConnectivityType, NatGateway, RouteTable, VPNGatewayV2 } from '../lib/route'; import { GatewayVpcEndpoint, GatewayVpcEndpointAwsService, SubnetType, VpnConnectionType } from 'aws-cdk-lib/aws-ec2'; import { Fn } from 'aws-cdk-lib'; @@ -115,19 +115,19 @@ const dynamoEndpoint = new GatewayVpcEndpoint(stacks.dynamodb, 'testDynamoEndpoi }); routeTables.dynamodb.addRoute('dynamoRoute', '0.0.0.0/0', { endpoint: dynamoEndpoint }); -const vpc2 = new vpc_v2.VpcV2(stacks.vpcpc, 'secondVPC', { - primaryAddressBlock: vpc_v2.IpAddresses.ipv4('10.1.0.0/16'), - secondaryAddressBlocks: [vpc_v2.IpAddresses.ipv4('10.2.0.0/16', { cidrBlockName: 'Temp Block' })], -}); +// const vpc2 = new vpc_v2.VpcV2(stacks.vpcpc, 'secondVPC', { +// primaryAddressBlock: vpc_v2.IpAddresses.ipv4('10.1.0.0/16'), +// secondaryAddressBlocks: [vpc_v2.IpAddresses.ipv4('10.2.0.0/16', { cidrBlockName: 'Temp Block' })], +// }); -const peeringConnection = new VPCPeeringConnection(stacks.vpcpc, 'crossAccountCrossRegionPeering', { - isCrossAccount: true, - requestorVpc: vpcs.vpcpc, - acceptorVpc: vpc2, - acceptorAccountId: '123456789012', - acceptorRegion: 'us-west-2', -}); -routeTables.vpcpc.addRoute('vpcPeeringRoute', '0.0.0.0/0', { gateway: peeringConnection }); +// const peeringConnection = new VPCPeeringConnection(stacks.vpcpc, 'crossAccountCrossRegionPeering', { +// isCrossAccount: true, +// requestorVpc: vpcs.vpcpc, +// acceptorVpc: vpc2, +// acceptorAccountId: '123456789012', +// acceptorRegion: 'us-west-2', +// }); +// routeTables.vpcpc.addRoute('vpcPeeringRoute', '0.0.0.0/0', { gateway: peeringConnection }); var i = 0; for (const stackName in stacks) { diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts b/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts index cf229a9ead0c7..34dd3d4994777 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts @@ -512,145 +512,46 @@ describe('EC2 Routing', () => { }, }); }); +}); - describe('VPCPeeringConnection', () => { - test('Cross account peering connection', () => { - const vpc1 = new vpc.VpcV2(stack, 'VPC1', { - primaryAddressBlock: vpc.IpAddresses.ipv4('10.1.0.0/16'), - }); - const vpc2 = new vpc.VpcV2(stack, 'VPC2', { - primaryAddressBlock: vpc.IpAddresses.ipv4('10.2.0.0/16'), - }); - - new route.VPCPeeringConnection(stack, 'TestPeering', { - isCrossAccount: true, - requestorVpc: vpc1, - acceptorVpc: vpc2, - acceptorAccountId: '123456789012', - acceptorRegion: 'us-west-2', - }); - - const template = Template.fromStack(stack); - template.hasResourceProperties('AWS::EC2::VPCPeeringConnection', { - PeerOwnerId: '123456789012', - PeerRegion: 'us-west-2', - VpcId: { - 'Fn::GetAtt': ['VPC17DE2CF87', 'VpcId'], - }, - PeerVpcId: { - 'Fn::GetAtt': ['VPC2C1F0E711', 'VpcId'], - }, - PeerRoleArn: { - 'Fn::GetAtt': ['TestPeeringPeerRole67D845E9', 'Arn'], - }, - }); - }); - - test('Default region handling for same account peering', () => { - const vpc1 = new vpc.VpcV2(stack, 'VPC1', { - primaryAddressBlock: vpc.IpAddresses.ipv4('10.1.0.0/16'), - }); - - const vpc2 = new vpc.VpcV2(stack, 'VPC2', { - primaryAddressBlock: vpc.IpAddresses.ipv4('10.2.0.0/16'), - }); +describe('VPCPeeringConnection', () => { - new route.VPCPeeringConnection(stack, 'TestPeering', { - isCrossAccount: false, - requestorVpc: vpc1, - acceptorVpc: vpc2, - }); + let stack: cdk.Stack; + let vpcA: vpc.VpcV2; + let vpcB: vpc.VpcV2; - const template = Template.fromStack(stack); - template.hasResourceProperties('AWS::EC2::VPCPeeringConnection', { - VpcId: { - 'Fn::GetAtt': ['VPC17DE2CF87', 'VpcId'], - }, - PeerVpcId: { - 'Fn::GetAtt': ['VPC2C1F0E711', 'VpcId'], - }, - PeerRegion: { - Ref: 'AWS::Region', - }, - }); + beforeEach(() => { + const app = new cdk.App({ + context: { + '@aws-cdk/core:newStyleStackSynthesis': false, + }, }); - - test('Overlap with primary CIDR block should throw error', () => { - const vpc1 = new vpc.VpcV2(stack, 'VPC1', { - primaryAddressBlock: vpc.IpAddresses.ipv4('10.0.0.0/16'), - }); - - const vpc2 = new vpc.VpcV2(stack, 'VPC2', { - primaryAddressBlock: vpc.IpAddresses.ipv4('10.0.0.0/16'), - }); - - expect(() => { - new route.VPCPeeringConnection(stack, 'TestPeering', { - isCrossAccount: false, - requestorVpc: vpc1, - acceptorVpc: vpc2, - }); - }).toThrow(/CIDR block should not overlap with existing subnet blocks/); + stack = new cdk.Stack(app, 'VpcStack'); + vpcA = new vpc.VpcV2(stack, 'VpcA', { + primaryAddressBlock: vpc.IpAddresses.ipv4('10.0.0.0/16'), + secondaryAddressBlocks: [vpc.IpAddresses.ipv4('10.1.0.0/16', { cidrBlockName: 'TempSecondaryBlock' })], }); - - test('Overlap with secondary CIDR block should throw error', () => { - const vpc1 = new vpc.VpcV2(stack, 'VPC1', { - primaryAddressBlock: vpc.IpAddresses.ipv4('10.0.0.0/16'), - secondaryAddressBlocks: [vpc.IpAddresses.ipv4('10.1.0.0/16', { cidrBlockName: 'Temp Block' })], - }); - - const vpc2 = new vpc.VpcV2(stack, 'VPC2', { - primaryAddressBlock: vpc.IpAddresses.ipv4('10.2.0.0/16'), - secondaryAddressBlocks: [vpc.IpAddresses.ipv4('10.1.0.0/16', { cidrBlockName: 'Temp Block' })], - }); - - expect(() => { - new route.VPCPeeringConnection(stack, 'TestPeering', { - isCrossAccount: false, - requestorVpc: vpc1, - acceptorVpc: vpc2, - }); - }).toThrow(/CIDR block should not overlap with existing subnet blocks/); + vpcB = new vpc.VpcV2(stack, 'VpcB', { + primaryAddressBlock: vpc.IpAddresses.ipv4('10.2.0.0/16'), }); + }); - test('Overlap with primary and secondary CIDR block should throw error', () => { - const vpc1 = new vpc.VpcV2(stack, 'VPC1', { - primaryAddressBlock: vpc.IpAddresses.ipv4('10.3.0.0/16'), - secondaryAddressBlocks: [vpc.IpAddresses.ipv4('10.1.0.0/16', { cidrBlockName: 'Temp Block' })], - }); - - const vpc2 = new vpc.VpcV2(stack, 'VPC2', { - primaryAddressBlock: vpc.IpAddresses.ipv4('10.2.0.0/16'), - secondaryAddressBlocks: [vpc.IpAddresses.ipv4('10.3.0.0/16', { cidrBlockName: 'Temp Block' })], - }); - - expect(() => { - new route.VPCPeeringConnection(stack, 'TestPeering', { - isCrossAccount: false, - requestorVpc: vpc1, - acceptorVpc: vpc2, - }); - }).toThrow(/CIDR block should not overlap with existing subnet blocks/); + test('Creates a VPC peering connection', () => { + new route.VPCPeeringConnection(stack, 'TestPeeringConnection', { + requestorVpc: vpcA, + acceptorVpc: vpcB, }); - test('Non overlapping CIDR blocks should succeed', () => { - const vpc1 = new vpc.VpcV2(stack, 'VPC1', { - primaryAddressBlock: vpc.IpAddresses.ipv4('10.0.0.0/16'), - secondaryAddressBlocks: [vpc.IpAddresses.ipv4('10.1.0.0/16', { cidrBlockName: 'Temp Block' })], - }); - - const vpc2 = new vpc.VpcV2(stack, 'VPC2', { - primaryAddressBlock: vpc.IpAddresses.ipv4('10.2.0.0/16'), - secondaryAddressBlocks: [vpc.IpAddresses.ipv4('10.3.0.0/16', { cidrBlockName: 'Temp Block' })], - }); - - expect(() => { - new route.VPCPeeringConnection(stack, 'TestPeering', { - isCrossAccount: false, - requestorVpc: vpc1, - acceptorVpc: vpc2, - }); - }).not.toThrow(); + const template = Template.fromStack(stack); + template.hasResourceProperties('AWS::EC2::VPCPeeringConnection', { + VpcId: { + 'Fn::GetAtt': ['VpcAAD85CA4C', 'VpcId'], + }, + PeerVpcId: { + 'Fn::GetAtt': ['VpcB98A08B07', 'VpcId'], + }, + PeerOwnerId: { Ref: 'AWS::AccountId' }, + PeerRegion: { Ref: 'AWS::Region' }, }); }); -}); +}); \ No newline at end of file From 9f96a92b19a2a4de86c641bdd64ee0b84c501082 Mon Sep 17 00:00:00 2001 From: Kailey Chen Date: Thu, 10 Oct 2024 15:40:35 -0700 Subject: [PATCH 12/34] error msg modifications & use ownerAccountId --- packages/@aws-cdk/aws-ec2-alpha/lib/route.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts b/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts index fbde39355c791..34bb5f19c7419 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts @@ -1,6 +1,6 @@ import { CfnEIP, CfnEgressOnlyInternetGateway, CfnInternetGateway, CfnNatGateway, CfnVPCPeeringConnection, CfnRoute, CfnRouteTable, CfnVPCGatewayAttachment, CfnVPNGateway, CfnVPNGatewayRoutePropagation, GatewayVpcEndpoint, IRouteTable, IVpcEndpoint, RouterType } from 'aws-cdk-lib/aws-ec2'; import { Construct, IDependable } from 'constructs'; -import { Annotations, Duration, IResource, Resource, Stack } from 'aws-cdk-lib/core'; +import { Annotations, Duration, IResource, Resource } from 'aws-cdk-lib/core'; import { IVpcV2, VPNGatewayV2Options } from './vpc-v2-base'; import { NetworkUtils, allRouteTableIds, CidrBlock } from './util'; import { ISubnetV2 } from './subnet-v2'; @@ -462,7 +462,7 @@ export class VPCPeeringConnection extends Resource implements IRouteTarget { this.routerType = RouterType.VPC_PEERING_CONNECTION; - const isCrossAccount = Stack.of(props.requestorVpc).account !== Stack.of(props.acceptorVpc).account; + const isCrossAccount = props.requestorVpc.ownerAccountId !== props.acceptorVpc.ownerAccountId; if (!isCrossAccount && props.peerRoleArn) { Annotations.of(this).addWarning( @@ -471,13 +471,12 @@ export class VPCPeeringConnection extends Resource implements IRouteTarget { } if (isCrossAccount && !props.peerRoleArn) { - throw new Error('Cross account VPC peering requires a peerArnId'); + throw new Error('Cross account VPC peering requires peerRoleArn'); } - // TODO: do we still want to validate? already have this check in the vpc peering const overlap = this.validateVpcCidrOverlap(props.requestorVpc, props.acceptorVpc); if (overlap) { - throw new Error('CIDR block should not overlap with existing subnet blocks'); + throw new Error('CIDR block should not overlap with each other for establishing a peering connection'); } this.resource = new CfnVPCPeeringConnection(this, 'VPCPeeringConnection', { From 57df8ed10f2ccc78f4a788b17ec1e7d250350766 Mon Sep 17 00:00:00 2001 From: Kailey Chen Date: Thu, 10 Oct 2024 18:45:27 -0700 Subject: [PATCH 13/34] update policies and warning --- packages/@aws-cdk/aws-ec2-alpha/lib/route.ts | 5 +++-- packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2-base.ts | 13 +++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts b/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts index 34bb5f19c7419..55da182770ed6 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts @@ -346,7 +346,7 @@ export class VPNGatewayV2 extends Resource implements IRouteTarget { const routeTableIds = allRouteTableIds(subnets); if (routeTableIds.length === 0) { - Annotations.of(this).addWarningV2('@aws-cdk:aws-ec2-elpha:enableVpnGatewayV2', `No subnets matching selection: '${JSON.stringify(vpnRoutePropagation)}'. Select other subnets to add routes to.`); + Annotations.of(scope).addWarningV2('@aws-cdk:aws-ec2-elpha:enableVpnGatewayV2', `No subnets matching selection: '${JSON.stringify(vpnRoutePropagation)}'. Select other subnets to add routes to.`); } this._routePropagation = new CfnVPNGatewayRoutePropagation(this, 'RoutePropagation', { @@ -465,7 +465,8 @@ export class VPCPeeringConnection extends Resource implements IRouteTarget { const isCrossAccount = props.requestorVpc.ownerAccountId !== props.acceptorVpc.ownerAccountId; if (!isCrossAccount && props.peerRoleArn) { - Annotations.of(this).addWarning( + Annotations.of(scope).addWarningV2( + '@aws-cdk/aws-ec2-alpha:peerRoleArnIgnored', 'This is a same account peering, peerRoleArn is not needed and will be ignored', ); } diff --git a/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2-base.ts b/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2-base.ts index 837b7a88eb90c..9a54a2acd2701 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2-base.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2-base.ts @@ -144,11 +144,11 @@ export interface IVpcV2 extends IVpc { addNatGateway(options: NatGatewayOptions): NatGateway; /** - * Adds a new role to VPC account + * Adds a new role to acceptor VPC account * A cross account role is required for the VPC to peer with another account. * For more information, see the {@link https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/peer-with-vpc-in-another-account.html}. */ - createAcceptorVpcRole(requestorAccountId: string, acceptorAccountId: string, acceptorVpcRegion: string): Role; + createAcceptorVpcRole(requestorAccountId: string): Role; /** * Creates a new peering connection @@ -486,25 +486,26 @@ export abstract class VpcV2Base extends Resource implements IVpcV2 { /** * Creates peering connection role for acceptor VPC */ - public createAcceptorVpcRole(requestorAccountId: string, acceptorAccountId: string, acceptorVpcRegion: string): Role { + public createAcceptorVpcRole(requestorAccountId: string): Role { const peeringRole = new Role(this, 'VpcPeeringRole', { assumedBy: new AccountPrincipal(requestorAccountId), + roleName: 'VpcPeeringRole', description: 'Restrictive role for VPC peering', }); peeringRole.addToPolicy(new PolicyStatement({ effect: Effect.ALLOW, actions: ['ec2:AcceptVpcPeeringConnection'], - resources: [`arn:${Aws.PARTITION}:ec2:${acceptorVpcRegion}:${requestorAccountId}:vpc/${acceptorAccountId}`], + resources: [`arn:${Aws.PARTITION}:ec2:${this.region}:${this.ownerAccountId}:vpc/${this.vpcId}`], })); peeringRole.addToPolicy(new PolicyStatement({ actions: ['ec2:AcceptVpcPeeringConnection'], effect: Effect.ALLOW, - resources: [`arn:${Aws.PARTITION}:ec2:${acceptorVpcRegion}:${requestorAccountId}:vpc-peering-connection/*`], + resources: [`arn:${Aws.PARTITION}:ec2:${this.region}:${this.ownerAccountId}:vpc-peering-connection/*`], conditions: { StringEquals: { - 'ec2:AccepterVpc': `arn:${Aws.PARTITION}:ec2:${acceptorVpcRegion}:${requestorAccountId}:vpc/${acceptorAccountId}`, + 'ec2:AccepterVpc': `arn:${Aws.PARTITION}:ec2:${this.region}:${this.ownerAccountId}:vpc/${this.vpcId}`, }, }, })); From 5299751d8cff016d7eaea9300bb34d8d9a004877 Mon Sep 17 00:00:00 2001 From: Kailey Chen Date: Thu, 10 Oct 2024 18:45:54 -0700 Subject: [PATCH 14/34] add tests and integration tests --- ...outev2-vpcpeerconnection-alpha.assets.json | 4 +- ...tev2-vpcpeerconnection-alpha.template.json | 78 +++++------ .../integ.route-v2.js.snapshot/manifest.json | 34 ++--- .../test/integ.route-v2.js.snapshot/tree.json | 128 ++++++++---------- .../aws-ec2-alpha/test/integ.route-v2.ts | 24 ++-- .../@aws-cdk/aws-ec2-alpha/test/route.test.ts | 83 +++++++++++- .../aws-ec2-alpha/test/vpc-add-method.test.ts | 17 +++ 7 files changed, 219 insertions(+), 149 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-vpcpeerconnection-alpha.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-vpcpeerconnection-alpha.assets.json index 47f4987a1309b..d0ef6b320e0ed 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-vpcpeerconnection-alpha.assets.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-vpcpeerconnection-alpha.assets.json @@ -1,7 +1,7 @@ { "version": "38.0.1", "files": { - "4fc8e38f9f8c75b7937e32a2d8924346cf1648878ab74ccf8083f3c7958cf89a": { + "247a442d4f157f616d8ab3238140453b7c58c3b66472c23fc213101c15b136d2": { "source": { "path": "aws-cdk-routev2-vpcpeerconnection-alpha.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "4fc8e38f9f8c75b7937e32a2d8924346cf1648878ab74ccf8083f3c7958cf89a.json", + "objectKey": "247a442d4f157f616d8ab3238140453b7c58c3b66472c23fc213101c15b136d2.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-vpcpeerconnection-alpha.template.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-vpcpeerconnection-alpha.template.json index 13d920985631c..501b1e51df0d9 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-vpcpeerconnection-alpha.template.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-vpcpeerconnection-alpha.template.json @@ -21,6 +21,26 @@ } } }, + "vpcpccrossAccountCrossRegionPeeringVPCPeeringConnection89B302C8": { + "Type": "AWS::EC2::VPCPeeringConnection", + "Properties": { + "PeerOwnerId": "012345678910", + "PeerRegion": "us-west-2", + "PeerRoleArn": "arn:aws:iam::012345678910:role/VpcPeeringRole", + "PeerVpcId": { + "Fn::GetAtt": [ + "secondVPCFBB45262", + "VpcId" + ] + }, + "VpcId": { + "Fn::GetAtt": [ + "vpcpc6CAE1A04", + "VpcId" + ] + } + } + }, "TestRoottableRouteTableFA28AA38": { "Type": "AWS::EC2::RouteTable", "Properties": { @@ -44,15 +64,13 @@ }, "VpcPeeringConnectionId": { "Fn::GetAtt": [ - "crossAccountCrossRegionPeeringPeeringConnection1503A608", + "vpcpccrossAccountCrossRegionPeeringVPCPeeringConnection89B302C8", "Id" ] } }, "DependsOn": [ - "crossAccountCrossRegionPeeringPeeringConnection1503A608", - "crossAccountCrossRegionPeeringPeerRoleDefaultPolicy4F428B82", - "crossAccountCrossRegionPeeringPeerRoleA26F8D4F" + "vpcpccrossAccountCrossRegionPeeringVPCPeeringConnection89B302C8" ] }, "secondVPCFBB45262": { @@ -76,7 +94,7 @@ } } }, - "crossAccountCrossRegionPeeringPeerRoleA26F8D4F": { + "secondVPCVpcPeeringRoleB5D6E33D": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { @@ -93,11 +111,7 @@ { "Ref": "AWS::Partition" }, - ":iam::", - { - "Ref": "AWS::AccountId" - }, - ":root" + ":iam::987654321098:root" ] ] } @@ -106,16 +120,17 @@ ], "Version": "2012-10-17" }, - "RoleName": "VPCPeeringRole-crossAccountCrossRegionPeering" + "Description": "Restrictive role for VPC peering", + "RoleName": "VpcPeeringRole" } }, - "crossAccountCrossRegionPeeringPeerRoleDefaultPolicy4F428B82": { + "secondVPCVpcPeeringRoleDefaultPolicy2274B424": { "Type": "AWS::IAM::Policy", "Properties": { "PolicyDocument": { "Statement": [ { - "Action": "ec2:acceptVpcPeeringConnection", + "Action": "ec2:AcceptVpcPeeringConnection", "Effect": "Allow", "Resource": { "Fn::Join": [ @@ -125,7 +140,7 @@ { "Ref": "AWS::Partition" }, - ":ec2:us-west-2:123456789012:vpc/", + ":ec2:us-west-2:012345678910:vpc/", { "Fn::GetAtt": [ "secondVPCFBB45262", @@ -137,7 +152,7 @@ } }, { - "Action": "ec2:acceptVpcPeeringConnection", + "Action": "ec2:AcceptVpcPeeringConnection", "Condition": { "StringEquals": { "ec2:AccepterVpc": { @@ -148,7 +163,7 @@ { "Ref": "AWS::Partition" }, - ":ec2:us-west-2:123456789012:vpc/", + ":ec2:us-west-2:012345678910:vpc/", { "Fn::GetAtt": [ "secondVPCFBB45262", @@ -169,7 +184,7 @@ { "Ref": "AWS::Partition" }, - ":ec2:us-west-2:123456789012:vpc-peering-connection/*" + ":ec2:us-west-2:012345678910:vpc-peering-connection/*" ] ] } @@ -177,38 +192,13 @@ ], "Version": "2012-10-17" }, - "PolicyName": "crossAccountCrossRegionPeeringPeerRoleDefaultPolicy4F428B82", + "PolicyName": "secondVPCVpcPeeringRoleDefaultPolicy2274B424", "Roles": [ { - "Ref": "crossAccountCrossRegionPeeringPeerRoleA26F8D4F" + "Ref": "secondVPCVpcPeeringRoleB5D6E33D" } ] } - }, - "crossAccountCrossRegionPeeringPeeringConnection1503A608": { - "Type": "AWS::EC2::VPCPeeringConnection", - "Properties": { - "PeerOwnerId": "123456789012", - "PeerRegion": "us-west-2", - "PeerRoleArn": { - "Fn::GetAtt": [ - "crossAccountCrossRegionPeeringPeerRoleA26F8D4F", - "Arn" - ] - }, - "PeerVpcId": { - "Fn::GetAtt": [ - "secondVPCFBB45262", - "VpcId" - ] - }, - "VpcId": { - "Fn::GetAtt": [ - "vpcpc6CAE1A04", - "VpcId" - ] - } - } } }, "Parameters": { diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/manifest.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/manifest.json index 6a6473586d703..502edd2ff6612 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/manifest.json @@ -306,6 +306,12 @@ "aws-cdk-routev2-virtualprivategw-alpha.assets" ], "metadata": { + "/aws-cdk-routev2-virtualprivategw-alpha": [ + { + "type": "aws:cdk:warning", + "data": "No subnets matching selection: '[]'. Select other subnets to add routes to. [ack: @aws-cdk:aws-ec2-elpha:enableVpnGatewayV2]" + } + ], "/aws-cdk-routev2-virtualprivategw-alpha/vpgw/Resource": [ { "type": "aws:cdk:logicalId", @@ -342,12 +348,6 @@ "data": "vpgwSubnetRouteTableAssociation49921F90" } ], - "/aws-cdk-routev2-virtualprivategw-alpha/testVPGW": [ - { - "type": "aws:cdk:warning", - "data": "No subnets matching selection: '[]'. Select other subnets to add routes to. [ack: @aws-cdk:aws-ec2-elpha:enableVpnGatewayV2]" - } - ], "/aws-cdk-routev2-virtualprivategw-alpha/testVPGW/IGW": [ { "type": "aws:cdk:logicalId", @@ -687,7 +687,7 @@ "notificationArns": [], "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/4fc8e38f9f8c75b7937e32a2d8924346cf1648878ab74ccf8083f3c7958cf89a.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/247a442d4f157f616d8ab3238140453b7c58c3b66472c23fc213101c15b136d2.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -716,6 +716,12 @@ "data": "vpcpcAmazonIpv66504EEB2" } ], + "/aws-cdk-routev2-vpcpeerconnection-alpha/vpcpc/crossAccountCrossRegionPeering/VPCPeeringConnection": [ + { + "type": "aws:cdk:logicalId", + "data": "vpcpccrossAccountCrossRegionPeeringVPCPeeringConnection89B302C8" + } + ], "/aws-cdk-routev2-vpcpeerconnection-alpha/TestRoottable/RouteTable": [ { "type": "aws:cdk:logicalId", @@ -740,22 +746,16 @@ "data": "secondVPCTempBlock7F6107B6" } ], - "/aws-cdk-routev2-vpcpeerconnection-alpha/crossAccountCrossRegionPeering/PeerRole/Resource": [ - { - "type": "aws:cdk:logicalId", - "data": "crossAccountCrossRegionPeeringPeerRoleA26F8D4F" - } - ], - "/aws-cdk-routev2-vpcpeerconnection-alpha/crossAccountCrossRegionPeering/PeerRole/DefaultPolicy/Resource": [ + "/aws-cdk-routev2-vpcpeerconnection-alpha/secondVPC/VpcPeeringRole/Resource": [ { "type": "aws:cdk:logicalId", - "data": "crossAccountCrossRegionPeeringPeerRoleDefaultPolicy4F428B82" + "data": "secondVPCVpcPeeringRoleB5D6E33D" } ], - "/aws-cdk-routev2-vpcpeerconnection-alpha/crossAccountCrossRegionPeering/PeeringConnection": [ + "/aws-cdk-routev2-vpcpeerconnection-alpha/secondVPC/VpcPeeringRole/DefaultPolicy/Resource": [ { "type": "aws:cdk:logicalId", - "data": "crossAccountCrossRegionPeeringPeeringConnection1503A608" + "data": "secondVPCVpcPeeringRoleDefaultPolicy2274B424" } ], "/aws-cdk-routev2-vpcpeerconnection-alpha/BootstrapVersion": [ diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/tree.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/tree.json index 64125ce6f223f..1c960c03406fd 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/tree.json @@ -1754,6 +1754,44 @@ "fqn": "aws-cdk-lib.aws_ec2.CfnVPCCidrBlock", "version": "0.0.0" } + }, + "crossAccountCrossRegionPeering": { + "id": "crossAccountCrossRegionPeering", + "path": "aws-cdk-routev2-vpcpeerconnection-alpha/vpcpc/crossAccountCrossRegionPeering", + "children": { + "VPCPeeringConnection": { + "id": "VPCPeeringConnection", + "path": "aws-cdk-routev2-vpcpeerconnection-alpha/vpcpc/crossAccountCrossRegionPeering/VPCPeeringConnection", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPCPeeringConnection", + "aws:cdk:cloudformation:props": { + "peerOwnerId": "012345678910", + "peerRegion": "us-west-2", + "peerRoleArn": "arn:aws:iam::012345678910:role/VpcPeeringRole", + "peerVpcId": { + "Fn::GetAtt": [ + "secondVPCFBB45262", + "VpcId" + ] + }, + "vpcId": { + "Fn::GetAtt": [ + "vpcpc6CAE1A04", + "VpcId" + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnVPCPeeringConnection", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2-alpha.VPCPeeringConnection", + "version": "0.0.0" + } } }, "constructInfo": { @@ -1803,7 +1841,7 @@ }, "vpcPeeringConnectionId": { "Fn::GetAtt": [ - "crossAccountCrossRegionPeeringPeeringConnection1503A608", + "vpcpccrossAccountCrossRegionPeeringVPCPeeringConnection89B302C8", "Id" ] } @@ -1866,24 +1904,14 @@ "fqn": "aws-cdk-lib.aws_ec2.CfnVPCCidrBlock", "version": "0.0.0" } - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-ec2-alpha.VpcV2", - "version": "0.0.0" - } - }, - "crossAccountCrossRegionPeering": { - "id": "crossAccountCrossRegionPeering", - "path": "aws-cdk-routev2-vpcpeerconnection-alpha/crossAccountCrossRegionPeering", - "children": { - "PeerRole": { - "id": "PeerRole", - "path": "aws-cdk-routev2-vpcpeerconnection-alpha/crossAccountCrossRegionPeering/PeerRole", + }, + "VpcPeeringRole": { + "id": "VpcPeeringRole", + "path": "aws-cdk-routev2-vpcpeerconnection-alpha/secondVPC/VpcPeeringRole", "children": { - "ImportPeerRole": { - "id": "ImportPeerRole", - "path": "aws-cdk-routev2-vpcpeerconnection-alpha/crossAccountCrossRegionPeering/PeerRole/ImportPeerRole", + "ImportVpcPeeringRole": { + "id": "ImportVpcPeeringRole", + "path": "aws-cdk-routev2-vpcpeerconnection-alpha/secondVPC/VpcPeeringRole/ImportVpcPeeringRole", "constructInfo": { "fqn": "aws-cdk-lib.Resource", "version": "0.0.0" @@ -1891,7 +1919,7 @@ }, "Resource": { "id": "Resource", - "path": "aws-cdk-routev2-vpcpeerconnection-alpha/crossAccountCrossRegionPeering/PeerRole/Resource", + "path": "aws-cdk-routev2-vpcpeerconnection-alpha/secondVPC/VpcPeeringRole/Resource", "attributes": { "aws:cdk:cloudformation:type": "AWS::IAM::Role", "aws:cdk:cloudformation:props": { @@ -1909,11 +1937,7 @@ { "Ref": "AWS::Partition" }, - ":iam::", - { - "Ref": "AWS::AccountId" - }, - ":root" + ":iam::987654321098:root" ] ] } @@ -1922,7 +1946,8 @@ ], "Version": "2012-10-17" }, - "roleName": "VPCPeeringRole-crossAccountCrossRegionPeering" + "description": "Restrictive role for VPC peering", + "roleName": "VpcPeeringRole" } }, "constructInfo": { @@ -1932,18 +1957,18 @@ }, "DefaultPolicy": { "id": "DefaultPolicy", - "path": "aws-cdk-routev2-vpcpeerconnection-alpha/crossAccountCrossRegionPeering/PeerRole/DefaultPolicy", + "path": "aws-cdk-routev2-vpcpeerconnection-alpha/secondVPC/VpcPeeringRole/DefaultPolicy", "children": { "Resource": { "id": "Resource", - "path": "aws-cdk-routev2-vpcpeerconnection-alpha/crossAccountCrossRegionPeering/PeerRole/DefaultPolicy/Resource", + "path": "aws-cdk-routev2-vpcpeerconnection-alpha/secondVPC/VpcPeeringRole/DefaultPolicy/Resource", "attributes": { "aws:cdk:cloudformation:type": "AWS::IAM::Policy", "aws:cdk:cloudformation:props": { "policyDocument": { "Statement": [ { - "Action": "ec2:acceptVpcPeeringConnection", + "Action": "ec2:AcceptVpcPeeringConnection", "Effect": "Allow", "Resource": { "Fn::Join": [ @@ -1953,7 +1978,7 @@ { "Ref": "AWS::Partition" }, - ":ec2:us-west-2:123456789012:vpc/", + ":ec2:us-west-2:012345678910:vpc/", { "Fn::GetAtt": [ "secondVPCFBB45262", @@ -1965,7 +1990,7 @@ } }, { - "Action": "ec2:acceptVpcPeeringConnection", + "Action": "ec2:AcceptVpcPeeringConnection", "Condition": { "StringEquals": { "ec2:AccepterVpc": { @@ -1976,7 +2001,7 @@ { "Ref": "AWS::Partition" }, - ":ec2:us-west-2:123456789012:vpc/", + ":ec2:us-west-2:012345678910:vpc/", { "Fn::GetAtt": [ "secondVPCFBB45262", @@ -1997,7 +2022,7 @@ { "Ref": "AWS::Partition" }, - ":ec2:us-west-2:123456789012:vpc-peering-connection/*" + ":ec2:us-west-2:012345678910:vpc-peering-connection/*" ] ] } @@ -2005,10 +2030,10 @@ ], "Version": "2012-10-17" }, - "policyName": "crossAccountCrossRegionPeeringPeerRoleDefaultPolicy4F428B82", + "policyName": "secondVPCVpcPeeringRoleDefaultPolicy2274B424", "roles": [ { - "Ref": "crossAccountCrossRegionPeeringPeerRoleA26F8D4F" + "Ref": "secondVPCVpcPeeringRoleB5D6E33D" } ] } @@ -2029,43 +2054,10 @@ "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } - }, - "PeeringConnection": { - "id": "PeeringConnection", - "path": "aws-cdk-routev2-vpcpeerconnection-alpha/crossAccountCrossRegionPeering/PeeringConnection", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::EC2::VPCPeeringConnection", - "aws:cdk:cloudformation:props": { - "peerOwnerId": "123456789012", - "peerRegion": "us-west-2", - "peerRoleArn": { - "Fn::GetAtt": [ - "crossAccountCrossRegionPeeringPeerRoleA26F8D4F", - "Arn" - ] - }, - "peerVpcId": { - "Fn::GetAtt": [ - "secondVPCFBB45262", - "VpcId" - ] - }, - "vpcId": { - "Fn::GetAtt": [ - "vpcpc6CAE1A04", - "VpcId" - ] - } - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_ec2.CfnVPCPeeringConnection", - "version": "0.0.0" - } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2-alpha.VPCPeeringConnection", + "fqn": "@aws-cdk/aws-ec2-alpha.VpcV2", "version": "0.0.0" } }, diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.ts b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.ts index e475968219533..891f7558d6625 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.ts @@ -115,19 +115,19 @@ const dynamoEndpoint = new GatewayVpcEndpoint(stacks.dynamodb, 'testDynamoEndpoi }); routeTables.dynamodb.addRoute('dynamoRoute', '0.0.0.0/0', { endpoint: dynamoEndpoint }); -// const vpc2 = new vpc_v2.VpcV2(stacks.vpcpc, 'secondVPC', { -// primaryAddressBlock: vpc_v2.IpAddresses.ipv4('10.1.0.0/16'), -// secondaryAddressBlocks: [vpc_v2.IpAddresses.ipv4('10.2.0.0/16', { cidrBlockName: 'Temp Block' })], -// }); +vpcs.vpcpc2 = new vpc_v2.VpcV2(stacks.vpcpc, 'secondVPC', { + primaryAddressBlock: vpc_v2.IpAddresses.ipv4('10.1.0.0/16'), + secondaryAddressBlocks: [vpc_v2.IpAddresses.ipv4('10.2.0.0/16', { cidrBlockName: 'Temp Block' })], + region: 'us-west-2', + ownerAccountId: '012345678910', +}); +vpcs.vpcpc2.createAcceptorVpcRole('987654321098'); -// const peeringConnection = new VPCPeeringConnection(stacks.vpcpc, 'crossAccountCrossRegionPeering', { -// isCrossAccount: true, -// requestorVpc: vpcs.vpcpc, -// acceptorVpc: vpc2, -// acceptorAccountId: '123456789012', -// acceptorRegion: 'us-west-2', -// }); -// routeTables.vpcpc.addRoute('vpcPeeringRoute', '0.0.0.0/0', { gateway: peeringConnection }); +const peeringConnection = vpcs.vpcpc.createPeeringConnection('crossAccountCrossRegionPeering', { + acceptorVpc: vpcs.vpcpc2, + peerRoleArn: 'arn:aws:iam::012345678910:role/VpcPeeringRole', +}); +routeTables.vpcpc.addRoute('vpcPeeringRoute', '0.0.0.0/0', { gateway: peeringConnection }); var i = 0; for (const stackName in stacks) { diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts b/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts index 34dd3d4994777..9e8f717dff3a6 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts @@ -3,7 +3,7 @@ import * as vpc from '../lib/vpc-v2'; import * as subnet from '../lib/subnet-v2'; import { CfnEIP, GatewayVpcEndpoint, GatewayVpcEndpointAwsService, SubnetType, VpnConnectionType } from 'aws-cdk-lib/aws-ec2'; import * as route from '../lib/route'; -import { Template } from 'aws-cdk-lib/assertions'; +import { Annotations, Template } from 'aws-cdk-lib/assertions'; describe('EC2 Routing', () => { let stack: cdk.Stack; @@ -519,6 +519,7 @@ describe('VPCPeeringConnection', () => { let stack: cdk.Stack; let vpcA: vpc.VpcV2; let vpcB: vpc.VpcV2; + let vpcC: vpc.VpcV2; beforeEach(() => { const app = new cdk.App({ @@ -526,32 +527,102 @@ describe('VPCPeeringConnection', () => { '@aws-cdk/core:newStyleStackSynthesis': false, }, }); - stack = new cdk.Stack(app, 'VpcStack'); + stack = new cdk.Stack(app, 'VpcStack', { env: { region: 'us-east-1' } }); vpcA = new vpc.VpcV2(stack, 'VpcA', { primaryAddressBlock: vpc.IpAddresses.ipv4('10.0.0.0/16'), secondaryAddressBlocks: [vpc.IpAddresses.ipv4('10.1.0.0/16', { cidrBlockName: 'TempSecondaryBlock' })], + region: 'us-east-1', }); vpcB = new vpc.VpcV2(stack, 'VpcB', { primaryAddressBlock: vpc.IpAddresses.ipv4('10.2.0.0/16'), + ownerAccountId: '012345678910', + }); + vpcC = new vpc.VpcV2(stack, 'VpcC', { + primaryAddressBlock: vpc.IpAddresses.ipv4('10.1.0.0/16'), + region: 'us-west-2', + ownerAccountId: '012345678910', }); }); - test('Creates a VPC peering connection', () => { + test('Creates a cross account VPC peering connection', () => { new route.VPCPeeringConnection(stack, 'TestPeeringConnection', { requestorVpc: vpcA, acceptorVpc: vpcB, + peerRoleArn: 'arn:aws:iam::012345678910:role/VpcPeeringRole', }); - const template = Template.fromStack(stack); template.hasResourceProperties('AWS::EC2::VPCPeeringConnection', { + PeerRoleArn: 'arn:aws:iam::012345678910:role/VpcPeeringRole', VpcId: { 'Fn::GetAtt': ['VpcAAD85CA4C', 'VpcId'], }, PeerVpcId: { 'Fn::GetAtt': ['VpcB98A08B07', 'VpcId'], }, - PeerOwnerId: { Ref: 'AWS::AccountId' }, - PeerRegion: { Ref: 'AWS::Region' }, + PeerOwnerId: '012345678910', + PeerRegion: 'us-east-1', + }); + }); + + test('Creates a cross region VPC peering connection', () => { + new route.VPCPeeringConnection(stack, 'TestCrossRegionPeeringConnection', { + requestorVpc: vpcB, + acceptorVpc: vpcC, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::EC2::VPCPeeringConnection', { + VpcId: { + 'Fn::GetAtt': ['VpcB98A08B07', 'VpcId'], + }, + PeerVpcId: { + 'Fn::GetAtt': ['VpcC211819BA', 'VpcId'], + }, + PeerOwnerId: '012345678910', + PeerRegion: 'us-west-2', + }); + }); + + test('Warns when peerRoleArn is provided for same account peering', () => { + new route.VPCPeeringConnection(stack, 'TestPeeringConnection', { + requestorVpc: vpcB, + acceptorVpc: vpcC, + peerRoleArn: 'arn:aws:iam::123456789012:role/unnecessary-role', }); + + Annotations.fromStack(stack).hasWarning('*', 'This is a same account peering, peerRoleArn is not needed and will be ignored [ack: @aws-cdk/aws-ec2-alpha:peerRoleArnIgnored]'); + }); + + test('Throws error when peerRoleArn is not provided for cross-account peering', () => { + expect(() => { + new route.VPCPeeringConnection(stack, 'TestCrossAccountPeeringConnection', { + requestorVpc: vpcA, + acceptorVpc: vpcB, + }); + }).toThrow(/Cross account VPC peering requires peerRoleArn/); + }); + + test('CIDR block overlap with secondary CIDR block should throw error', () => { + expect(() => { + new route.VPCPeeringConnection(stack, 'TestPeering', { + requestorVpc: vpcA, + acceptorVpc: vpcC, + peerRoleArn: 'arn:aws:iam::123456789012:role/unnecessary-role', + }); + }).toThrow(/CIDR block should not overlap with each other for establishing a peering connection/); + }); + + test('CIDR block overlap should throw error', () => { + const vpcD = new vpc.VpcV2(stack, 'VpcD', { + primaryAddressBlock: vpc.IpAddresses.ipv4('10.0.0.0/16'), + region: 'us-east-1', + }); + + expect(() => { + new route.VPCPeeringConnection(stack, 'TestPeering', { + requestorVpc: vpcA, + acceptorVpc: vpcD, + peerRoleArn: 'arn:aws:iam::123456789012:role/unnecessary-role', + }); + }).toThrow(/CIDR block should not overlap with each other for establishing a peering connection/); }); }); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/vpc-add-method.test.ts b/packages/@aws-cdk/aws-ec2-alpha/test/vpc-add-method.test.ts index 9ac84c7646237..c9cffbc8b471e 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/vpc-add-method.test.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/test/vpc-add-method.test.ts @@ -398,4 +398,21 @@ describe('Vpc V2 with full control', () => { }).toThrow('The VPN Gateway has already been enabled.'); }); + test('createAcceptorVpcRole creates a restricted role', () => { + myVpc.createAcceptorVpcRole('123456789012'); + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Role', { + AssumeRolePolicyDocument: { + Statement: [ + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { + AWS: { 'Fn::Join': ['', ['arn:', { Ref: 'AWS::Partition' }, ':iam::123456789012:root']] }, + }, + }, + ], + Version: '2012-10-17', + }, + }); + }); }); \ No newline at end of file From 0143dbcf4e6b66972adc706ef039bfe17048092f Mon Sep 17 00:00:00 2001 From: Kailey Chen Date: Thu, 10 Oct 2024 19:11:14 -0700 Subject: [PATCH 15/34] add readme --- packages/@aws-cdk/aws-ec2-alpha/README.md | 42 ++++++++++++++--------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/README.md b/packages/@aws-cdk/aws-ec2-alpha/README.md index f651fbb47b765..4904d3ba51b7f 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/README.md +++ b/packages/@aws-cdk/aws-ec2-alpha/README.md @@ -235,37 +235,45 @@ new Route(this, 'DynamoDBRoute', { VPC peering connection allows you to connect two VPCs and route traffic between them using private IP addresses. The VpcV2 construct supports creating VPC peering connections through the `VPCPeeringConnection` construct from the `route` module. -Here's an example of how to create a VPC peering connection between two VPCs: - - -Note that for cross-account peering, you'll need to ensure that the peering request is accepted in the peer account. For more information see [Accept or reject a VPC peering connection](https://docs.aws.amazon.com/vpc/latest/peering/accept-vpc-peering-connection.html). - -To add routes for the peering connection to specific subnets, you can use the addRoute method of the RouteTable construct. +``` ## Adding Egress-Only Internet Gateway to VPC From d31b6ca4653e1c9745e9dd5857e5870f056d548c Mon Sep 17 00:00:00 2001 From: Kailey Chen Date: Fri, 11 Oct 2024 09:24:34 -0700 Subject: [PATCH 16/34] fix lint fail due to ordering in readme --- packages/@aws-cdk/aws-ec2-alpha/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/README.md b/packages/@aws-cdk/aws-ec2-alpha/README.md index 4904d3ba51b7f..072b6faab268d 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/README.md +++ b/packages/@aws-cdk/aws-ec2-alpha/README.md @@ -237,7 +237,7 @@ VPC peering connection allows you to connect two VPCs and route traffic between This is an example of how to create a VPC peering connection between two VPCs. The process involves 3 main steps: -1. **Acceptor Account Stack** +**Step 1: Acceptor Account Stack** Create a restrictive IAM role in the acceptor VPC account. This role will be used to grant limited permissions for accepting the peering request from the requestor account. @@ -251,7 +251,7 @@ const acceptorVpc = new VpcV2(this, 'VpcA', { const acceptorRoleArn = acceptorVpc.createAcceptorVpcRole('111') ``` -2. **Requestor Account Stack** +**Step 2: Requestor Account Stack** Initiate the peering connection request from the requestor VPC. @@ -263,7 +263,7 @@ const peeringConnection = new VPCPeeringConnection(this, 'crossAccountCrossRegio }); ``` -3. **Route Table Configuration** +**Step 3: Route Table Configuration** Update route tables in both VPCs to enable traffic flow. If a route is added to the requestor stack, information will be able to flow from the requestor VPC to the acceptor VPC, but not in the reverse direction. For bi-directional communication, routes need to be added in both VPCs from their respective stacks. From 751530c5a4752eb1b6d70ba0e99f60bbb55325e5 Mon Sep 17 00:00:00 2001 From: Kailey Chen Date: Fri, 11 Oct 2024 12:10:19 -0700 Subject: [PATCH 17/34] update readme errors --- packages/@aws-cdk/aws-ec2-alpha/README.md | 32 ++++++++++++++++------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/README.md b/packages/@aws-cdk/aws-ec2-alpha/README.md index 072b6faab268d..a2a9804407741 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/README.md +++ b/packages/@aws-cdk/aws-ec2-alpha/README.md @@ -242,32 +242,46 @@ This is an example of how to create a VPC peering connection between two VPCs. T Create a restrictive IAM role in the acceptor VPC account. This role will be used to grant limited permissions for accepting the peering request from the requestor account. ```ts +// Step 1: Acceptor Account Stack const stack = new Stack(); const acceptorVpc = new VpcV2(this, 'VpcA', { primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/16'), }); -const acceptorRoleArn = acceptorVpc.createAcceptorVpcRole('111') +const acceptorRoleArn = acceptorVpc.createAcceptorVpcRole('987654321098') ``` **Step 2: Requestor Account Stack** Initiate the peering connection request from the requestor VPC. -```ts -const peeringConnection = new VPCPeeringConnection(this, 'crossAccountCrossRegionPeering', { - requestorVpc: acceptorVpc, - acceptorVpc: requestorVpc, - peerRoleArn: acceptorRoleArn, -}); -``` - **Step 3: Route Table Configuration** Update route tables in both VPCs to enable traffic flow. If a route is added to the requestor stack, information will be able to flow from the requestor VPC to the acceptor VPC, but not in the reverse direction. For bi-directional communication, routes need to be added in both VPCs from their respective stacks. ```ts +// Step 2: Requestor Account Stack +const stack = new Stack(); + +// TODO: Import acceptorVpc into the requestor stack +const acceptorVpc = new VpcV2(this, 'VpcA', { + primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/16'), +}); + +const acceptorRoleArn = 'arn:aws:iam::123456789012:role/VpcPeeringRole'; + +const requestorVpc = new VpcV2(this, 'VpcB', { + primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'), +}); + +const peeringConnection = new VPCPeeringConnection(this, 'crossAccountCrossRegionPeering', { + requestorVpc: requestorVpc, + acceptorVpc: acceptorVpc, + peerRoleArn: acceptorRoleArn, +}); + +// Step 3: Route Table Configuration const routeTable = new RouteTable(this, 'RouteTable', { vpc: requestorVpc, }); From 98d39d289082cc382699b367c78bd0ba14840aa1 Mon Sep 17 00:00:00 2001 From: Kailey Chen Date: Fri, 11 Oct 2024 12:30:55 -0700 Subject: [PATCH 18/34] update readme peering connection class to function --- packages/@aws-cdk/aws-ec2-alpha/README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/README.md b/packages/@aws-cdk/aws-ec2-alpha/README.md index a2a9804407741..173de2b663b76 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/README.md +++ b/packages/@aws-cdk/aws-ec2-alpha/README.md @@ -275,11 +275,10 @@ const requestorVpc = new VpcV2(this, 'VpcB', { primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'), }); -const peeringConnection = new VPCPeeringConnection(this, 'crossAccountCrossRegionPeering', { - requestorVpc: requestorVpc, +const peeringConnection = requestorVpc.createPeeringConnection('crossAccountCrossRegionPeering', { acceptorVpc: acceptorVpc, peerRoleArn: acceptorRoleArn, -}); +}) // Step 3: Route Table Configuration const routeTable = new RouteTable(this, 'RouteTable', { From 49e2e4f353b0a2847d5ca12f259167fa2894d908 Mon Sep 17 00:00:00 2001 From: Kailey Chen Date: Tue, 15 Oct 2024 10:12:00 -0700 Subject: [PATCH 19/34] add createPeeringConnection test --- .../aws-ec2-alpha/test/vpc-add-method.test.ts | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/vpc-add-method.test.ts b/packages/@aws-cdk/aws-ec2-alpha/test/vpc-add-method.test.ts index c9cffbc8b471e..977705348d7cc 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/vpc-add-method.test.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/test/vpc-add-method.test.ts @@ -415,4 +415,32 @@ describe('Vpc V2 with full control', () => { }, }); }); + + test('createPeeringConnection establishes connection between 2 VPCs', () => { + const acceptorRoleArn = 'arn:aws:iam::123456789012:role/VpcPeeringRole'; + const acceptorVpc = new vpc.VpcV2(stack, 'TestAcceptorVpc', { + primaryAddressBlock: vpc.IpAddresses.ipv4('10.0.0.0/16'), + ownerAccountId: '987654321098', + region: 'us-east-1', + enableDnsHostnames: true, + enableDnsSupport: true, + }); + + myVpc.createPeeringConnection('testPeeringConnection', { + acceptorVpc: acceptorVpc, + peerRoleArn: acceptorRoleArn, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::EC2::VPCPeeringConnection', { + PeerRoleArn: acceptorRoleArn, + VpcId: { + 'Fn::GetAtt': ['TestVpcE77CE678', 'VpcId'], + }, + PeerVpcId: { + 'Fn::GetAtt': ['TestAcceptorVpc4AE3E611', 'VpcId'], + }, + PeerOwnerId: '987654321098', + PeerRegion: 'us-east-1', + }); + }); }); \ No newline at end of file From b8fc4a000c946e12ecfe9e5310cf3e8b668070a3 Mon Sep 17 00:00:00 2001 From: Kailey Chen Date: Tue, 15 Oct 2024 17:07:06 -0700 Subject: [PATCH 20/34] change warning to error when peerRoleArn is defined for same account --- packages/@aws-cdk/aws-ec2-alpha/lib/route.ts | 5 +--- .../@aws-cdk/aws-ec2-alpha/test/route.test.ts | 23 ++++++++++--------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts b/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts index 55da182770ed6..b63fd96b86f78 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts @@ -465,10 +465,7 @@ export class VPCPeeringConnection extends Resource implements IRouteTarget { const isCrossAccount = props.requestorVpc.ownerAccountId !== props.acceptorVpc.ownerAccountId; if (!isCrossAccount && props.peerRoleArn) { - Annotations.of(scope).addWarningV2( - '@aws-cdk/aws-ec2-alpha:peerRoleArnIgnored', - 'This is a same account peering, peerRoleArn is not needed and will be ignored', - ); + throw new Error('peerRoleArn is not needed for same account peering'); } if (isCrossAccount && !props.peerRoleArn) { diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts b/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts index 9e8f717dff3a6..8a459d27a63ca 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts @@ -3,7 +3,7 @@ import * as vpc from '../lib/vpc-v2'; import * as subnet from '../lib/subnet-v2'; import { CfnEIP, GatewayVpcEndpoint, GatewayVpcEndpointAwsService, SubnetType, VpnConnectionType } from 'aws-cdk-lib/aws-ec2'; import * as route from '../lib/route'; -import { Annotations, Template } from 'aws-cdk-lib/assertions'; +import { Template } from 'aws-cdk-lib/assertions'; describe('EC2 Routing', () => { let stack: cdk.Stack; @@ -532,6 +532,7 @@ describe('VPCPeeringConnection', () => { primaryAddressBlock: vpc.IpAddresses.ipv4('10.0.0.0/16'), secondaryAddressBlocks: [vpc.IpAddresses.ipv4('10.1.0.0/16', { cidrBlockName: 'TempSecondaryBlock' })], region: 'us-east-1', + ownerAccountId: '987654321098', }); vpcB = new vpc.VpcV2(stack, 'VpcB', { primaryAddressBlock: vpc.IpAddresses.ipv4('10.2.0.0/16'), @@ -582,14 +583,14 @@ describe('VPCPeeringConnection', () => { }); }); - test('Warns when peerRoleArn is provided for same account peering', () => { - new route.VPCPeeringConnection(stack, 'TestPeeringConnection', { - requestorVpc: vpcB, - acceptorVpc: vpcC, - peerRoleArn: 'arn:aws:iam::123456789012:role/unnecessary-role', - }); - - Annotations.fromStack(stack).hasWarning('*', 'This is a same account peering, peerRoleArn is not needed and will be ignored [ack: @aws-cdk/aws-ec2-alpha:peerRoleArnIgnored]'); + test('Throws error when peerRoleArn is provided for same account peering', () => { + expect(() => { + new route.VPCPeeringConnection(stack, 'TestPeeringConnection', { + requestorVpc: vpcB, + acceptorVpc: vpcC, + peerRoleArn: 'arn:aws:iam::123456789012:role/unnecessary-role', + }); + }).toThrow(/peerRoleArn is not needed for same account peering/); }); test('Throws error when peerRoleArn is not provided for cross-account peering', () => { @@ -606,7 +607,7 @@ describe('VPCPeeringConnection', () => { new route.VPCPeeringConnection(stack, 'TestPeering', { requestorVpc: vpcA, acceptorVpc: vpcC, - peerRoleArn: 'arn:aws:iam::123456789012:role/unnecessary-role', + peerRoleArn: 'arn:aws:iam::012345678910:role/VpcPeeringRole', }); }).toThrow(/CIDR block should not overlap with each other for establishing a peering connection/); }); @@ -621,7 +622,7 @@ describe('VPCPeeringConnection', () => { new route.VPCPeeringConnection(stack, 'TestPeering', { requestorVpc: vpcA, acceptorVpc: vpcD, - peerRoleArn: 'arn:aws:iam::123456789012:role/unnecessary-role', + peerRoleArn: 'arn:aws:iam::012345678910:role/VpcPeeringRole', }); }).toThrow(/CIDR block should not overlap with each other for establishing a peering connection/); }); From e810bd75bbd8d11fc480384760ffb0d19085bbfa Mon Sep 17 00:00:00 2001 From: Kailey Chen Date: Tue, 15 Oct 2024 17:14:59 -0700 Subject: [PATCH 21/34] update description for peerRoleArn --- packages/@aws-cdk/aws-ec2-alpha/lib/route.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts b/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts index b63fd96b86f78..21157547d8af1 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts @@ -185,9 +185,9 @@ export interface VPCPeeringConnectionOptions { readonly acceptorVpc: IVpcV2; /** - * The AWS account ID of the acceptor VPC owner. + * The role arn created in the acceptor account. * - * @default - no roleArn needed if not cross account connection + * @default - no peerRoleArn needed if not cross account connection */ readonly peerRoleArn?: string; From b926d864a3746cef4aaeee2aa55e9ed84c434842 Mon Sep 17 00:00:00 2001 From: Kailey Chen Date: Wed, 16 Oct 2024 10:59:43 -0700 Subject: [PATCH 22/34] add clarity in readme different types of peering --- packages/@aws-cdk/aws-ec2-alpha/README.md | 112 +++++++++++++++++++--- 1 file changed, 99 insertions(+), 13 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/README.md b/packages/@aws-cdk/aws-ec2-alpha/README.md index 173de2b663b76..adf72c59bd805 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/README.md +++ b/packages/@aws-cdk/aws-ec2-alpha/README.md @@ -229,58 +229,124 @@ new Route(this, 'DynamoDBRoute', { destination: '0.0.0.0/0', target: { endpoint: dynamoEndpoint }, }); + ``` ## VPC Peering Connection VPC peering connection allows you to connect two VPCs and route traffic between them using private IP addresses. The VpcV2 construct supports creating VPC peering connections through the `VPCPeeringConnection` construct from the `route` module. -This is an example of how to create a VPC peering connection between two VPCs. The process involves 3 main steps: +For more information, see [What is VPC peering?](https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html). -**Step 1: Acceptor Account Stack** +The following show examples of how to create a peering connection between two VPCs for all possible combinations of same-account or cross-account, and same-region or cross-region configurations. -Create a restrictive IAM role in the acceptor VPC account. This role will be used to grant limited permissions for accepting the peering request from the requestor account. +**Case 1: Same Account and Same Region Peering Connection** ```ts -// Step 1: Acceptor Account Stack const stack = new Stack(); -const acceptorVpc = new VpcV2(this, 'VpcA', { +const vpcA = new VpcV2(this, 'VpcA', { primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/16'), + region: 'us-east-1', + ownerAccountId: '123456789012', +}); + +const vpcB = new VpcV2(this, 'VpcB', { + primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'), + region: 'us-east-1', + ownerAccountId: '123456789012', }); -const acceptorRoleArn = acceptorVpc.createAcceptorVpcRole('987654321098') +const peeringConnection = vpcA.createPeeringConnection('sameAccountSameRegionPeering', { + acceptorVpc: vpcB, +}); ``` -**Step 2: Requestor Account Stack** +**Case 2: Same Account and Cross Region Peering Connection** -Initiate the peering connection request from the requestor VPC. +The only change from Case 1 is specifying a different region in the VpcV2 class for each VPC. -**Step 3: Route Table Configuration** +```ts +const stack = new Stack(); -Update route tables in both VPCs to enable traffic flow. If a route is added to the requestor stack, information will be able to flow from the requestor VPC to the acceptor VPC, but not in the reverse direction. For bi-directional communication, routes need to be added in both VPCs from their respective stacks. +const vpcA = new VpcV2(this, 'VpcA', { + primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/16'), + region: 'us-east-1', + ownerAccountId: '123456789012', +}); + +const vpcB = new VpcV2(this, 'VpcB', { + primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'), + region: 'us-west-2', + ownerAccountId: '123456789012', +}); + +const peeringConnection = vpcA.createPeeringConnection('sameAccountCrossRegionPeering', { + acceptorVpc: vpcB, +}); +``` + +**Case 3: Cross Account Peering Connection** + +For cross-account connections, the acceptor account needs an IAM role that grants the requestor account permission to initiate the connection. Create a restrictive IAM role in the acceptor account to provide the necessary permissions. + +```ts +const stack = new Stack(); + +const acceptorVpc = new VpcV2(this, 'VpcA', { + primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/16'), +}); + +const acceptorRoleArn = acceptorVpc.createAcceptorVpcRole('987654321098') // Requestor account ID +``` + +After creating an IAM role in the acceptor account, we can initiate the peering connection request from the requestor VPC. ```ts -// Step 2: Requestor Account Stack const stack = new Stack(); // TODO: Import acceptorVpc into the requestor stack const acceptorVpc = new VpcV2(this, 'VpcA', { primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/16'), + region: 'us-east-1', + ownerAccountId: '123456789012', }); const acceptorRoleArn = 'arn:aws:iam::123456789012:role/VpcPeeringRole'; const requestorVpc = new VpcV2(this, 'VpcB', { primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'), + region: 'us-west-2', + ownerAccountId: '987654321098', }); const peeringConnection = requestorVpc.createPeeringConnection('crossAccountCrossRegionPeering', { acceptorVpc: acceptorVpc, peerRoleArn: acceptorRoleArn, -}) +}); +``` + +### Route Table Configuration + +After establishing the VPC peering connection, routes must be added to the respective route tables in the VPCs to enable traffic flow. If a route is added to the requestor stack, information will be able to flow from the requestor VPC to the acceptor VPC, but not in the reverse direction. For bi-directional communication, routes need to be added in both VPCs from their respective stacks. + +For more information, see [Update your route tables for a VPC peering connection](https://docs.aws.amazon.com/vpc/latest/peering/vpc-peering-routing.html). + +```ts +const stack = new Stack(); + +const acceptorVpc = new VpcV2(this, 'VpcA', { + primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/16'), +}); + +const requestorVpc = new VpcV2(this, 'VpcB', { + primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'), +}); + +const peeringConnection = requestorVpc.createPeeringConnection('peeringConnection', { + acceptorVpc: acceptorVpc, +}); -// Step 3: Route Table Configuration const routeTable = new RouteTable(this, 'RouteTable', { vpc: requestorVpc, }); @@ -288,6 +354,26 @@ const routeTable = new RouteTable(this, 'RouteTable', { routeTable.addRoute('vpcPeeringRoute', '10.0.0.0/16', { gateway: peeringConnection }); ``` +This can also be done using AWS CLI. For more information, see [create-route](https://docs.aws.amazon.com/cli/latest/reference/ec2/create-route.html). + +```bash +# Add a route to the requestor VPC route table +aws ec2 create-route --route-table-id rtb-requestor --destination-cidr-block 10.0.0.0/16 --vpc-peering-connection-id pcx-xxxxxxxx + +# For bi-directional add a route in the acceptor vpc account as well +aws ec2 create-route --route-table-id rtb-acceptor --destination-cidr-block 10.1.0.0/16 --vpc-peering-connection-id pcx-xxxxxxxx +``` + +### Deleting the Peering Connection + +To delete a VPC peering connection, use the following command: + +```bash +aws ec2 delete-vpc-peering-connection --vpc-peering-connection-id pcx-xxxxxxxx +``` + +For more information, see [Delete a VPC peering connection](https://docs.aws.amazon.com/vpc/latest/peering/create-vpc-peering-connection.html#delete-vpc-peering-connection). + ## Adding Egress-Only Internet Gateway to VPC An egress-only internet gateway is a horizontally scaled, redundant, and highly available VPC component that allows outbound communication over IPv6 from instances in your VPC to the internet, and prevents the internet from initiating an IPv6 connection with your instances. From 9ff9da66cd2b728ebe82e50e38ec8e2c188038d1 Mon Sep 17 00:00:00 2001 From: Kailey Chen Date: Wed, 16 Oct 2024 13:39:12 -0700 Subject: [PATCH 23/34] return integ.route-v2 to original test case --- ...outev2-vpcpeerconnection-alpha.assets.json | 4 +- ...tev2-vpcpeerconnection-alpha.template.json | 177 ++--------- .../integ.route-v2.js.snapshot/manifest.json | 34 +- .../test/integ.route-v2.js.snapshot/tree.json | 290 +++--------------- .../aws-ec2-alpha/test/integ.route-v2.ts | 16 +- 5 files changed, 81 insertions(+), 440 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-vpcpeerconnection-alpha.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-vpcpeerconnection-alpha.assets.json index d0ef6b320e0ed..c64769b1370f6 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-vpcpeerconnection-alpha.assets.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-vpcpeerconnection-alpha.assets.json @@ -1,7 +1,7 @@ { "version": "38.0.1", "files": { - "247a442d4f157f616d8ab3238140453b7c58c3b66472c23fc213101c15b136d2": { + "fa56ca630709a15070b4208becd94454c974906d445fd83b73389524957f89e8": { "source": { "path": "aws-cdk-routev2-vpcpeerconnection-alpha.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "247a442d4f157f616d8ab3238140453b7c58c3b66472c23fc213101c15b136d2.json", + "objectKey": "fa56ca630709a15070b4208becd94454c974906d445fd83b73389524957f89e8.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-vpcpeerconnection-alpha.template.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-vpcpeerconnection-alpha.template.json index 501b1e51df0d9..7f195e58f758f 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-vpcpeerconnection-alpha.template.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/aws-cdk-routev2-vpcpeerconnection-alpha.template.json @@ -21,18 +21,9 @@ } } }, - "vpcpccrossAccountCrossRegionPeeringVPCPeeringConnection89B302C8": { - "Type": "AWS::EC2::VPCPeeringConnection", + "TestRoottableRouteTableFA28AA38": { + "Type": "AWS::EC2::RouteTable", "Properties": { - "PeerOwnerId": "012345678910", - "PeerRegion": "us-west-2", - "PeerRoleArn": "arn:aws:iam::012345678910:role/VpcPeeringRole", - "PeerVpcId": { - "Fn::GetAtt": [ - "secondVPCFBB45262", - "VpcId" - ] - }, "VpcId": { "Fn::GetAtt": [ "vpcpc6CAE1A04", @@ -41,164 +32,50 @@ } } }, - "TestRoottableRouteTableFA28AA38": { - "Type": "AWS::EC2::RouteTable", + "vpcpcSubnet1DD6CE35": { + "Type": "AWS::EC2::Subnet", "Properties": { + "AssignIpv6AddressOnCreation": false, + "AvailabilityZone": "us-east-1a", + "CidrBlock": "10.0.0.0/24", + "Ipv6CidrBlock": { + "Fn::Select": [ + 0, + { + "Fn::GetAtt": [ + "vpcpc6CAE1A04", + "Ipv6CidrBlocks" + ] + } + ] + }, "VpcId": { "Fn::GetAtt": [ "vpcpc6CAE1A04", "VpcId" ] } - } + }, + "DependsOn": [ + "vpcpcAmazonIpv66504EEB2" + ] }, - "TestRoottablevpcPeeringRouteA5DE3C21": { - "Type": "AWS::EC2::Route", + "vpcpcSubnetRouteTableAssociation8531BF5C": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": { - "DestinationCidrBlock": "0.0.0.0/0", "RouteTableId": { "Fn::GetAtt": [ "TestRoottableRouteTableFA28AA38", "RouteTableId" ] }, - "VpcPeeringConnectionId": { - "Fn::GetAtt": [ - "vpcpccrossAccountCrossRegionPeeringVPCPeeringConnection89B302C8", - "Id" - ] + "SubnetId": { + "Ref": "vpcpcSubnet1DD6CE35" } }, "DependsOn": [ - "vpcpccrossAccountCrossRegionPeeringVPCPeeringConnection89B302C8" + "vpcpcAmazonIpv66504EEB2" ] - }, - "secondVPCFBB45262": { - "Type": "AWS::EC2::VPC", - "Properties": { - "CidrBlock": "10.1.0.0/16", - "EnableDnsHostnames": true, - "EnableDnsSupport": true, - "InstanceTenancy": "default" - } - }, - "secondVPCTempBlock7F6107B6": { - "Type": "AWS::EC2::VPCCidrBlock", - "Properties": { - "CidrBlock": "10.2.0.0/16", - "VpcId": { - "Fn::GetAtt": [ - "secondVPCFBB45262", - "VpcId" - ] - } - } - }, - "secondVPCVpcPeeringRoleB5D6E33D": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "AWS": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::987654321098:root" - ] - ] - } - } - } - ], - "Version": "2012-10-17" - }, - "Description": "Restrictive role for VPC peering", - "RoleName": "VpcPeeringRole" - } - }, - "secondVPCVpcPeeringRoleDefaultPolicy2274B424": { - "Type": "AWS::IAM::Policy", - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": "ec2:AcceptVpcPeeringConnection", - "Effect": "Allow", - "Resource": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":ec2:us-west-2:012345678910:vpc/", - { - "Fn::GetAtt": [ - "secondVPCFBB45262", - "VpcId" - ] - } - ] - ] - } - }, - { - "Action": "ec2:AcceptVpcPeeringConnection", - "Condition": { - "StringEquals": { - "ec2:AccepterVpc": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":ec2:us-west-2:012345678910:vpc/", - { - "Fn::GetAtt": [ - "secondVPCFBB45262", - "VpcId" - ] - } - ] - ] - } - } - }, - "Effect": "Allow", - "Resource": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":ec2:us-west-2:012345678910:vpc-peering-connection/*" - ] - ] - } - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "secondVPCVpcPeeringRoleDefaultPolicy2274B424", - "Roles": [ - { - "Ref": "secondVPCVpcPeeringRoleB5D6E33D" - } - ] - } } }, "Parameters": { diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/manifest.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/manifest.json index 502edd2ff6612..66638a15bf730 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/manifest.json @@ -687,7 +687,7 @@ "notificationArns": [], "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/247a442d4f157f616d8ab3238140453b7c58c3b66472c23fc213101c15b136d2.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/fa56ca630709a15070b4208becd94454c974906d445fd83b73389524957f89e8.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -716,46 +716,22 @@ "data": "vpcpcAmazonIpv66504EEB2" } ], - "/aws-cdk-routev2-vpcpeerconnection-alpha/vpcpc/crossAccountCrossRegionPeering/VPCPeeringConnection": [ - { - "type": "aws:cdk:logicalId", - "data": "vpcpccrossAccountCrossRegionPeeringVPCPeeringConnection89B302C8" - } - ], "/aws-cdk-routev2-vpcpeerconnection-alpha/TestRoottable/RouteTable": [ { "type": "aws:cdk:logicalId", "data": "TestRoottableRouteTableFA28AA38" } ], - "/aws-cdk-routev2-vpcpeerconnection-alpha/TestRoottable/vpcPeeringRoute/Route": [ - { - "type": "aws:cdk:logicalId", - "data": "TestRoottablevpcPeeringRouteA5DE3C21" - } - ], - "/aws-cdk-routev2-vpcpeerconnection-alpha/secondVPC/Resource": [ - { - "type": "aws:cdk:logicalId", - "data": "secondVPCFBB45262" - } - ], - "/aws-cdk-routev2-vpcpeerconnection-alpha/secondVPC/Temp Block": [ - { - "type": "aws:cdk:logicalId", - "data": "secondVPCTempBlock7F6107B6" - } - ], - "/aws-cdk-routev2-vpcpeerconnection-alpha/secondVPC/VpcPeeringRole/Resource": [ + "/aws-cdk-routev2-vpcpeerconnection-alpha/vpcpcSubnet/Subnet": [ { "type": "aws:cdk:logicalId", - "data": "secondVPCVpcPeeringRoleB5D6E33D" + "data": "vpcpcSubnet1DD6CE35" } ], - "/aws-cdk-routev2-vpcpeerconnection-alpha/secondVPC/VpcPeeringRole/DefaultPolicy/Resource": [ + "/aws-cdk-routev2-vpcpeerconnection-alpha/vpcpcSubnet/RouteTableAssociation": [ { "type": "aws:cdk:logicalId", - "data": "secondVPCVpcPeeringRoleDefaultPolicy2274B424" + "data": "vpcpcSubnetRouteTableAssociation8531BF5C" } ], "/aws-cdk-routev2-vpcpeerconnection-alpha/BootstrapVersion": [ diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/tree.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/tree.json index 1c960c03406fd..963c1d07f33a0 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.js.snapshot/tree.json @@ -1754,44 +1754,6 @@ "fqn": "aws-cdk-lib.aws_ec2.CfnVPCCidrBlock", "version": "0.0.0" } - }, - "crossAccountCrossRegionPeering": { - "id": "crossAccountCrossRegionPeering", - "path": "aws-cdk-routev2-vpcpeerconnection-alpha/vpcpc/crossAccountCrossRegionPeering", - "children": { - "VPCPeeringConnection": { - "id": "VPCPeeringConnection", - "path": "aws-cdk-routev2-vpcpeerconnection-alpha/vpcpc/crossAccountCrossRegionPeering/VPCPeeringConnection", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::EC2::VPCPeeringConnection", - "aws:cdk:cloudformation:props": { - "peerOwnerId": "012345678910", - "peerRegion": "us-west-2", - "peerRoleArn": "arn:aws:iam::012345678910:role/VpcPeeringRole", - "peerVpcId": { - "Fn::GetAtt": [ - "secondVPCFBB45262", - "VpcId" - ] - }, - "vpcId": { - "Fn::GetAtt": [ - "vpcpc6CAE1A04", - "VpcId" - ] - } - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_ec2.CfnVPCPeeringConnection", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-ec2-alpha.VPCPeeringConnection", - "version": "0.0.0" - } } }, "constructInfo": { @@ -1821,42 +1783,6 @@ "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable", "version": "0.0.0" } - }, - "vpcPeeringRoute": { - "id": "vpcPeeringRoute", - "path": "aws-cdk-routev2-vpcpeerconnection-alpha/TestRoottable/vpcPeeringRoute", - "children": { - "Route": { - "id": "Route", - "path": "aws-cdk-routev2-vpcpeerconnection-alpha/TestRoottable/vpcPeeringRoute/Route", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::EC2::Route", - "aws:cdk:cloudformation:props": { - "destinationCidrBlock": "0.0.0.0/0", - "routeTableId": { - "Fn::GetAtt": [ - "TestRoottableRouteTableFA28AA38", - "RouteTableId" - ] - }, - "vpcPeeringConnectionId": { - "Fn::GetAtt": [ - "vpcpccrossAccountCrossRegionPeeringVPCPeeringConnection89B302C8", - "Id" - ] - } - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-ec2-alpha.Route", - "version": "0.0.0" - } } }, "constructInfo": { @@ -1864,200 +1790,76 @@ "version": "0.0.0" } }, - "secondVPC": { - "id": "secondVPC", - "path": "aws-cdk-routev2-vpcpeerconnection-alpha/secondVPC", + "vpcpcSubnet": { + "id": "vpcpcSubnet", + "path": "aws-cdk-routev2-vpcpeerconnection-alpha/vpcpcSubnet", "children": { - "Resource": { - "id": "Resource", - "path": "aws-cdk-routev2-vpcpeerconnection-alpha/secondVPC/Resource", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::EC2::VPC", - "aws:cdk:cloudformation:props": { - "cidrBlock": "10.1.0.0/16", - "enableDnsHostnames": true, - "enableDnsSupport": true, - "instanceTenancy": "default" - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_ec2.CfnVPC", - "version": "0.0.0" - } - }, - "Temp Block": { - "id": "Temp Block", - "path": "aws-cdk-routev2-vpcpeerconnection-alpha/secondVPC/Temp Block", + "Subnet": { + "id": "Subnet", + "path": "aws-cdk-routev2-vpcpeerconnection-alpha/vpcpcSubnet/Subnet", "attributes": { - "aws:cdk:cloudformation:type": "AWS::EC2::VPCCidrBlock", + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", "aws:cdk:cloudformation:props": { - "cidrBlock": "10.2.0.0/16", + "assignIpv6AddressOnCreation": false, + "availabilityZone": "us-east-1a", + "cidrBlock": "10.0.0.0/24", + "ipv6CidrBlock": { + "Fn::Select": [ + 0, + { + "Fn::GetAtt": [ + "vpcpc6CAE1A04", + "Ipv6CidrBlocks" + ] + } + ] + }, "vpcId": { "Fn::GetAtt": [ - "secondVPCFBB45262", + "vpcpc6CAE1A04", "VpcId" ] } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_ec2.CfnVPCCidrBlock", + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet", "version": "0.0.0" } }, - "VpcPeeringRole": { - "id": "VpcPeeringRole", - "path": "aws-cdk-routev2-vpcpeerconnection-alpha/secondVPC/VpcPeeringRole", - "children": { - "ImportVpcPeeringRole": { - "id": "ImportVpcPeeringRole", - "path": "aws-cdk-routev2-vpcpeerconnection-alpha/secondVPC/VpcPeeringRole/ImportVpcPeeringRole", - "constructInfo": { - "fqn": "aws-cdk-lib.Resource", - "version": "0.0.0" - } - }, - "Resource": { - "id": "Resource", - "path": "aws-cdk-routev2-vpcpeerconnection-alpha/secondVPC/VpcPeeringRole/Resource", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::IAM::Role", - "aws:cdk:cloudformation:props": { - "assumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "AWS": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::987654321098:root" - ] - ] - } - } - } - ], - "Version": "2012-10-17" - }, - "description": "Restrictive role for VPC peering", - "roleName": "VpcPeeringRole" - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.CfnRole", - "version": "0.0.0" - } - }, - "DefaultPolicy": { - "id": "DefaultPolicy", - "path": "aws-cdk-routev2-vpcpeerconnection-alpha/secondVPC/VpcPeeringRole/DefaultPolicy", - "children": { - "Resource": { - "id": "Resource", - "path": "aws-cdk-routev2-vpcpeerconnection-alpha/secondVPC/VpcPeeringRole/DefaultPolicy/Resource", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::IAM::Policy", - "aws:cdk:cloudformation:props": { - "policyDocument": { - "Statement": [ - { - "Action": "ec2:AcceptVpcPeeringConnection", - "Effect": "Allow", - "Resource": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":ec2:us-west-2:012345678910:vpc/", - { - "Fn::GetAtt": [ - "secondVPCFBB45262", - "VpcId" - ] - } - ] - ] - } - }, - { - "Action": "ec2:AcceptVpcPeeringConnection", - "Condition": { - "StringEquals": { - "ec2:AccepterVpc": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":ec2:us-west-2:012345678910:vpc/", - { - "Fn::GetAtt": [ - "secondVPCFBB45262", - "VpcId" - ] - } - ] - ] - } - } - }, - "Effect": "Allow", - "Resource": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":ec2:us-west-2:012345678910:vpc-peering-connection/*" - ] - ] - } - } - ], - "Version": "2012-10-17" - }, - "policyName": "secondVPCVpcPeeringRoleDefaultPolicy2274B424", - "roles": [ - { - "Ref": "secondVPCVpcPeeringRoleB5D6E33D" - } - ] - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", - "version": "0.0.0" - } - } + "Acl": { + "id": "Acl", + "path": "aws-cdk-routev2-vpcpeerconnection-alpha/vpcpcSubnet/Acl", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "aws-cdk-routev2-vpcpeerconnection-alpha/vpcpcSubnet/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Fn::GetAtt": [ + "TestRoottableRouteTableFA28AA38", + "RouteTableId" + ] }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.Policy", - "version": "0.0.0" + "subnetId": { + "Ref": "vpcpcSubnet1DD6CE35" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.Role", + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2-alpha.VpcV2", + "fqn": "@aws-cdk/aws-ec2-alpha.SubnetV2", "version": "0.0.0" } }, diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.ts b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.ts index 891f7558d6625..4f9d98b92471f 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.route-v2.ts @@ -57,7 +57,7 @@ for (const stackName in stacks) { routeTable: routeTables[stackName], }); subnets[stackName] = subnet; - } else if (stackName != 'vpcpc') { + } else { // use empty ipv6 that doesn't overlap const subnet = new SubnetV2(stacks[stackName], stackName + 'Subnet', { vpc: vpc, @@ -115,20 +115,6 @@ const dynamoEndpoint = new GatewayVpcEndpoint(stacks.dynamodb, 'testDynamoEndpoi }); routeTables.dynamodb.addRoute('dynamoRoute', '0.0.0.0/0', { endpoint: dynamoEndpoint }); -vpcs.vpcpc2 = new vpc_v2.VpcV2(stacks.vpcpc, 'secondVPC', { - primaryAddressBlock: vpc_v2.IpAddresses.ipv4('10.1.0.0/16'), - secondaryAddressBlocks: [vpc_v2.IpAddresses.ipv4('10.2.0.0/16', { cidrBlockName: 'Temp Block' })], - region: 'us-west-2', - ownerAccountId: '012345678910', -}); -vpcs.vpcpc2.createAcceptorVpcRole('987654321098'); - -const peeringConnection = vpcs.vpcpc.createPeeringConnection('crossAccountCrossRegionPeering', { - acceptorVpc: vpcs.vpcpc2, - peerRoleArn: 'arn:aws:iam::012345678910:role/VpcPeeringRole', -}); -routeTables.vpcpc.addRoute('vpcPeeringRoute', '0.0.0.0/0', { gateway: peeringConnection }); - var i = 0; for (const stackName in stacks) { new IntegTest(app, 'integtest-model-' + i, { From b13d3635a9667b07070848dfcc6ef7e640fbd363 Mon Sep 17 00:00:00 2001 From: Kailey Chen Date: Wed, 16 Oct 2024 13:39:57 -0700 Subject: [PATCH 24/34] integration test for peering connection --- ...efaultTestDeployAssertB5B8DCA8.assets.json | 19 + ...aultTestDeployAssertB5B8DCA8.template.json | 36 ++ .../acceptor-stack.assets.json | 20 + .../acceptor-stack.template.json | 142 ++++++ .../test/integ.vpcpc.js.snapshot/cdk.out | 1 + .../test/integ.vpcpc.js.snapshot/integ.json | 13 + .../integ.vpcpc.js.snapshot/manifest.json | 212 ++++++++ .../requestor-stack.assets.json | 20 + .../requestor-stack.template.json | 119 +++++ .../test/integ.vpcpc.js.snapshot/tree.json | 469 ++++++++++++++++++ .../aws-ec2-alpha/test/integ.vpcpc.ts | 95 ++++ 11 files changed, 1146 insertions(+) create mode 100644 packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/VpcpcCrossAccountIntegDefaultTestDeployAssertB5B8DCA8.assets.json create mode 100644 packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/VpcpcCrossAccountIntegDefaultTestDeployAssertB5B8DCA8.template.json create mode 100644 packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/acceptor-stack.assets.json create mode 100644 packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/acceptor-stack.template.json create mode 100644 packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/integ.json create mode 100644 packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/requestor-stack.assets.json create mode 100644 packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/requestor-stack.template.json create mode 100644 packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/tree.json create mode 100644 packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.ts diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/VpcpcCrossAccountIntegDefaultTestDeployAssertB5B8DCA8.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/VpcpcCrossAccountIntegDefaultTestDeployAssertB5B8DCA8.assets.json new file mode 100644 index 0000000000000..2e0c890253c27 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/VpcpcCrossAccountIntegDefaultTestDeployAssertB5B8DCA8.assets.json @@ -0,0 +1,19 @@ +{ + "version": "38.0.1", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "VpcpcCrossAccountIntegDefaultTestDeployAssertB5B8DCA8.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/VpcpcCrossAccountIntegDefaultTestDeployAssertB5B8DCA8.template.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/VpcpcCrossAccountIntegDefaultTestDeployAssertB5B8DCA8.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/VpcpcCrossAccountIntegDefaultTestDeployAssertB5B8DCA8.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/acceptor-stack.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/acceptor-stack.assets.json new file mode 100644 index 0000000000000..5caef75119bf9 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/acceptor-stack.assets.json @@ -0,0 +1,20 @@ +{ + "version": "38.0.1", + "files": { + "0f24269a2562149271e39a0d72b62808fb6210582ae268699403114701a77f7d": { + "source": { + "path": "acceptor-stack.template.json", + "packaging": "file" + }, + "destinations": { + "234567890123-us-east-1": { + "bucketName": "cdk-hnb659fds-assets-234567890123-us-east-1", + "objectKey": "0f24269a2562149271e39a0d72b62808fb6210582ae268699403114701a77f7d.json", + "region": "us-east-1", + "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-file-publishing-role-234567890123-us-east-1" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/acceptor-stack.template.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/acceptor-stack.template.json new file mode 100644 index 0000000000000..40f646eca36dd --- /dev/null +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/acceptor-stack.template.json @@ -0,0 +1,142 @@ +{ + "Resources": { + "acceptorVpc5B7D1670": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.0.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default" + } + }, + "acceptorVpcVpcPeeringRoleF389E47A": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": "arn:aws:iam::234567890123:root" + } + } + ], + "Version": "2012-10-17" + }, + "Description": "Restrictive role for VPC peering", + "RoleName": "VpcPeeringRole" + } + }, + "acceptorVpcVpcPeeringRoleDefaultPolicyE79C72D0": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "ec2:AcceptVpcPeeringConnection", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":ec2:us-east-1:234567890123:vpc/", + { + "Fn::GetAtt": [ + "acceptorVpc5B7D1670", + "VpcId" + ] + } + ] + ] + } + }, + { + "Action": "ec2:AcceptVpcPeeringConnection", + "Condition": { + "StringEquals": { + "ec2:AccepterVpc": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":ec2:us-east-1:234567890123:vpc/", + { + "Fn::GetAtt": [ + "acceptorVpc5B7D1670", + "VpcId" + ] + } + ] + ] + } + } + }, + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":ec2:us-east-1:234567890123:vpc-peering-connection/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "acceptorVpcVpcPeeringRoleDefaultPolicyE79C72D0", + "Roles": [ + { + "Ref": "acceptorVpcVpcPeeringRoleF389E47A" + } + ] + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/cdk.out b/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/cdk.out new file mode 100644 index 0000000000000..c6e612584e352 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"38.0.1"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/integ.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/integ.json new file mode 100644 index 0000000000000..e513fb54e9323 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/integ.json @@ -0,0 +1,13 @@ +{ + "version": "38.0.1", + "testCases": { + "VpcpcCrossAccountInteg/DefaultTest": { + "stacks": [ + "acceptor-stack", + "requestor-stack" + ], + "assertionStack": "VpcpcCrossAccountInteg/DefaultTest/DeployAssert", + "assertionStackName": "VpcpcCrossAccountIntegDefaultTestDeployAssertB5B8DCA8" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/manifest.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/manifest.json new file mode 100644 index 0000000000000..181d22a9525fb --- /dev/null +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/manifest.json @@ -0,0 +1,212 @@ +{ + "version": "38.0.1", + "artifacts": { + "acceptor-stack.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "acceptor-stack.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "acceptor-stack": { + "type": "aws:cloudformation:stack", + "environment": "aws://234567890123/us-east-1", + "properties": { + "templateFile": "acceptor-stack.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "notificationArns": [], + "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-deploy-role-234567890123-us-east-1", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-cfn-exec-role-234567890123-us-east-1", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-234567890123-us-east-1/0f24269a2562149271e39a0d72b62808fb6210582ae268699403114701a77f7d.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "acceptor-stack.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-lookup-role-234567890123-us-east-1", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "acceptor-stack.assets" + ], + "metadata": { + "/acceptor-stack/acceptorVpc/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "acceptorVpc5B7D1670" + } + ], + "/acceptor-stack/acceptorVpc/VpcPeeringRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "acceptorVpcVpcPeeringRoleF389E47A" + } + ], + "/acceptor-stack/acceptorVpc/VpcPeeringRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "acceptorVpcVpcPeeringRoleDefaultPolicyE79C72D0" + } + ], + "/acceptor-stack/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/acceptor-stack/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "acceptor-stack" + }, + "requestor-stack.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "requestor-stack.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "requestor-stack": { + "type": "aws:cloudformation:stack", + "environment": "aws://123456789012/us-east-1", + "properties": { + "templateFile": "requestor-stack.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "notificationArns": [], + "assumeRoleArn": "arn:${AWS::Partition}:iam::123456789012:role/cdk-hnb659fds-deploy-role-123456789012-us-east-1", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::123456789012:role/cdk-hnb659fds-cfn-exec-role-123456789012-us-east-1", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-123456789012-us-east-1/97ed73811c6238b5ca810c262385064a85e50d171ac8685e8aa595963d0ed115.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "requestor-stack.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::123456789012:role/cdk-hnb659fds-lookup-role-123456789012-us-east-1", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "requestor-stack.assets" + ], + "metadata": { + "/requestor-stack/requestorVpc/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "requestorVpcFFA7DDD4" + } + ], + "/requestor-stack/requestorVpc/TempBlock": [ + { + "type": "aws:cdk:logicalId", + "data": "requestorVpcTempBlock78E0B4F4" + } + ], + "/requestor-stack/VpcB/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcB98A08B07" + } + ], + "/requestor-stack/VpcB/acceptorAccountCrossRegionPeering/VPCPeeringConnection": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcBacceptorAccountCrossRegionPeeringVPCPeeringConnection8510BFF3" + } + ], + "/requestor-stack/RouteTable/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "RouteTableE1378006" + } + ], + "/requestor-stack/RouteTable/vpcPeeringRoute/Route": [ + { + "type": "aws:cdk:logicalId", + "data": "RouteTablevpcPeeringRoute2C93DAB3" + } + ], + "/requestor-stack/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/requestor-stack/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "requestor-stack" + }, + "VpcpcCrossAccountIntegDefaultTestDeployAssertB5B8DCA8.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "VpcpcCrossAccountIntegDefaultTestDeployAssertB5B8DCA8.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "VpcpcCrossAccountIntegDefaultTestDeployAssertB5B8DCA8": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "VpcpcCrossAccountIntegDefaultTestDeployAssertB5B8DCA8.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "notificationArns": [], + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "VpcpcCrossAccountIntegDefaultTestDeployAssertB5B8DCA8.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "VpcpcCrossAccountIntegDefaultTestDeployAssertB5B8DCA8.assets" + ], + "metadata": { + "/VpcpcCrossAccountInteg/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/VpcpcCrossAccountInteg/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "VpcpcCrossAccountInteg/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/requestor-stack.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/requestor-stack.assets.json new file mode 100644 index 0000000000000..7a4af96bbe403 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/requestor-stack.assets.json @@ -0,0 +1,20 @@ +{ + "version": "38.0.1", + "files": { + "97ed73811c6238b5ca810c262385064a85e50d171ac8685e8aa595963d0ed115": { + "source": { + "path": "requestor-stack.template.json", + "packaging": "file" + }, + "destinations": { + "123456789012-us-east-1": { + "bucketName": "cdk-hnb659fds-assets-123456789012-us-east-1", + "objectKey": "97ed73811c6238b5ca810c262385064a85e50d171ac8685e8aa595963d0ed115.json", + "region": "us-east-1", + "assumeRoleArn": "arn:${AWS::Partition}:iam::123456789012:role/cdk-hnb659fds-file-publishing-role-123456789012-us-east-1" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/requestor-stack.template.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/requestor-stack.template.json new file mode 100644 index 0000000000000..d2ec40b042e07 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/requestor-stack.template.json @@ -0,0 +1,119 @@ +{ + "Resources": { + "requestorVpcFFA7DDD4": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.1.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default" + } + }, + "requestorVpcTempBlock78E0B4F4": { + "Type": "AWS::EC2::VPCCidrBlock", + "Properties": { + "CidrBlock": "10.3.0.0/16", + "VpcId": { + "Fn::GetAtt": [ + "requestorVpcFFA7DDD4", + "VpcId" + ] + } + } + }, + "VpcB98A08B07": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.2.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default" + } + }, + "VpcBacceptorAccountCrossRegionPeeringVPCPeeringConnection8510BFF3": { + "Type": "AWS::EC2::VPCPeeringConnection", + "Properties": { + "PeerOwnerId": "12345678", + "PeerRegion": "us-east-1", + "PeerVpcId": { + "Fn::GetAtt": [ + "requestorVpcFFA7DDD4", + "VpcId" + ] + }, + "VpcId": { + "Fn::GetAtt": [ + "VpcB98A08B07", + "VpcId" + ] + } + } + }, + "RouteTableE1378006": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Fn::GetAtt": [ + "VpcB98A08B07", + "VpcId" + ] + } + } + }, + "RouteTablevpcPeeringRoute2C93DAB3": { + "Type": "AWS::EC2::Route", + "Properties": { + "DestinationCidrBlock": "10.0.0.0/16", + "RouteTableId": { + "Fn::GetAtt": [ + "RouteTableE1378006", + "RouteTableId" + ] + }, + "VpcPeeringConnectionId": { + "Fn::GetAtt": [ + "VpcBacceptorAccountCrossRegionPeeringVPCPeeringConnection8510BFF3", + "Id" + ] + } + }, + "DependsOn": [ + "VpcBacceptorAccountCrossRegionPeeringVPCPeeringConnection8510BFF3" + ] + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/tree.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/tree.json new file mode 100644 index 0000000000000..b4edf1295d79b --- /dev/null +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/tree.json @@ -0,0 +1,469 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "acceptor-stack": { + "id": "acceptor-stack", + "path": "acceptor-stack", + "children": { + "acceptorVpc": { + "id": "acceptorVpc", + "path": "acceptor-stack/acceptorVpc", + "children": { + "Resource": { + "id": "Resource", + "path": "acceptor-stack/acceptorVpc/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPC", + "aws:cdk:cloudformation:props": { + "cidrBlock": "10.0.0.0/16", + "enableDnsHostnames": true, + "enableDnsSupport": true, + "instanceTenancy": "default" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnVPC", + "version": "0.0.0" + } + }, + "VpcPeeringRole": { + "id": "VpcPeeringRole", + "path": "acceptor-stack/acceptorVpc/VpcPeeringRole", + "children": { + "ImportVpcPeeringRole": { + "id": "ImportVpcPeeringRole", + "path": "acceptor-stack/acceptorVpc/VpcPeeringRole/ImportVpcPeeringRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "acceptor-stack/acceptorVpc/VpcPeeringRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": "arn:aws:iam::234567890123:root" + } + } + ], + "Version": "2012-10-17" + }, + "description": "Restrictive role for VPC peering", + "roleName": "VpcPeeringRole" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "acceptor-stack/acceptorVpc/VpcPeeringRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "acceptor-stack/acceptorVpc/VpcPeeringRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": "ec2:AcceptVpcPeeringConnection", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":ec2:us-east-1:234567890123:vpc/", + { + "Fn::GetAtt": [ + "acceptorVpc5B7D1670", + "VpcId" + ] + } + ] + ] + } + }, + { + "Action": "ec2:AcceptVpcPeeringConnection", + "Condition": { + "StringEquals": { + "ec2:AccepterVpc": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":ec2:us-east-1:234567890123:vpc/", + { + "Fn::GetAtt": [ + "acceptorVpc5B7D1670", + "VpcId" + ] + } + ] + ] + } + } + }, + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":ec2:us-east-1:234567890123:vpc-peering-connection/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "policyName": "acceptorVpcVpcPeeringRoleDefaultPolicyE79C72D0", + "roles": [ + { + "Ref": "acceptorVpcVpcPeeringRoleF389E47A" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2-alpha.VpcV2", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "acceptor-stack/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "acceptor-stack/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "requestor-stack": { + "id": "requestor-stack", + "path": "requestor-stack", + "children": { + "requestorVpc": { + "id": "requestorVpc", + "path": "requestor-stack/requestorVpc", + "children": { + "Resource": { + "id": "Resource", + "path": "requestor-stack/requestorVpc/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPC", + "aws:cdk:cloudformation:props": { + "cidrBlock": "10.1.0.0/16", + "enableDnsHostnames": true, + "enableDnsSupport": true, + "instanceTenancy": "default" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnVPC", + "version": "0.0.0" + } + }, + "TempBlock": { + "id": "TempBlock", + "path": "requestor-stack/requestorVpc/TempBlock", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPCCidrBlock", + "aws:cdk:cloudformation:props": { + "cidrBlock": "10.3.0.0/16", + "vpcId": { + "Fn::GetAtt": [ + "requestorVpcFFA7DDD4", + "VpcId" + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnVPCCidrBlock", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2-alpha.VpcV2", + "version": "0.0.0" + } + }, + "VpcB": { + "id": "VpcB", + "path": "requestor-stack/VpcB", + "children": { + "Resource": { + "id": "Resource", + "path": "requestor-stack/VpcB/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPC", + "aws:cdk:cloudformation:props": { + "cidrBlock": "10.2.0.0/16", + "enableDnsHostnames": true, + "enableDnsSupport": true, + "instanceTenancy": "default" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnVPC", + "version": "0.0.0" + } + }, + "acceptorAccountCrossRegionPeering": { + "id": "acceptorAccountCrossRegionPeering", + "path": "requestor-stack/VpcB/acceptorAccountCrossRegionPeering", + "children": { + "VPCPeeringConnection": { + "id": "VPCPeeringConnection", + "path": "requestor-stack/VpcB/acceptorAccountCrossRegionPeering/VPCPeeringConnection", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPCPeeringConnection", + "aws:cdk:cloudformation:props": { + "peerOwnerId": "123456789012", + "peerRegion": "us-east-1", + "peerVpcId": { + "Fn::GetAtt": [ + "requestorVpcFFA7DDD4", + "VpcId" + ] + }, + "vpcId": { + "Fn::GetAtt": [ + "VpcB98A08B07", + "VpcId" + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnVPCPeeringConnection", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2-alpha.VPCPeeringConnection", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2-alpha.VpcV2", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "requestor-stack/RouteTable", + "children": { + "RouteTable": { + "id": "RouteTable", + "path": "requestor-stack/RouteTable/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Fn::GetAtt": [ + "VpcB98A08B07", + "VpcId" + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "vpcPeeringRoute": { + "id": "vpcPeeringRoute", + "path": "requestor-stack/RouteTable/vpcPeeringRoute", + "children": { + "Route": { + "id": "Route", + "path": "requestor-stack/RouteTable/vpcPeeringRoute/Route", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "destinationCidrBlock": "10.0.0.0/16", + "routeTableId": { + "Fn::GetAtt": [ + "RouteTableE1378006", + "RouteTableId" + ] + }, + "vpcPeeringConnectionId": { + "Fn::GetAtt": [ + "VpcBacceptorAccountCrossRegionPeeringVPCPeeringConnection8510BFF3", + "Id" + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2-alpha.Route", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2-alpha.RouteTable", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "requestor-stack/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "requestor-stack/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "VpcpcCrossAccountInteg": { + "id": "VpcpcCrossAccountInteg", + "path": "VpcpcCrossAccountInteg", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "VpcpcCrossAccountInteg/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "VpcpcCrossAccountInteg/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "VpcpcCrossAccountInteg/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "VpcpcCrossAccountInteg/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "VpcpcCrossAccountInteg/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.ts b/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.ts new file mode 100644 index 0000000000000..c0106993e9664 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.ts @@ -0,0 +1,95 @@ +/* + * Our integration tests act as snapshot tests to make sure the rendered template is stable. + * If any changes to the result are required, + * you need to perform an actual CloudFormation deployment of this application, + * and, if it is successful, a new snapshot will be written out. + * + * For more information on CDK integ tests, + * see the main CONTRIBUTING.md file. + * + * Notes on how to run this integ test + * Replace 123456789012 and 234567890123 with your own account numbers + * + * 1. Configure Accounts + * a. Requestor Account (123456789012) should be bootstrapped for us-east-1 + * b. Acceptor Account (234567890123) should be bootstrapped for us-east-1 + * and needs to set trust permissions for requestor account (123456789012) + * - `cdk bootstrap --trust 123456789012 --cloudformation-execution-policies 'arn:aws:iam::aws:policy/AdministratorAccess' 'aws://234567890123/us-east-1'` + * - assuming this is the default profile for aws credentials + * + * 2. Set environment variables + * a. `export CDK_INTEG_ACCOUNT=123456789012` + * b. `export CDK_INTEG_CROSS_ACCOUNT=234567890123` + * + * 3. Run the integ test (from the @aws-cdk/aws-ec2-alpha/test directory) + * a. Get temporary console access credentials for Requestor Account + * - `yarn integ test/integ.vpcpc.js` + * b. Fall back if temp credentials do not work (account info may be in snapshot) + * - `yarn integ test/integ.vpcpc.js --profiles cross-account` +*/ + +import * as vpc_v2 from '../lib/vpc-v2'; +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; +import * as cdk from 'aws-cdk-lib'; +import { Construct } from 'constructs'; +import { RouteTable } from '../lib/route'; + +const app = new cdk.App(); +const account = process.env.CDK_INTEG_ACCOUNT || '123456789012'; +const acceptorAccount = process.env.CDK_INTEG_CROSS_ACCOUNT || '234567890123'; + +class AcceptorStack extends cdk.Stack { + constructor(scope: Construct, id: string, props?: cdk.StackProps) { + super(scope, id, props); + + const acceptorVpc = new vpc_v2.VpcV2(this, 'acceptorVpc', { + primaryAddressBlock: vpc_v2.IpAddresses.ipv4('10.0.0.0/16'), + }); + acceptorVpc.createAcceptorVpcRole(acceptorAccount); + } +} + +class RequestorStack extends cdk.Stack { + constructor(scope: Construct, id: string, props?: cdk.StackProps) { + super(scope, id, props); + + // TODO: Import acceptorVpc into the requestor stack + // Once implemented, need to test for cross account + const acceptorVpc = new vpc_v2.VpcV2(this, 'requestorVpc', { + primaryAddressBlock: vpc_v2.IpAddresses.ipv4('10.1.0.0/16'), + secondaryAddressBlocks: [vpc_v2.IpAddresses.ipv4('10.3.0.0/16', { cidrBlockName: 'TempBlock' })], + }); + + const requestorVpc = new vpc_v2.VpcV2(this, 'VpcB', { + primaryAddressBlock: vpc_v2.IpAddresses.ipv4('10.2.0.0/16'), + }); + + const peeringConnection = requestorVpc.createPeeringConnection('acceptorAccountCrossRegionPeering', { + acceptorVpc: acceptorVpc, + }); + + const routeTable = new RouteTable(this, 'RouteTable', { + vpc: requestorVpc, + }); + + routeTable.addRoute('vpcPeeringRoute', '10.0.0.0/16', { gateway: peeringConnection }); + } +} + +const acceptorStack = new AcceptorStack(app, 'acceptor-stack', { + env: { + account: acceptorAccount, + region: 'us-east-1', + }, +}); + +const requestorStack = new RequestorStack(app, 'requestor-stack', { + env: { + account: account, + region: 'us-east-1', + }, +}); + +new IntegTest(app, 'VpcpcCrossAccountInteg', { + testCases: [acceptorStack, requestorStack], +}); \ No newline at end of file From 66071926659143f7c2043151ffe0e3d7acf3eea1 Mon Sep 17 00:00:00 2001 From: Shikha Aggarwal Date: Wed, 16 Oct 2024 15:43:11 -0700 Subject: [PATCH 25/34] Apply suggestions from code review --- packages/@aws-cdk/aws-ec2-alpha/README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/README.md b/packages/@aws-cdk/aws-ec2-alpha/README.md index adf72c59bd805..6dbb2eb7d5640 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/README.md +++ b/packages/@aws-cdk/aws-ec2-alpha/README.md @@ -236,6 +236,8 @@ new Route(this, 'DynamoDBRoute', { VPC peering connection allows you to connect two VPCs and route traffic between them using private IP addresses. The VpcV2 construct supports creating VPC peering connections through the `VPCPeeringConnection` construct from the `route` module. +Peering Connection cannot be established between two VPCs with overlapping CIDR ranges. Please make sure the two VPC CIDRs do not overlap with each other else it will throw an error. + For more information, see [What is VPC peering?](https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html). The following show examples of how to create a peering connection between two VPCs for all possible combinations of same-account or cross-account, and same-region or cross-region configurations. @@ -288,7 +290,9 @@ const peeringConnection = vpcA.createPeeringConnection('sameAccountCrossRegionPe **Case 3: Cross Account Peering Connection** -For cross-account connections, the acceptor account needs an IAM role that grants the requestor account permission to initiate the connection. Create a restrictive IAM role in the acceptor account to provide the necessary permissions. +For cross-account connections, the acceptor account needs an IAM role that grants the requestor account permission to initiate the connection. Create a new IAM role in the acceptor account using method `createAcceptorVpcRole` to provide the necessary permissions. + +Once role is created in account, provide role arn for field `peerRoleArn` under method `createPeeringConnection` ```ts const stack = new Stack(); From 2f78a5ac01f322a49694aea2c03401af276f7467 Mon Sep 17 00:00:00 2001 From: 1kaileychen Date: Wed, 16 Oct 2024 17:09:51 -0700 Subject: [PATCH 26/34] Update wording suggestion Co-authored-by: Shikha Aggarwal --- packages/@aws-cdk/aws-ec2-alpha/lib/route.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts b/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts index 21157547d8af1..80776a0f29eee 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/lib/route.ts @@ -494,7 +494,7 @@ export class VPCPeeringConnection extends Resource implements IRouteTarget { * * @param requestorVpc The VPC of the requestor. * @param acceptorVpc The VPC of the acceptor. - * @returns True if the IPv4 CIDR block overlaps with existing subnet CIDR blocks, false otherwise. + * @returns True if the IPv4 CIDR block overlaps with each other for two VPCs, false otherwise. * @internal */ private validateVpcCidrOverlap(requestorVpc: IVpcV2, acceptorVpc: IVpcV2): boolean { From 5773a08f657c7702d8a3d028851608165f952d01 Mon Sep 17 00:00:00 2001 From: Kailey Chen Date: Thu, 17 Oct 2024 16:04:58 -0700 Subject: [PATCH 27/34] remove region and ownerAccountId from VpcV2Props --- packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2.ts | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2.ts b/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2.ts index 7ee2e841b6c00..eee969f8e1010 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2.ts @@ -180,20 +180,6 @@ export interface VpcV2Props { * @default - autogenerated by CDK */ readonly vpcName?: string; - - /** - * Optional to override inferred region - * - * @default - current stack's environment region - */ - readonly region?: string; - - /** - * The ID of the AWS account that owns the VPC - * - * @default - the account id of the parent stack - */ - readonly ownerAccountId?: string; } /** @@ -326,8 +312,8 @@ export class VpcV2 extends VpcV2Base { resource: 'vpc', resourceName: this.vpcId, }, this.stack); - this.region = props.region ?? this.stack.region; - this.ownerAccountId = props.ownerAccountId ?? this.stack.account; + this.region = this.stack.region; + this.ownerAccountId = this.stack.account; if (props.secondaryAddressBlocks) { const secondaryAddressBlocks: IIpAddresses[] = props.secondaryAddressBlocks; From 8e3ff5fce2c6dfb2963fd74ad41a671603adae7a Mon Sep 17 00:00:00 2001 From: Kailey Chen Date: Thu, 17 Oct 2024 16:05:24 -0700 Subject: [PATCH 28/34] update test cases and readme --- packages/@aws-cdk/aws-ec2-alpha/README.md | 26 ++++------ .../@aws-cdk/aws-ec2-alpha/test/route.test.ts | 47 ++++++++++--------- .../aws-ec2-alpha/test/vpc-add-method.test.ts | 9 +--- 3 files changed, 37 insertions(+), 45 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/README.md b/packages/@aws-cdk/aws-ec2-alpha/README.md index adf72c59bd805..9fa56bc2a4c46 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/README.md +++ b/packages/@aws-cdk/aws-ec2-alpha/README.md @@ -240,6 +240,8 @@ For more information, see [What is VPC peering?](https://docs.aws.amazon.com/vpc The following show examples of how to create a peering connection between two VPCs for all possible combinations of same-account or cross-account, and same-region or cross-region configurations. +Note: You cannot create a VPC peering connection between VPCs that have matching or overlapping CIDR blocks + **Case 1: Same Account and Same Region Peering Connection** ```ts @@ -247,14 +249,10 @@ const stack = new Stack(); const vpcA = new VpcV2(this, 'VpcA', { primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/16'), - region: 'us-east-1', - ownerAccountId: '123456789012', }); const vpcB = new VpcV2(this, 'VpcB', { primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'), - region: 'us-east-1', - ownerAccountId: '123456789012', }); const peeringConnection = vpcA.createPeeringConnection('sameAccountSameRegionPeering', { @@ -264,23 +262,23 @@ const peeringConnection = vpcA.createPeeringConnection('sameAccountSameRegionPee **Case 2: Same Account and Cross Region Peering Connection** -The only change from Case 1 is specifying a different region in the VpcV2 class for each VPC. +There is no difference from Case 1 when calling `createPeeringConnection`. The only change is that one of the VPCs are created in another stack with a different region. ```ts -const stack = new Stack(); +const app = new App(); -const vpcA = new VpcV2(this, 'VpcA', { +const stackA = new Stack(app, 'VpcStackA', { env: { account: '012345678910', region: 'us-east-1' } }); +const stackB = new Stack(app, 'VpcStackB', { env: { account: '012345678910', region: 'us-west-2' } }); + +const vpcA = new VpcV2(stackA, 'VpcA', { primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/16'), - region: 'us-east-1', - ownerAccountId: '123456789012', }); -const vpcB = new VpcV2(this, 'VpcB', { +const vpcB = new VpcV2(stackB, 'VpcB', { primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'), - region: 'us-west-2', - ownerAccountId: '123456789012', }); +// TODO: Lookup vpcB in stackA const peeringConnection = vpcA.createPeeringConnection('sameAccountCrossRegionPeering', { acceptorVpc: vpcB, }); @@ -308,16 +306,12 @@ const stack = new Stack(); // TODO: Import acceptorVpc into the requestor stack const acceptorVpc = new VpcV2(this, 'VpcA', { primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/16'), - region: 'us-east-1', - ownerAccountId: '123456789012', }); const acceptorRoleArn = 'arn:aws:iam::123456789012:role/VpcPeeringRole'; const requestorVpc = new VpcV2(this, 'VpcB', { primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'), - region: 'us-west-2', - ownerAccountId: '987654321098', }); const peeringConnection = requestorVpc.createPeeringConnection('crossAccountCrossRegionPeering', { diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts b/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts index 8a459d27a63ca..cdfeb79fdbb57 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts @@ -516,7 +516,9 @@ describe('EC2 Routing', () => { describe('VPCPeeringConnection', () => { - let stack: cdk.Stack; + let stackA: cdk.Stack; + let stackB: cdk.Stack; + let stackC: cdk.Stack; let vpcA: vpc.VpcV2; let vpcB: vpc.VpcV2; let vpcC: vpc.VpcV2; @@ -527,31 +529,34 @@ describe('VPCPeeringConnection', () => { '@aws-cdk/core:newStyleStackSynthesis': false, }, }); - stack = new cdk.Stack(app, 'VpcStack', { env: { region: 'us-east-1' } }); - vpcA = new vpc.VpcV2(stack, 'VpcA', { + stackA = new cdk.Stack(app, 'VpcStackA', { env: { account: '987654321098', region: 'us-east-1' } }); + stackB = new cdk.Stack(app, 'VpcStackB', { env: { account: '012345678910', region: 'us-east-1' } }); + stackC = new cdk.Stack(app, 'VpcStackC', { env: { account: '012345678910', region: 'us-west-2' } }); + + vpcA = new vpc.VpcV2(stackA, 'VpcA', { primaryAddressBlock: vpc.IpAddresses.ipv4('10.0.0.0/16'), secondaryAddressBlocks: [vpc.IpAddresses.ipv4('10.1.0.0/16', { cidrBlockName: 'TempSecondaryBlock' })], - region: 'us-east-1', - ownerAccountId: '987654321098', }); - vpcB = new vpc.VpcV2(stack, 'VpcB', { + vpcB = new vpc.VpcV2(stackB, 'VpcB', { primaryAddressBlock: vpc.IpAddresses.ipv4('10.2.0.0/16'), - ownerAccountId: '012345678910', }); - vpcC = new vpc.VpcV2(stack, 'VpcC', { + vpcC = new vpc.VpcV2(stackC, 'VpcC', { primaryAddressBlock: vpc.IpAddresses.ipv4('10.1.0.0/16'), - region: 'us-west-2', - ownerAccountId: '012345678910', }); }); + // eslint-disable-next-line jest/no-commented-out-tests + /* + // Test cases currently can't be used until the lookup function is implemented + // TODO: Lookup the acceptorVPC for the corresponding stack in each test case + test('Creates a cross account VPC peering connection', () => { - new route.VPCPeeringConnection(stack, 'TestPeeringConnection', { + new route.VPCPeeringConnection(stackA, 'TestPeeringConnection', { requestorVpc: vpcA, acceptorVpc: vpcB, peerRoleArn: 'arn:aws:iam::012345678910:role/VpcPeeringRole', }); - const template = Template.fromStack(stack); + const template = Template.fromStack(stackA); template.hasResourceProperties('AWS::EC2::VPCPeeringConnection', { PeerRoleArn: 'arn:aws:iam::012345678910:role/VpcPeeringRole', VpcId: { @@ -566,12 +571,12 @@ describe('VPCPeeringConnection', () => { }); test('Creates a cross region VPC peering connection', () => { - new route.VPCPeeringConnection(stack, 'TestCrossRegionPeeringConnection', { + new route.VPCPeeringConnection(stackB, 'TestCrossRegionPeeringConnection', { requestorVpc: vpcB, acceptorVpc: vpcC, }); - Template.fromStack(stack).hasResourceProperties('AWS::EC2::VPCPeeringConnection', { + Template.fromStack(stackB).hasResourceProperties('AWS::EC2::VPCPeeringConnection', { VpcId: { 'Fn::GetAtt': ['VpcB98A08B07', 'VpcId'], }, @@ -582,10 +587,10 @@ describe('VPCPeeringConnection', () => { PeerRegion: 'us-west-2', }); }); - + */ test('Throws error when peerRoleArn is provided for same account peering', () => { expect(() => { - new route.VPCPeeringConnection(stack, 'TestPeeringConnection', { + new route.VPCPeeringConnection(stackB, 'TestPeeringConnection', { requestorVpc: vpcB, acceptorVpc: vpcC, peerRoleArn: 'arn:aws:iam::123456789012:role/unnecessary-role', @@ -595,7 +600,7 @@ describe('VPCPeeringConnection', () => { test('Throws error when peerRoleArn is not provided for cross-account peering', () => { expect(() => { - new route.VPCPeeringConnection(stack, 'TestCrossAccountPeeringConnection', { + new route.VPCPeeringConnection(stackA, 'TestCrossAccountPeeringConnection', { requestorVpc: vpcA, acceptorVpc: vpcB, }); @@ -604,7 +609,7 @@ describe('VPCPeeringConnection', () => { test('CIDR block overlap with secondary CIDR block should throw error', () => { expect(() => { - new route.VPCPeeringConnection(stack, 'TestPeering', { + new route.VPCPeeringConnection(stackA, 'TestPeering', { requestorVpc: vpcA, acceptorVpc: vpcC, peerRoleArn: 'arn:aws:iam::012345678910:role/VpcPeeringRole', @@ -613,16 +618,14 @@ describe('VPCPeeringConnection', () => { }); test('CIDR block overlap should throw error', () => { - const vpcD = new vpc.VpcV2(stack, 'VpcD', { + const vpcD = new vpc.VpcV2(stackA, 'VpcD', { primaryAddressBlock: vpc.IpAddresses.ipv4('10.0.0.0/16'), - region: 'us-east-1', }); expect(() => { - new route.VPCPeeringConnection(stack, 'TestPeering', { + new route.VPCPeeringConnection(stackA, 'TestPeering', { requestorVpc: vpcA, acceptorVpc: vpcD, - peerRoleArn: 'arn:aws:iam::012345678910:role/VpcPeeringRole', }); }).toThrow(/CIDR block should not overlap with each other for establishing a peering connection/); }); diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/vpc-add-method.test.ts b/packages/@aws-cdk/aws-ec2-alpha/test/vpc-add-method.test.ts index 977705348d7cc..26400da6bc87b 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/vpc-add-method.test.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/test/vpc-add-method.test.ts @@ -417,30 +417,25 @@ describe('Vpc V2 with full control', () => { }); test('createPeeringConnection establishes connection between 2 VPCs', () => { - const acceptorRoleArn = 'arn:aws:iam::123456789012:role/VpcPeeringRole'; const acceptorVpc = new vpc.VpcV2(stack, 'TestAcceptorVpc', { primaryAddressBlock: vpc.IpAddresses.ipv4('10.0.0.0/16'), - ownerAccountId: '987654321098', - region: 'us-east-1', enableDnsHostnames: true, enableDnsSupport: true, }); myVpc.createPeeringConnection('testPeeringConnection', { acceptorVpc: acceptorVpc, - peerRoleArn: acceptorRoleArn, }); Template.fromStack(stack).hasResourceProperties('AWS::EC2::VPCPeeringConnection', { - PeerRoleArn: acceptorRoleArn, VpcId: { 'Fn::GetAtt': ['TestVpcE77CE678', 'VpcId'], }, PeerVpcId: { 'Fn::GetAtt': ['TestAcceptorVpc4AE3E611', 'VpcId'], }, - PeerOwnerId: '987654321098', - PeerRegion: 'us-east-1', + PeerOwnerId: { Ref: 'AWS::AccountId' }, + PeerRegion: { Ref: 'AWS::Region' }, }); }); }); \ No newline at end of file From 951abf0fc555d927d94fccd062c3d537489e81d8 Mon Sep 17 00:00:00 2001 From: Kailey Chen Date: Thu, 17 Oct 2024 16:49:19 -0700 Subject: [PATCH 29/34] update account ids that are allowed in readme and tests --- packages/@aws-cdk/aws-ec2-alpha/README.md | 8 +-- .../@aws-cdk/aws-ec2-alpha/test/route.test.ts | 57 +++++++++++++------ 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/README.md b/packages/@aws-cdk/aws-ec2-alpha/README.md index 415aec4305749..f1ed00a0943b5 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/README.md +++ b/packages/@aws-cdk/aws-ec2-alpha/README.md @@ -269,8 +269,8 @@ There is no difference from Case 1 when calling `createPeeringConnection`. The o ```ts const app = new App(); -const stackA = new Stack(app, 'VpcStackA', { env: { account: '012345678910', region: 'us-east-1' } }); -const stackB = new Stack(app, 'VpcStackB', { env: { account: '012345678910', region: 'us-west-2' } }); +const stackA = new Stack(app, 'VpcStackA', { env: { account: '000000000000', region: 'us-east-1' } }); +const stackB = new Stack(app, 'VpcStackB', { env: { account: '111111111111', region: 'us-west-2' } }); const vpcA = new VpcV2(stackA, 'VpcA', { primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/16'), @@ -299,7 +299,7 @@ const acceptorVpc = new VpcV2(this, 'VpcA', { primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/16'), }); -const acceptorRoleArn = acceptorVpc.createAcceptorVpcRole('987654321098') // Requestor account ID +const acceptorRoleArn = acceptorVpc.createAcceptorVpcRole('000000000000') // Requestor account ID ``` After creating an IAM role in the acceptor account, we can initiate the peering connection request from the requestor VPC. @@ -312,7 +312,7 @@ const acceptorVpc = new VpcV2(this, 'VpcA', { primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/16'), }); -const acceptorRoleArn = 'arn:aws:iam::123456789012:role/VpcPeeringRole'; +const acceptorRoleArn = 'arn:aws:iam::111111111111:role/VpcPeeringRole'; const requestorVpc = new VpcV2(this, 'VpcB', { primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'), diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts b/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts index cdfeb79fdbb57..83909367d5b73 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts @@ -516,9 +516,13 @@ describe('EC2 Routing', () => { describe('VPCPeeringConnection', () => { + let stack: cdk.Stack; + /* + // Uncomment when lookup is implemented let stackA: cdk.Stack; let stackB: cdk.Stack; let stackC: cdk.Stack; + */ let vpcA: vpc.VpcV2; let vpcB: vpc.VpcV2; let vpcC: vpc.VpcV2; @@ -529,9 +533,24 @@ describe('VPCPeeringConnection', () => { '@aws-cdk/core:newStyleStackSynthesis': false, }, }); - stackA = new cdk.Stack(app, 'VpcStackA', { env: { account: '987654321098', region: 'us-east-1' } }); - stackB = new cdk.Stack(app, 'VpcStackB', { env: { account: '012345678910', region: 'us-east-1' } }); - stackC = new cdk.Stack(app, 'VpcStackC', { env: { account: '012345678910', region: 'us-west-2' } }); + + stack = new cdk.Stack(app, 'VpcStack' ); + vpcA = new vpc.VpcV2(stack, 'VpcA', { + primaryAddressBlock: vpc.IpAddresses.ipv4('10.0.0.0/16'), + secondaryAddressBlocks: [vpc.IpAddresses.ipv4('10.1.0.0/16', { cidrBlockName: 'TempSecondaryBlock' })], + }); + vpcB = new vpc.VpcV2(stack, 'VpcB', { + primaryAddressBlock: vpc.IpAddresses.ipv4('10.2.0.0/16'), + }); + vpcC = new vpc.VpcV2(stack, 'VpcC', { + primaryAddressBlock: vpc.IpAddresses.ipv4('10.1.0.0/16'), + }); + + /* + // Uncomment when lookup is implemented + stackA = new cdk.Stack(app, 'VpcStackA', { env: { account: '234567890123', region: 'us-east-1' } }); + stackB = new cdk.Stack(app, 'VpcStackB', { env: { account: '123456789012', region: 'us-east-1' } }); + stackC = new cdk.Stack(app, 'VpcStackC', { env: { account: '123456789012', region: 'us-west-2' } }); vpcA = new vpc.VpcV2(stackA, 'VpcA', { primaryAddressBlock: vpc.IpAddresses.ipv4('10.0.0.0/16'), @@ -543,6 +562,7 @@ describe('VPCPeeringConnection', () => { vpcC = new vpc.VpcV2(stackC, 'VpcC', { primaryAddressBlock: vpc.IpAddresses.ipv4('10.1.0.0/16'), }); + */ }); // eslint-disable-next-line jest/no-commented-out-tests @@ -587,10 +607,20 @@ describe('VPCPeeringConnection', () => { PeerRegion: 'us-west-2', }); }); + + test('Throws error when peerRoleArn is not provided for cross-account peering', () => { + expect(() => { + new route.VPCPeeringConnection(stack, 'TestCrossAccountPeeringConnection', { + requestorVpc: vpcA, + acceptorVpc: vpcB, + }); + }).toThrow(/Cross account VPC peering requires peerRoleArn/); + }); */ + test('Throws error when peerRoleArn is provided for same account peering', () => { expect(() => { - new route.VPCPeeringConnection(stackB, 'TestPeeringConnection', { + new route.VPCPeeringConnection(stack, 'TestPeeringConnection', { requestorVpc: vpcB, acceptorVpc: vpcC, peerRoleArn: 'arn:aws:iam::123456789012:role/unnecessary-role', @@ -598,32 +628,23 @@ describe('VPCPeeringConnection', () => { }).toThrow(/peerRoleArn is not needed for same account peering/); }); - test('Throws error when peerRoleArn is not provided for cross-account peering', () => { - expect(() => { - new route.VPCPeeringConnection(stackA, 'TestCrossAccountPeeringConnection', { - requestorVpc: vpcA, - acceptorVpc: vpcB, - }); - }).toThrow(/Cross account VPC peering requires peerRoleArn/); - }); - test('CIDR block overlap with secondary CIDR block should throw error', () => { expect(() => { - new route.VPCPeeringConnection(stackA, 'TestPeering', { + new route.VPCPeeringConnection(stack, 'TestPeering', { requestorVpc: vpcA, acceptorVpc: vpcC, - peerRoleArn: 'arn:aws:iam::012345678910:role/VpcPeeringRole', + // peerRoleArn: 'arn:aws:iam::012345678910:role/VpcPeeringRole', }); }).toThrow(/CIDR block should not overlap with each other for establishing a peering connection/); }); - test('CIDR block overlap should throw error', () => { - const vpcD = new vpc.VpcV2(stackA, 'VpcD', { + test('CIDR block overlap with primary CIDR block should throw error', () => { + const vpcD = new vpc.VpcV2(stack, 'VpcD', { primaryAddressBlock: vpc.IpAddresses.ipv4('10.0.0.0/16'), }); expect(() => { - new route.VPCPeeringConnection(stackA, 'TestPeering', { + new route.VPCPeeringConnection(stack, 'TestPeering', { requestorVpc: vpcA, acceptorVpc: vpcD, }); From 7cd80098a6d5ff2da424de7534880deac98a10c7 Mon Sep 17 00:00:00 2001 From: shikha372 Date: Thu, 14 Nov 2024 14:49:46 -0800 Subject: [PATCH 30/34] fixing integ test for cross account --- packages/@aws-cdk/aws-ec2-alpha/README.md | 14 +- .../@aws-cdk/aws-ec2-alpha/lib/vpc-v2-base.ts | 12 -- packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2.ts | 10 -- ...efaultTestDeployAssertB5B8DCA8.assets.json | 0 ...aultTestDeployAssertB5B8DCA8.template.json | 0 .../acceptor-stack.assets.json | 20 +++ .../acceptor-stack.template.json | 36 ++++- .../cdk.out | 0 .../integ.json | 0 .../manifest.json | 58 ++++--- .../requestor-stack.assets.json | 20 +++ .../requestor-stack.template.json | 43 ++--- .../tree.json | 151 ++++++++++-------- ...pcpc.ts => integ.peering-cross-account.ts} | 41 +++-- .../acceptor-stack.assets.json | 20 --- .../requestor-stack.assets.json | 20 --- 16 files changed, 238 insertions(+), 207 deletions(-) rename packages/@aws-cdk/aws-ec2-alpha/test/{integ.vpcpc.js.snapshot => integ.peering-cross-account.js.snapshot}/VpcpcCrossAccountIntegDefaultTestDeployAssertB5B8DCA8.assets.json (100%) rename packages/@aws-cdk/aws-ec2-alpha/test/{integ.vpcpc.js.snapshot => integ.peering-cross-account.js.snapshot}/VpcpcCrossAccountIntegDefaultTestDeployAssertB5B8DCA8.template.json (100%) create mode 100644 packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/acceptor-stack.assets.json rename packages/@aws-cdk/aws-ec2-alpha/test/{integ.vpcpc.js.snapshot => integ.peering-cross-account.js.snapshot}/acceptor-stack.template.json (76%) rename packages/@aws-cdk/aws-ec2-alpha/test/{integ.vpcpc.js.snapshot => integ.peering-cross-account.js.snapshot}/cdk.out (100%) rename packages/@aws-cdk/aws-ec2-alpha/test/{integ.vpcpc.js.snapshot => integ.peering-cross-account.js.snapshot}/integ.json (100%) rename packages/@aws-cdk/aws-ec2-alpha/test/{integ.vpcpc.js.snapshot => integ.peering-cross-account.js.snapshot}/manifest.json (79%) create mode 100644 packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/requestor-stack.assets.json rename packages/@aws-cdk/aws-ec2-alpha/test/{integ.vpcpc.js.snapshot => integ.peering-cross-account.js.snapshot}/requestor-stack.template.json (65%) rename packages/@aws-cdk/aws-ec2-alpha/test/{integ.vpcpc.js.snapshot => integ.peering-cross-account.js.snapshot}/tree.json (84%) rename packages/@aws-cdk/aws-ec2-alpha/test/{integ.vpcpc.ts => integ.peering-cross-account.ts} (69%) delete mode 100644 packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/acceptor-stack.assets.json delete mode 100644 packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/requestor-stack.assets.json diff --git a/packages/@aws-cdk/aws-ec2-alpha/README.md b/packages/@aws-cdk/aws-ec2-alpha/README.md index dd99db5a69ff7..334fb4553641f 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/README.md +++ b/packages/@aws-cdk/aws-ec2-alpha/README.md @@ -298,15 +298,19 @@ const acceptorVpc = new VpcV2(this, 'VpcA', { const acceptorRoleArn = acceptorVpc.createAcceptorVpcRole('000000000000') // Requestor account ID ``` -After creating an IAM role in the acceptor account, we can initiate the peering connection request from the requestor VPC. +After creating an IAM role in the acceptor account, we can initiate the peering connection request from the requestor VPC. Import accpeptorVpc to the stack using `fromVpcV2Attributes` method, it is recommended to specify owner account id of the acceptor VPC in case of cross account peering connection, if acceptor VPC is hosted in different region provide region value for import as well. +The following code snippet demonstrates how to set up VPC peering between two VPCs in different AWS accounts using CDK: ```ts const stack = new Stack(); -// TODO: Import acceptorVpc into the requestor stack -const acceptorVpc = new VpcV2(this, 'VpcA', { - primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/16'), -}); +const acceptorVpc = VpcV2.fromVpcV2Attributes(this, 'acceptorVpc', { + //Replace VPC Id before running integ test again + vpcId: 'vpc-XXXX', + vpcCidrBlock: '10.0.0.0/16', + region: 'us-east-2', + ownerAccountId: '111111111111', + }); const acceptorRoleArn = 'arn:aws:iam::111111111111:role/VpcPeeringRole'; diff --git a/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2-base.ts b/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2-base.ts index cadf03304af30..26bde2cb903c8 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2-base.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2-base.ts @@ -1,6 +1,4 @@ import { Aws, Resource, Annotations } from 'aws-cdk-lib'; -import { IVpc, ISubnet, SubnetSelection, SelectedSubnets, EnableVpnGatewayOptions, VpnGateway, VpnConnectionType, CfnVPCGatewayAttachment, CfnVPNGatewayRoutePropagation, VpnConnectionOptions, VpnConnection, ClientVpnEndpointOptions, ClientVpnEndpoint, InterfaceVpcEndpointOptions, InterfaceVpcEndpoint, GatewayVpcEndpointOptions, GatewayVpcEndpoint, FlowLogOptions, FlowLog, FlowLogResourceType, SubnetType, SubnetFilter, CfnVPCCidrBlock } from 'aws-cdk-lib/aws-ec2'; -import { Resource, Annotations } from 'aws-cdk-lib'; import { IVpc, ISubnet, SubnetSelection, SelectedSubnets, EnableVpnGatewayOptions, VpnGateway, VpnConnectionType, CfnVPCGatewayAttachment, CfnVPNGatewayRoutePropagation, VpnConnectionOptions, VpnConnection, ClientVpnEndpointOptions, ClientVpnEndpoint, InterfaceVpcEndpointOptions, InterfaceVpcEndpoint, GatewayVpcEndpointOptions, GatewayVpcEndpoint, FlowLogOptions, FlowLog, FlowLogResourceType, SubnetType, SubnetFilter } from 'aws-cdk-lib/aws-ec2'; import { allRouteTableIds, flatten, subnetGroupNameFromConstructId } from './util'; import { IDependable, Dependable, IConstruct, DependencyGroup } from 'constructs'; @@ -205,16 +203,6 @@ export abstract class VpcV2Base extends Resource implements IVpcV2 { */ public abstract readonly isolatedSubnets: ISubnet[]; - /** - * Region for this VPC - */ - public abstract readonly region?: string; - - /** - * Identifier of the owner for this VPC - */ - public abstract readonly ownerAccountId?: string; - /** * AZs for this VPC */ diff --git a/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2.ts b/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2.ts index de8ef9445a4cd..841bdcb6d8a63 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2.ts @@ -401,16 +401,6 @@ export class VpcV2 extends VpcV2Base { */ public readonly privateSubnets: ISubnet[]; - /** - * Region for this VPC - */ - public readonly region?: string; - - /** - * Identifier of the owner for this VPC - */ - public readonly ownerAccountId?: string; - /** * To define dependency on internet connectivity */ diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/VpcpcCrossAccountIntegDefaultTestDeployAssertB5B8DCA8.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/VpcpcCrossAccountIntegDefaultTestDeployAssertB5B8DCA8.assets.json similarity index 100% rename from packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/VpcpcCrossAccountIntegDefaultTestDeployAssertB5B8DCA8.assets.json rename to packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/VpcpcCrossAccountIntegDefaultTestDeployAssertB5B8DCA8.assets.json diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/VpcpcCrossAccountIntegDefaultTestDeployAssertB5B8DCA8.template.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/VpcpcCrossAccountIntegDefaultTestDeployAssertB5B8DCA8.template.json similarity index 100% rename from packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/VpcpcCrossAccountIntegDefaultTestDeployAssertB5B8DCA8.template.json rename to packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/VpcpcCrossAccountIntegDefaultTestDeployAssertB5B8DCA8.template.json diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/acceptor-stack.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/acceptor-stack.assets.json new file mode 100644 index 0000000000000..3404356133306 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/acceptor-stack.assets.json @@ -0,0 +1,20 @@ +{ + "version": "38.0.1", + "files": { + "e97fe58daf8de56bb30d904e42ed339da043ace5fbeee7c360b161c03cc9a9c3": { + "source": { + "path": "acceptor-stack.template.json", + "packaging": "file" + }, + "destinations": { + "916743627080-us-east-1": { + "bucketName": "cdk-hnb659fds-assets-916743627080-us-east-1", + "objectKey": "e97fe58daf8de56bb30d904e42ed339da043ace5fbeee7c360b161c03cc9a9c3.json", + "region": "us-east-1", + "assumeRoleArn": "arn:${AWS::Partition}:iam::916743627080:role/cdk-hnb659fds-file-publishing-role-916743627080-us-east-1" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/acceptor-stack.template.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/acceptor-stack.template.json similarity index 76% rename from packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/acceptor-stack.template.json rename to packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/acceptor-stack.template.json index 40f646eca36dd..188500fe23879 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/acceptor-stack.template.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/acceptor-stack.template.json @@ -18,7 +18,7 @@ "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { - "AWS": "arn:aws:iam::234567890123:root" + "AWS": "arn:aws:iam::12345678:root" } } ], @@ -44,7 +44,7 @@ { "Ref": "AWS::Partition" }, - ":ec2:us-east-1:234567890123:vpc/", + ":ec2:us-east-1:916743627080:vpc/", { "Fn::GetAtt": [ "acceptorVpc5B7D1670", @@ -67,7 +67,7 @@ { "Ref": "AWS::Partition" }, - ":ec2:us-east-1:234567890123:vpc/", + ":ec2:us-east-1:916743627080:vpc/", { "Fn::GetAtt": [ "acceptorVpc5B7D1670", @@ -88,7 +88,7 @@ { "Ref": "AWS::Partition" }, - ":ec2:us-east-1:234567890123:vpc-peering-connection/*" + ":ec2:us-east-1:916743627080:vpc-peering-connection/*" ] ] } @@ -103,6 +103,34 @@ } ] } + }, + "requestorVpcSameAccountF27E91F7": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.1.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default" + } + }, + "requestorVpcSameAccountsameAccountPeeringVPCPeeringConnection4E07C8CD": { + "Type": "AWS::EC2::VPCPeeringConnection", + "Properties": { + "PeerOwnerId": "916743627080", + "PeerRegion": "us-east-1", + "PeerVpcId": { + "Fn::GetAtt": [ + "acceptorVpc5B7D1670", + "VpcId" + ] + }, + "VpcId": { + "Fn::GetAtt": [ + "requestorVpcSameAccountF27E91F7", + "VpcId" + ] + } + } } }, "Parameters": { diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/cdk.out b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/cdk.out similarity index 100% rename from packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/cdk.out rename to packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/cdk.out diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/integ.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/integ.json similarity index 100% rename from packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/integ.json rename to packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/integ.json diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/manifest.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/manifest.json similarity index 79% rename from packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/manifest.json rename to packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/manifest.json index 181d22a9525fb..57a05f2fe2528 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/manifest.json @@ -11,22 +11,22 @@ }, "acceptor-stack": { "type": "aws:cloudformation:stack", - "environment": "aws://234567890123/us-east-1", + "environment": "aws://916743627080/us-east-1", "properties": { "templateFile": "acceptor-stack.template.json", "terminationProtection": false, "validateOnSynth": false, "notificationArns": [], - "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-deploy-role-234567890123-us-east-1", - "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-cfn-exec-role-234567890123-us-east-1", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-234567890123-us-east-1/0f24269a2562149271e39a0d72b62808fb6210582ae268699403114701a77f7d.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::916743627080:role/cdk-hnb659fds-deploy-role-916743627080-us-east-1", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::916743627080:role/cdk-hnb659fds-cfn-exec-role-916743627080-us-east-1", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-916743627080-us-east-1/e97fe58daf8de56bb30d904e42ed339da043ace5fbeee7c360b161c03cc9a9c3.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ "acceptor-stack.assets" ], "lookupRole": { - "arn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-lookup-role-234567890123-us-east-1", + "arn": "arn:${AWS::Partition}:iam::916743627080:role/cdk-hnb659fds-lookup-role-916743627080-us-east-1", "requiresBootstrapStackVersion": 8, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" } @@ -53,6 +53,21 @@ "data": "acceptorVpcVpcPeeringRoleDefaultPolicyE79C72D0" } ], + "/acceptor-stack/requestorVpcSameAccount/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "requestorVpcSameAccountF27E91F7" + } + ], + "/acceptor-stack/requestorVpcSameAccount/sameAccountPeering/VPCPeeringConnection": [ + { + "type": "aws:cdk:logicalId", + "data": "requestorVpcSameAccountsameAccountPeeringVPCPeeringConnection4E07C8CD", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_REPLACE" + ] + } + ], "/acceptor-stack/BootstrapVersion": [ { "type": "aws:cdk:logicalId", @@ -78,22 +93,22 @@ }, "requestor-stack": { "type": "aws:cloudformation:stack", - "environment": "aws://123456789012/us-east-1", + "environment": "aws://12345678/us-east-1", "properties": { "templateFile": "requestor-stack.template.json", "terminationProtection": false, "validateOnSynth": false, "notificationArns": [], - "assumeRoleArn": "arn:${AWS::Partition}:iam::123456789012:role/cdk-hnb659fds-deploy-role-123456789012-us-east-1", - "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::123456789012:role/cdk-hnb659fds-cfn-exec-role-123456789012-us-east-1", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-123456789012-us-east-1/97ed73811c6238b5ca810c262385064a85e50d171ac8685e8aa595963d0ed115.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-deploy-role-12345678-us-east-1", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-cfn-exec-role-12345678-us-east-1", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-12345678-us-east-1/5dcf720ce4f65c20539f2ee806749786ee4a48fa104e0ab316e3c903a2e20d24.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ "requestor-stack.assets" ], "lookupRole": { - "arn": "arn:${AWS::Partition}:iam::123456789012:role/cdk-hnb659fds-lookup-role-123456789012-us-east-1", + "arn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-lookup-role-12345678-us-east-1", "requiresBootstrapStackVersion": 8, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" } @@ -102,28 +117,19 @@ "requestor-stack.assets" ], "metadata": { - "/requestor-stack/requestorVpc/Resource": [ - { - "type": "aws:cdk:logicalId", - "data": "requestorVpcFFA7DDD4" - } - ], - "/requestor-stack/requestorVpc/TempBlock": [ - { - "type": "aws:cdk:logicalId", - "data": "requestorVpcTempBlock78E0B4F4" - } - ], - "/requestor-stack/VpcB/Resource": [ + "/requestor-stack/requestorVpcCrossAccount/Resource": [ { "type": "aws:cdk:logicalId", - "data": "VpcB98A08B07" + "data": "requestorVpcCrossAccount6372A252" } ], - "/requestor-stack/VpcB/acceptorAccountCrossRegionPeering/VPCPeeringConnection": [ + "/requestor-stack/requestorVpcCrossAccount/acceptorAccountCrossRegionPeering/VPCPeeringConnection": [ { "type": "aws:cdk:logicalId", - "data": "VpcBacceptorAccountCrossRegionPeeringVPCPeeringConnection8510BFF3" + "data": "requestorVpcCrossAccountacceptorAccountCrossRegionPeeringVPCPeeringConnection3605B6B0", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_REPLACE" + ] } ], "/requestor-stack/RouteTable/RouteTable": [ diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/requestor-stack.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/requestor-stack.assets.json new file mode 100644 index 0000000000000..586d449f3ea87 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/requestor-stack.assets.json @@ -0,0 +1,20 @@ +{ + "version": "38.0.1", + "files": { + "5dcf720ce4f65c20539f2ee806749786ee4a48fa104e0ab316e3c903a2e20d24": { + "source": { + "path": "requestor-stack.template.json", + "packaging": "file" + }, + "destinations": { + "12345678-us-east-1": { + "bucketName": "cdk-hnb659fds-assets-12345678-us-east-1", + "objectKey": "5dcf720ce4f65c20539f2ee806749786ee4a48fa104e0ab316e3c903a2e20d24.json", + "region": "us-east-1", + "assumeRoleArn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-file-publishing-role-12345678-us-east-1" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/requestor-stack.template.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/requestor-stack.template.json similarity index 65% rename from packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/requestor-stack.template.json rename to packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/requestor-stack.template.json index d2ec40b042e07..6aca00bac17e3 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/requestor-stack.template.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/requestor-stack.template.json @@ -1,27 +1,6 @@ { "Resources": { - "requestorVpcFFA7DDD4": { - "Type": "AWS::EC2::VPC", - "Properties": { - "CidrBlock": "10.1.0.0/16", - "EnableDnsHostnames": true, - "EnableDnsSupport": true, - "InstanceTenancy": "default" - } - }, - "requestorVpcTempBlock78E0B4F4": { - "Type": "AWS::EC2::VPCCidrBlock", - "Properties": { - "CidrBlock": "10.3.0.0/16", - "VpcId": { - "Fn::GetAtt": [ - "requestorVpcFFA7DDD4", - "VpcId" - ] - } - } - }, - "VpcB98A08B07": { + "requestorVpcCrossAccount6372A252": { "Type": "AWS::EC2::VPC", "Properties": { "CidrBlock": "10.2.0.0/16", @@ -30,20 +9,16 @@ "InstanceTenancy": "default" } }, - "VpcBacceptorAccountCrossRegionPeeringVPCPeeringConnection8510BFF3": { + "requestorVpcCrossAccountacceptorAccountCrossRegionPeeringVPCPeeringConnection3605B6B0": { "Type": "AWS::EC2::VPCPeeringConnection", "Properties": { - "PeerOwnerId": "12345678", + "PeerOwnerId": "916743627080", "PeerRegion": "us-east-1", - "PeerVpcId": { - "Fn::GetAtt": [ - "requestorVpcFFA7DDD4", - "VpcId" - ] - }, + "PeerRoleArn": "arn:aws:iam::916743627080:role/VpcPeeringRole", + "PeerVpcId": "vpc-09b9235d8a3195ba3", "VpcId": { "Fn::GetAtt": [ - "VpcB98A08B07", + "requestorVpcCrossAccount6372A252", "VpcId" ] } @@ -54,7 +29,7 @@ "Properties": { "VpcId": { "Fn::GetAtt": [ - "VpcB98A08B07", + "requestorVpcCrossAccount6372A252", "VpcId" ] } @@ -72,13 +47,13 @@ }, "VpcPeeringConnectionId": { "Fn::GetAtt": [ - "VpcBacceptorAccountCrossRegionPeeringVPCPeeringConnection8510BFF3", + "requestorVpcCrossAccountacceptorAccountCrossRegionPeeringVPCPeeringConnection3605B6B0", "Id" ] } }, "DependsOn": [ - "VpcBacceptorAccountCrossRegionPeeringVPCPeeringConnection8510BFF3" + "requestorVpcCrossAccountacceptorAccountCrossRegionPeeringVPCPeeringConnection3605B6B0" ] } }, diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/tree.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/tree.json similarity index 84% rename from packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/tree.json rename to packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/tree.json index b4edf1295d79b..2348237ed39a3 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/tree.json @@ -53,7 +53,7 @@ "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { - "AWS": "arn:aws:iam::234567890123:root" + "AWS": "arn:aws:iam::12345678:root" } } ], @@ -91,7 +91,7 @@ { "Ref": "AWS::Partition" }, - ":ec2:us-east-1:234567890123:vpc/", + ":ec2:us-east-1:916743627080:vpc/", { "Fn::GetAtt": [ "acceptorVpc5B7D1670", @@ -114,7 +114,7 @@ { "Ref": "AWS::Partition" }, - ":ec2:us-east-1:234567890123:vpc/", + ":ec2:us-east-1:916743627080:vpc/", { "Fn::GetAtt": [ "acceptorVpc5B7D1670", @@ -135,7 +135,7 @@ { "Ref": "AWS::Partition" }, - ":ec2:us-east-1:234567890123:vpc-peering-connection/*" + ":ec2:us-east-1:916743627080:vpc-peering-connection/*" ] ] } @@ -174,39 +174,13 @@ "version": "0.0.0" } }, - "BootstrapVersion": { - "id": "BootstrapVersion", - "path": "acceptor-stack/BootstrapVersion", - "constructInfo": { - "fqn": "aws-cdk-lib.CfnParameter", - "version": "0.0.0" - } - }, - "CheckBootstrapVersion": { - "id": "CheckBootstrapVersion", - "path": "acceptor-stack/CheckBootstrapVersion", - "constructInfo": { - "fqn": "aws-cdk-lib.CfnRule", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.Stack", - "version": "0.0.0" - } - }, - "requestor-stack": { - "id": "requestor-stack", - "path": "requestor-stack", - "children": { - "requestorVpc": { - "id": "requestorVpc", - "path": "requestor-stack/requestorVpc", + "requestorVpcSameAccount": { + "id": "requestorVpcSameAccount", + "path": "acceptor-stack/requestorVpcSameAccount", "children": { "Resource": { "id": "Resource", - "path": "requestor-stack/requestorVpc/Resource", + "path": "acceptor-stack/requestorVpcSameAccount/Resource", "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::VPC", "aws:cdk:cloudformation:props": { @@ -221,23 +195,40 @@ "version": "0.0.0" } }, - "TempBlock": { - "id": "TempBlock", - "path": "requestor-stack/requestorVpc/TempBlock", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::EC2::VPCCidrBlock", - "aws:cdk:cloudformation:props": { - "cidrBlock": "10.3.0.0/16", - "vpcId": { - "Fn::GetAtt": [ - "requestorVpcFFA7DDD4", - "VpcId" - ] + "sameAccountPeering": { + "id": "sameAccountPeering", + "path": "acceptor-stack/requestorVpcSameAccount/sameAccountPeering", + "children": { + "VPCPeeringConnection": { + "id": "VPCPeeringConnection", + "path": "acceptor-stack/requestorVpcSameAccount/sameAccountPeering/VPCPeeringConnection", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPCPeeringConnection", + "aws:cdk:cloudformation:props": { + "peerOwnerId": "916743627080", + "peerRegion": "us-east-1", + "peerVpcId": { + "Fn::GetAtt": [ + "acceptorVpc5B7D1670", + "VpcId" + ] + }, + "vpcId": { + "Fn::GetAtt": [ + "requestorVpcSameAccountF27E91F7", + "VpcId" + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnVPCPeeringConnection", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_ec2.CfnVPCCidrBlock", + "fqn": "@aws-cdk/aws-ec2-alpha.VPCPeeringConnection", "version": "0.0.0" } } @@ -247,13 +238,47 @@ "version": "0.0.0" } }, - "VpcB": { - "id": "VpcB", - "path": "requestor-stack/VpcB", + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "acceptor-stack/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "acceptor-stack/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "requestor-stack": { + "id": "requestor-stack", + "path": "requestor-stack", + "children": { + "acceptorVpc": { + "id": "acceptorVpc", + "path": "requestor-stack/acceptorVpc", + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2-alpha.VpcV2Base", + "version": "0.0.0" + } + }, + "requestorVpcCrossAccount": { + "id": "requestorVpcCrossAccount", + "path": "requestor-stack/requestorVpcCrossAccount", "children": { "Resource": { "id": "Resource", - "path": "requestor-stack/VpcB/Resource", + "path": "requestor-stack/requestorVpcCrossAccount/Resource", "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::VPC", "aws:cdk:cloudformation:props": { @@ -270,25 +295,21 @@ }, "acceptorAccountCrossRegionPeering": { "id": "acceptorAccountCrossRegionPeering", - "path": "requestor-stack/VpcB/acceptorAccountCrossRegionPeering", + "path": "requestor-stack/requestorVpcCrossAccount/acceptorAccountCrossRegionPeering", "children": { "VPCPeeringConnection": { "id": "VPCPeeringConnection", - "path": "requestor-stack/VpcB/acceptorAccountCrossRegionPeering/VPCPeeringConnection", + "path": "requestor-stack/requestorVpcCrossAccount/acceptorAccountCrossRegionPeering/VPCPeeringConnection", "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::VPCPeeringConnection", "aws:cdk:cloudformation:props": { - "peerOwnerId": "123456789012", + "peerOwnerId": "916743627080", "peerRegion": "us-east-1", - "peerVpcId": { - "Fn::GetAtt": [ - "requestorVpcFFA7DDD4", - "VpcId" - ] - }, + "peerRoleArn": "arn:aws:iam::916743627080:role/VpcPeeringRole", + "peerVpcId": "vpc-09b9235d8a3195ba3", "vpcId": { "Fn::GetAtt": [ - "VpcB98A08B07", + "requestorVpcCrossAccount6372A252", "VpcId" ] } @@ -323,7 +344,7 @@ "aws:cdk:cloudformation:props": { "vpcId": { "Fn::GetAtt": [ - "VpcB98A08B07", + "requestorVpcCrossAccount6372A252", "VpcId" ] } @@ -353,7 +374,7 @@ }, "vpcPeeringConnectionId": { "Fn::GetAtt": [ - "VpcBacceptorAccountCrossRegionPeeringVPCPeeringConnection8510BFF3", + "requestorVpcCrossAccountacceptorAccountCrossRegionPeeringVPCPeeringConnection3605B6B0", "Id" ] } @@ -411,7 +432,7 @@ "path": "VpcpcCrossAccountInteg/DefaultTest/Default", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.3.0" + "version": "10.4.2" } }, "DeployAssert": { @@ -457,7 +478,7 @@ "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.3.0" + "version": "10.4.2" } } }, diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.ts b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.ts similarity index 69% rename from packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.ts rename to packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.ts index c0106993e9664..413c327a366c8 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.ts @@ -18,14 +18,19 @@ * - assuming this is the default profile for aws credentials * * 2. Set environment variables - * a. `export CDK_INTEG_ACCOUNT=123456789012` - * b. `export CDK_INTEG_CROSS_ACCOUNT=234567890123` + * a. `export CDK_INTEG_ACCOUNT=123456789012` //Requestor Account + * b. `export CDK_INTEG_CROSS_ACCOUNT=234567890123` //Acceptor Account * - * 3. Run the integ test (from the @aws-cdk/aws-ec2-alpha/test directory) + * 3. Run the integ test (from the @aws-cdk/aws-ec2-alpha/test directory)with no clean flag * a. Get temporary console access credentials for Requestor Account - * - `yarn integ test/integ.vpcpc.js` + * - `yarn integ test/integ.vpcpc.js --no-clean` * b. Fall back if temp credentials do not work (account info may be in snapshot) * - `yarn integ test/integ.vpcpc.js --profiles cross-account` + * Note: Integration test will fail since vpcId of acceptor stack is a dummy value + * + * 4. Modify acceptorVpcId to actual physical Id and rerun the integration test to + * test cross account peering + * - `yarn integ test/integ.vpcpc.js` */ import * as vpc_v2 from '../lib/vpc-v2'; @@ -45,7 +50,18 @@ class AcceptorStack extends cdk.Stack { const acceptorVpc = new vpc_v2.VpcV2(this, 'acceptorVpc', { primaryAddressBlock: vpc_v2.IpAddresses.ipv4('10.0.0.0/16'), }); - acceptorVpc.createAcceptorVpcRole(acceptorAccount); + + //Same account VPC peering + const requestorVpc = new vpc_v2.VpcV2(this, 'requestorVpcSameAccount', { + primaryAddressBlock: vpc_v2.IpAddresses.ipv4('10.1.0.0/16'), + }); + + requestorVpc.createPeeringConnection('sameAccountPeering', { + acceptorVpc: acceptorVpc, + }); + + //For cross-account peering connection + acceptorVpc.createAcceptorVpcRole(account); } } @@ -53,19 +69,22 @@ class RequestorStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); - // TODO: Import acceptorVpc into the requestor stack - // Once implemented, need to test for cross account - const acceptorVpc = new vpc_v2.VpcV2(this, 'requestorVpc', { - primaryAddressBlock: vpc_v2.IpAddresses.ipv4('10.1.0.0/16'), - secondaryAddressBlocks: [vpc_v2.IpAddresses.ipv4('10.3.0.0/16', { cidrBlockName: 'TempBlock' })], + //Import acceptorVpc into the requestor stack, change vpcId after vpc is created using acceptorStack definition + const acceptorVpc = vpc_v2.VpcV2.fromVpcV2Attributes(this, 'acceptorVpc', { + //Replace VPC Id before running integ test again + vpcId: 'vpc-09b9235d8a3195ba3', + vpcCidrBlock: '10.0.0.0/16', + region: 'us-east-1', + ownerAccountId: acceptorAccount, }); - const requestorVpc = new vpc_v2.VpcV2(this, 'VpcB', { + const requestorVpc = new vpc_v2.VpcV2(this, 'requestorVpcCrossAccount', { primaryAddressBlock: vpc_v2.IpAddresses.ipv4('10.2.0.0/16'), }); const peeringConnection = requestorVpc.createPeeringConnection('acceptorAccountCrossRegionPeering', { acceptorVpc: acceptorVpc, + peerRoleArn: 'arn:aws:iam::916743627080:role/VpcPeeringRole', }); const routeTable = new RouteTable(this, 'RouteTable', { diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/acceptor-stack.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/acceptor-stack.assets.json deleted file mode 100644 index 5caef75119bf9..0000000000000 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/acceptor-stack.assets.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "version": "38.0.1", - "files": { - "0f24269a2562149271e39a0d72b62808fb6210582ae268699403114701a77f7d": { - "source": { - "path": "acceptor-stack.template.json", - "packaging": "file" - }, - "destinations": { - "234567890123-us-east-1": { - "bucketName": "cdk-hnb659fds-assets-234567890123-us-east-1", - "objectKey": "0f24269a2562149271e39a0d72b62808fb6210582ae268699403114701a77f7d.json", - "region": "us-east-1", - "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-file-publishing-role-234567890123-us-east-1" - } - } - } - }, - "dockerImages": {} -} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/requestor-stack.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/requestor-stack.assets.json deleted file mode 100644 index 7a4af96bbe403..0000000000000 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.vpcpc.js.snapshot/requestor-stack.assets.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "version": "38.0.1", - "files": { - "97ed73811c6238b5ca810c262385064a85e50d171ac8685e8aa595963d0ed115": { - "source": { - "path": "requestor-stack.template.json", - "packaging": "file" - }, - "destinations": { - "123456789012-us-east-1": { - "bucketName": "cdk-hnb659fds-assets-123456789012-us-east-1", - "objectKey": "97ed73811c6238b5ca810c262385064a85e50d171ac8685e8aa595963d0ed115.json", - "region": "us-east-1", - "assumeRoleArn": "arn:${AWS::Partition}:iam::123456789012:role/cdk-hnb659fds-file-publishing-role-123456789012-us-east-1" - } - } - } - }, - "dockerImages": {} -} \ No newline at end of file From 9ceb78dcf7bda92a4749f9dc902db73b60b3db1d Mon Sep 17 00:00:00 2001 From: shikha372 Date: Fri, 15 Nov 2024 10:46:16 -0800 Subject: [PATCH 31/34] fixing account id in test snapshot --- .../acceptor-stack.assets.json | 10 +++++----- .../acceptor-stack.template.json | 8 ++++---- .../manifest.json | 12 ++++++------ .../requestor-stack.assets.json | 4 ++-- .../requestor-stack.template.json | 2 +- .../tree.json | 10 +++++----- 6 files changed, 23 insertions(+), 23 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/acceptor-stack.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/acceptor-stack.assets.json index 3404356133306..a1d772336ff2e 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/acceptor-stack.assets.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/acceptor-stack.assets.json @@ -1,17 +1,17 @@ { "version": "38.0.1", "files": { - "e97fe58daf8de56bb30d904e42ed339da043ace5fbeee7c360b161c03cc9a9c3": { + "34c1052a8eb4080f81a8ce579f7e552334e70d6019ef73deaf914358f9d679d1": { "source": { "path": "acceptor-stack.template.json", "packaging": "file" }, "destinations": { - "916743627080-us-east-1": { - "bucketName": "cdk-hnb659fds-assets-916743627080-us-east-1", - "objectKey": "e97fe58daf8de56bb30d904e42ed339da043ace5fbeee7c360b161c03cc9a9c3.json", + "234567890123-us-east-1": { + "bucketName": "cdk-hnb659fds-assets-234567890123-us-east-1", + "objectKey": "34c1052a8eb4080f81a8ce579f7e552334e70d6019ef73deaf914358f9d679d1.json", "region": "us-east-1", - "assumeRoleArn": "arn:${AWS::Partition}:iam::916743627080:role/cdk-hnb659fds-file-publishing-role-916743627080-us-east-1" + "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-file-publishing-role-234567890123-us-east-1" } } } diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/acceptor-stack.template.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/acceptor-stack.template.json index 188500fe23879..72217fdffef18 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/acceptor-stack.template.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/acceptor-stack.template.json @@ -44,7 +44,7 @@ { "Ref": "AWS::Partition" }, - ":ec2:us-east-1:916743627080:vpc/", + ":ec2:us-east-1:234567890123:vpc/", { "Fn::GetAtt": [ "acceptorVpc5B7D1670", @@ -67,7 +67,7 @@ { "Ref": "AWS::Partition" }, - ":ec2:us-east-1:916743627080:vpc/", + ":ec2:us-east-1:234567890123:vpc/", { "Fn::GetAtt": [ "acceptorVpc5B7D1670", @@ -88,7 +88,7 @@ { "Ref": "AWS::Partition" }, - ":ec2:us-east-1:916743627080:vpc-peering-connection/*" + ":ec2:us-east-1:234567890123:vpc-peering-connection/*" ] ] } @@ -116,7 +116,7 @@ "requestorVpcSameAccountsameAccountPeeringVPCPeeringConnection4E07C8CD": { "Type": "AWS::EC2::VPCPeeringConnection", "Properties": { - "PeerOwnerId": "916743627080", + "PeerOwnerId": "234567890123", "PeerRegion": "us-east-1", "PeerVpcId": { "Fn::GetAtt": [ diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/manifest.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/manifest.json index 57a05f2fe2528..67e4520ec29e0 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/manifest.json @@ -11,22 +11,22 @@ }, "acceptor-stack": { "type": "aws:cloudformation:stack", - "environment": "aws://916743627080/us-east-1", + "environment": "aws://234567890123/us-east-1", "properties": { "templateFile": "acceptor-stack.template.json", "terminationProtection": false, "validateOnSynth": false, "notificationArns": [], - "assumeRoleArn": "arn:${AWS::Partition}:iam::916743627080:role/cdk-hnb659fds-deploy-role-916743627080-us-east-1", - "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::916743627080:role/cdk-hnb659fds-cfn-exec-role-916743627080-us-east-1", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-916743627080-us-east-1/e97fe58daf8de56bb30d904e42ed339da043ace5fbeee7c360b161c03cc9a9c3.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-deploy-role-234567890123-us-east-1", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-cfn-exec-role-234567890123-us-east-1", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-234567890123-us-east-1/34c1052a8eb4080f81a8ce579f7e552334e70d6019ef73deaf914358f9d679d1.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ "acceptor-stack.assets" ], "lookupRole": { - "arn": "arn:${AWS::Partition}:iam::916743627080:role/cdk-hnb659fds-lookup-role-916743627080-us-east-1", + "arn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-lookup-role-234567890123-us-east-1", "requiresBootstrapStackVersion": 8, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" } @@ -101,7 +101,7 @@ "notificationArns": [], "assumeRoleArn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-deploy-role-12345678-us-east-1", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-cfn-exec-role-12345678-us-east-1", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-12345678-us-east-1/5dcf720ce4f65c20539f2ee806749786ee4a48fa104e0ab316e3c903a2e20d24.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-12345678-us-east-1/a3dc1b1e845e0078e800b7fcd60d3634a2ab75ac0074794c0344338afc77b16f.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/requestor-stack.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/requestor-stack.assets.json index 586d449f3ea87..1aa5990e5adb9 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/requestor-stack.assets.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/requestor-stack.assets.json @@ -1,7 +1,7 @@ { "version": "38.0.1", "files": { - "5dcf720ce4f65c20539f2ee806749786ee4a48fa104e0ab316e3c903a2e20d24": { + "a3dc1b1e845e0078e800b7fcd60d3634a2ab75ac0074794c0344338afc77b16f": { "source": { "path": "requestor-stack.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "12345678-us-east-1": { "bucketName": "cdk-hnb659fds-assets-12345678-us-east-1", - "objectKey": "5dcf720ce4f65c20539f2ee806749786ee4a48fa104e0ab316e3c903a2e20d24.json", + "objectKey": "a3dc1b1e845e0078e800b7fcd60d3634a2ab75ac0074794c0344338afc77b16f.json", "region": "us-east-1", "assumeRoleArn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-file-publishing-role-12345678-us-east-1" } diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/requestor-stack.template.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/requestor-stack.template.json index 6aca00bac17e3..b975fceab7bb4 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/requestor-stack.template.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/requestor-stack.template.json @@ -12,7 +12,7 @@ "requestorVpcCrossAccountacceptorAccountCrossRegionPeeringVPCPeeringConnection3605B6B0": { "Type": "AWS::EC2::VPCPeeringConnection", "Properties": { - "PeerOwnerId": "916743627080", + "PeerOwnerId": "234567890123", "PeerRegion": "us-east-1", "PeerRoleArn": "arn:aws:iam::916743627080:role/VpcPeeringRole", "PeerVpcId": "vpc-09b9235d8a3195ba3", diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/tree.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/tree.json index 2348237ed39a3..cfd1493b0ca60 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.peering-cross-account.js.snapshot/tree.json @@ -91,7 +91,7 @@ { "Ref": "AWS::Partition" }, - ":ec2:us-east-1:916743627080:vpc/", + ":ec2:us-east-1:234567890123:vpc/", { "Fn::GetAtt": [ "acceptorVpc5B7D1670", @@ -114,7 +114,7 @@ { "Ref": "AWS::Partition" }, - ":ec2:us-east-1:916743627080:vpc/", + ":ec2:us-east-1:234567890123:vpc/", { "Fn::GetAtt": [ "acceptorVpc5B7D1670", @@ -135,7 +135,7 @@ { "Ref": "AWS::Partition" }, - ":ec2:us-east-1:916743627080:vpc-peering-connection/*" + ":ec2:us-east-1:234567890123:vpc-peering-connection/*" ] ] } @@ -205,7 +205,7 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::VPCPeeringConnection", "aws:cdk:cloudformation:props": { - "peerOwnerId": "916743627080", + "peerOwnerId": "234567890123", "peerRegion": "us-east-1", "peerVpcId": { "Fn::GetAtt": [ @@ -303,7 +303,7 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::VPCPeeringConnection", "aws:cdk:cloudformation:props": { - "peerOwnerId": "916743627080", + "peerOwnerId": "234567890123", "peerRegion": "us-east-1", "peerRoleArn": "arn:aws:iam::916743627080:role/VpcPeeringRole", "peerVpcId": "vpc-09b9235d8a3195ba3", From c0949b54ce2de69fc5d0a6d47b985ba91a9c0e7a Mon Sep 17 00:00:00 2001 From: shikha372 Date: Mon, 18 Nov 2024 11:24:17 -0800 Subject: [PATCH 32/34] adding unit test fixes --- .../@aws-cdk/aws-ec2-alpha/test/route.test.ts | 73 ++++++++----------- 1 file changed, 31 insertions(+), 42 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts b/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts index 83909367d5b73..dfaa1f68caa8d 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/test/route.test.ts @@ -516,13 +516,10 @@ describe('EC2 Routing', () => { describe('VPCPeeringConnection', () => { - let stack: cdk.Stack; - /* - // Uncomment when lookup is implemented let stackA: cdk.Stack; let stackB: cdk.Stack; let stackC: cdk.Stack; - */ + let vpcA: vpc.VpcV2; let vpcB: vpc.VpcV2; let vpcC: vpc.VpcV2; @@ -534,23 +531,9 @@ describe('VPCPeeringConnection', () => { }, }); - stack = new cdk.Stack(app, 'VpcStack' ); - vpcA = new vpc.VpcV2(stack, 'VpcA', { - primaryAddressBlock: vpc.IpAddresses.ipv4('10.0.0.0/16'), - secondaryAddressBlocks: [vpc.IpAddresses.ipv4('10.1.0.0/16', { cidrBlockName: 'TempSecondaryBlock' })], - }); - vpcB = new vpc.VpcV2(stack, 'VpcB', { - primaryAddressBlock: vpc.IpAddresses.ipv4('10.2.0.0/16'), - }); - vpcC = new vpc.VpcV2(stack, 'VpcC', { - primaryAddressBlock: vpc.IpAddresses.ipv4('10.1.0.0/16'), - }); - - /* - // Uncomment when lookup is implemented stackA = new cdk.Stack(app, 'VpcStackA', { env: { account: '234567890123', region: 'us-east-1' } }); stackB = new cdk.Stack(app, 'VpcStackB', { env: { account: '123456789012', region: 'us-east-1' } }); - stackC = new cdk.Stack(app, 'VpcStackC', { env: { account: '123456789012', region: 'us-west-2' } }); + stackC = new cdk.Stack(app, 'VpcStackC', { env: { account: '123456789012', region: 'us-west-2' }, crossRegionReferences: true }); vpcA = new vpc.VpcV2(stackA, 'VpcA', { primaryAddressBlock: vpc.IpAddresses.ipv4('10.0.0.0/16'), @@ -562,18 +545,21 @@ describe('VPCPeeringConnection', () => { vpcC = new vpc.VpcV2(stackC, 'VpcC', { primaryAddressBlock: vpc.IpAddresses.ipv4('10.1.0.0/16'), }); - */ - }); - // eslint-disable-next-line jest/no-commented-out-tests - /* - // Test cases currently can't be used until the lookup function is implemented - // TODO: Lookup the acceptorVPC for the corresponding stack in each test case + }); test('Creates a cross account VPC peering connection', () => { + + const importedVpcB = vpc.VpcV2.fromVpcV2Attributes(stackA, 'VpcB', { + vpcId: 'mockVpcBId', //cross account stack references are not supported + vpcCidrBlock: '10.2.0.0/16', + region: vpcB.env.region, + ownerAccountId: '123456789012', + }); + new route.VPCPeeringConnection(stackA, 'TestPeeringConnection', { requestorVpc: vpcA, - acceptorVpc: vpcB, + acceptorVpc: importedVpcB, peerRoleArn: 'arn:aws:iam::012345678910:role/VpcPeeringRole', }); const template = Template.fromStack(stackA); @@ -582,45 +568,48 @@ describe('VPCPeeringConnection', () => { VpcId: { 'Fn::GetAtt': ['VpcAAD85CA4C', 'VpcId'], }, - PeerVpcId: { - 'Fn::GetAtt': ['VpcB98A08B07', 'VpcId'], - }, - PeerOwnerId: '012345678910', + PeerVpcId: 'mockVpcBId', + PeerOwnerId: '123456789012', PeerRegion: 'us-east-1', }); }); test('Creates a cross region VPC peering connection', () => { + + const importedVpcC = vpc.VpcV2.fromVpcV2Attributes(stackA, 'VpcB', { + vpcId: 'mockVpcCId', //cross account stack references are not supported + vpcCidrBlock: '10.3.0.0/16', + region: vpcC.env.region, + ownerAccountId: '123456789012', + }); + new route.VPCPeeringConnection(stackB, 'TestCrossRegionPeeringConnection', { requestorVpc: vpcB, - acceptorVpc: vpcC, + acceptorVpc: importedVpcC, }); Template.fromStack(stackB).hasResourceProperties('AWS::EC2::VPCPeeringConnection', { VpcId: { 'Fn::GetAtt': ['VpcB98A08B07', 'VpcId'], }, - PeerVpcId: { - 'Fn::GetAtt': ['VpcC211819BA', 'VpcId'], - }, - PeerOwnerId: '012345678910', + PeerVpcId: 'mockVpcCId', + PeerOwnerId: '123456789012', PeerRegion: 'us-west-2', }); }); test('Throws error when peerRoleArn is not provided for cross-account peering', () => { expect(() => { - new route.VPCPeeringConnection(stack, 'TestCrossAccountPeeringConnection', { + new route.VPCPeeringConnection(stackA, 'TestCrossAccountPeeringConnection', { requestorVpc: vpcA, acceptorVpc: vpcB, }); }).toThrow(/Cross account VPC peering requires peerRoleArn/); }); - */ test('Throws error when peerRoleArn is provided for same account peering', () => { expect(() => { - new route.VPCPeeringConnection(stack, 'TestPeeringConnection', { + new route.VPCPeeringConnection(stackB, 'TestPeeringConnection', { requestorVpc: vpcB, acceptorVpc: vpcC, peerRoleArn: 'arn:aws:iam::123456789012:role/unnecessary-role', @@ -630,21 +619,21 @@ describe('VPCPeeringConnection', () => { test('CIDR block overlap with secondary CIDR block should throw error', () => { expect(() => { - new route.VPCPeeringConnection(stack, 'TestPeering', { + new route.VPCPeeringConnection(stackA, 'TestPeering', { requestorVpc: vpcA, acceptorVpc: vpcC, - // peerRoleArn: 'arn:aws:iam::012345678910:role/VpcPeeringRole', + peerRoleArn: 'arn:aws:iam::012345678910:role/VpcPeeringRole', }); }).toThrow(/CIDR block should not overlap with each other for establishing a peering connection/); }); test('CIDR block overlap with primary CIDR block should throw error', () => { - const vpcD = new vpc.VpcV2(stack, 'VpcD', { + const vpcD = new vpc.VpcV2(stackA, 'VpcD', { primaryAddressBlock: vpc.IpAddresses.ipv4('10.0.0.0/16'), }); expect(() => { - new route.VPCPeeringConnection(stack, 'TestPeering', { + new route.VPCPeeringConnection(stackA, 'TestPeering', { requestorVpc: vpcA, acceptorVpc: vpcD, }); From 882a0b5a695415ffefc8490d8a60826528b42060 Mon Sep 17 00:00:00 2001 From: shikha372 Date: Tue, 19 Nov 2024 12:00:32 -0800 Subject: [PATCH 33/34] fixing Readme --- packages/@aws-cdk/aws-ec2-alpha/README.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/README.md b/packages/@aws-cdk/aws-ec2-alpha/README.md index 334fb4553641f..46411b4912776 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/README.md +++ b/packages/@aws-cdk/aws-ec2-alpha/README.md @@ -272,11 +272,18 @@ const vpcA = new VpcV2(stackA, 'VpcA', { primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/16'), }); -const vpcB = new VpcV2(stackB, 'VpcB', { +new VpcV2(stackB, 'VpcB', { primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'), }); -// TODO: Lookup vpcB in stackA +const vpcB = VpcV2.fromVpcV2Attributes(stackA, 'ImportedVpcB', { + vpcId: 'MockVpcBid', + vpcCidrBlock: '10.1.0.0/16', + region: 'us-west-2', + ownerAccountId: '111111111111', + }); + + const peeringConnection = vpcA.createPeeringConnection('sameAccountCrossRegionPeering', { acceptorVpc: vpcB, }); @@ -305,7 +312,6 @@ The following code snippet demonstrates how to set up VPC peering between two VP const stack = new Stack(); const acceptorVpc = VpcV2.fromVpcV2Attributes(this, 'acceptorVpc', { - //Replace VPC Id before running integ test again vpcId: 'vpc-XXXX', vpcCidrBlock: '10.0.0.0/16', region: 'us-east-2', From 2a8f8b688ee875703ba8c02286af23bec46220c7 Mon Sep 17 00:00:00 2001 From: shikha372 Date: Tue, 19 Nov 2024 15:43:06 -0800 Subject: [PATCH 34/34] modifying ReadMe --- packages/@aws-cdk/aws-ec2-alpha/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2-alpha/README.md b/packages/@aws-cdk/aws-ec2-alpha/README.md index 46411b4912776..21d5ff793016b 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/README.md +++ b/packages/@aws-cdk/aws-ec2-alpha/README.md @@ -260,13 +260,13 @@ const peeringConnection = vpcA.createPeeringConnection('sameAccountSameRegionPee **Case 2: Same Account and Cross Region Peering Connection** -There is no difference from Case 1 when calling `createPeeringConnection`. The only change is that one of the VPCs are created in another stack with a different region. +There is no difference from Case 1 when calling `createPeeringConnection`. The only change is that one of the VPCs are created in another stack with a different region. To establish cross region VPC peering connection, acceptorVpc needs to be imported to the requestor VPC stack using `fromVpcV2Attributes` method. ```ts const app = new App(); const stackA = new Stack(app, 'VpcStackA', { env: { account: '000000000000', region: 'us-east-1' } }); -const stackB = new Stack(app, 'VpcStackB', { env: { account: '111111111111', region: 'us-west-2' } }); +const stackB = new Stack(app, 'VpcStackB', { env: { account: '000000000000', region: 'us-west-2' } }); const vpcA = new VpcV2(stackA, 'VpcA', { primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/16'), @@ -280,7 +280,7 @@ const vpcB = VpcV2.fromVpcV2Attributes(stackA, 'ImportedVpcB', { vpcId: 'MockVpcBid', vpcCidrBlock: '10.1.0.0/16', region: 'us-west-2', - ownerAccountId: '111111111111', + ownerAccountId: '000000000000', }); @@ -302,7 +302,7 @@ const acceptorVpc = new VpcV2(this, 'VpcA', { primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/16'), }); -const acceptorRoleArn = acceptorVpc.createAcceptorVpcRole('000000000000') // Requestor account ID +const acceptorRoleArn = acceptorVpc.createAcceptorVpcRole('000000000000'); // Requestor account ID ``` After creating an IAM role in the acceptor account, we can initiate the peering connection request from the requestor VPC. Import accpeptorVpc to the stack using `fromVpcV2Attributes` method, it is recommended to specify owner account id of the acceptor VPC in case of cross account peering connection, if acceptor VPC is hosted in different region provide region value for import as well.