-
Notifications
You must be signed in to change notification settings - Fork 4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ec2): L2 Construct - VpcPeeringConnection
fixes #9338
- Loading branch information
1 parent
3cad6a3
commit c9c3808
Showing
4 changed files
with
259 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
132 changes: 132 additions & 0 deletions
132
packages/@aws-cdk/aws-ec2/lib/vpc-peering-connection.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
import * as iam from '@aws-cdk/aws-iam'; | ||
import * as cdk from '@aws-cdk/core'; | ||
import { CfnVPCPeeringConnection } from './ec2.generated'; | ||
import { IVpc } from './vpc'; | ||
|
||
/** | ||
* VPC with which you are creating the VPC peering connection. | ||
*/ | ||
export class PeerVpc { | ||
constructor( | ||
/** | ||
* The ID of the VPC with which you are creating the VPC peering connection | ||
*/ | ||
public readonly vpcId: string, | ||
|
||
/** | ||
* The Region code for the accepter VPC | ||
* | ||
* @default - The Region in which you make the request | ||
*/ | ||
public readonly region?: string, | ||
|
||
/** | ||
* The AWS account ID of the owner of the accepter VPC | ||
* | ||
* @default - Your AWS account ID | ||
*/ | ||
public readonly account?: string, | ||
) {} | ||
} | ||
|
||
/** | ||
* Options for constructing VpcPeeringConnection | ||
*/ | ||
export interface VpcPeeringConnectionOptions { | ||
/** | ||
* The name of VPC peering connections | ||
* | ||
* @default - generated by CloudFormation | ||
*/ | ||
readonly vpcPeeringConnectionName?: string | ||
|
||
/** | ||
* VPC with which you are creating the VPC peering connection. | ||
*/ | ||
readonly peerVpc: PeerVpc | ||
|
||
/** | ||
* The role, which is required when you are peering a VPC in a different AWS account. | ||
* | ||
* @default - conditional | ||
*/ | ||
readonly role?: iam.IRole | ||
} | ||
|
||
/** | ||
* Props for constructing VpcPeeringConnection | ||
*/ | ||
export interface VpcPeeringConnectionProps extends VpcPeeringConnectionOptions { | ||
/** | ||
* The requester VPC that you own | ||
*/ | ||
readonly vpc: IVpc | ||
} | ||
|
||
/** | ||
* VPC peering connection between two VPC | ||
*/ | ||
export interface IVpcPeeringConnection extends cdk.IResource { | ||
/** | ||
* The ID of the VPC peering connection. | ||
* | ||
* @attribute | ||
*/ | ||
readonly vpcPeeringConnectionId: string | ||
} | ||
|
||
/** | ||
* Attributes of VPC peering connection | ||
*/ | ||
export interface VpcPeeringConnectionAttributes { | ||
/** | ||
* The ID of the VPC peering connection. | ||
*/ | ||
readonly vpcPeeringConnectionId: string | ||
} | ||
|
||
/** | ||
* VPC peering connection between two VPC | ||
*/ | ||
export class VpcPeeringConnection extends cdk.Resource implements IVpcPeeringConnection { | ||
/** | ||
* Import a VPC peering connection from attributes | ||
*/ | ||
public static fromVpcPeeringConnectionAttributes(scope: cdk.Construct, id: string, attrs: VpcPeeringConnectionAttributes): IVpcPeeringConnection { | ||
class Import extends cdk.Resource implements IVpcPeeringConnection { | ||
public readonly vpcPeeringConnectionId: string = attrs.vpcPeeringConnectionId | ||
} | ||
return new Import(scope, id); | ||
} | ||
|
||
/** | ||
* The ID of the VPC peering connection. | ||
* | ||
* @attribute | ||
*/ | ||
public readonly vpcPeeringConnectionId: string | ||
|
||
constructor(scope: cdk.Construct, id: string, props: VpcPeeringConnectionProps) { | ||
super(scope, id); | ||
|
||
if (props.peerVpc?.account && !props.role) { | ||
throw new Error('The role is required when you are peering a VPC in a different AWS account.'); | ||
} | ||
|
||
const tags: cdk.CfnTag[] = []; | ||
if (props.vpcPeeringConnectionName) { | ||
tags.push({ key: 'Name', value: props.vpcPeeringConnectionName }); | ||
} | ||
|
||
const resource = new CfnVPCPeeringConnection(this, 'Resource', { | ||
vpcId: props.vpc.vpcId, | ||
peerVpcId: props.peerVpc.vpcId, | ||
peerRegion: props.peerVpc.region || this.stack.region, | ||
peerOwnerId: props.peerVpc.account || this.stack.account, | ||
peerRoleArn: props.role?.roleArn, | ||
tags, | ||
}); | ||
|
||
this.vpcPeeringConnectionId = resource.ref; | ||
} | ||
} |
113 changes: 113 additions & 0 deletions
113
packages/@aws-cdk/aws-ec2/test/vpc-peering-connection.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
import { ABSENT } from '@aws-cdk/assert'; | ||
import '@aws-cdk/assert/jest'; | ||
import * as iam from '@aws-cdk/aws-iam'; | ||
import * as cdk from '@aws-cdk/core'; | ||
import * as ec2 from '../lib'; | ||
|
||
describe('Normal', () => { | ||
describe('Account x Region', () => { | ||
test('Peer vpc in my account & the same region', () => { | ||
const stack = new cdk.Stack(); | ||
const vpc = ec2.Vpc.fromVpcAttributes(stack, 'vpc', { vpcId: 'vpc-01234567890123456', availabilityZones: ['ap-northeast-1a'] }); | ||
const peerVpc = new ec2.PeerVpc('vpc-09876543210987654'); | ||
new ec2.VpcPeeringConnection(stack, 'peering', { vpc, peerVpc }); | ||
|
||
expect(stack).toHaveResource('AWS::EC2::VPCPeeringConnection', { | ||
VpcId: vpc.vpcId, | ||
PeerOwnerId: { | ||
Ref: 'AWS::AccountId', | ||
}, | ||
PeerRegion: { | ||
Ref: 'AWS::Region', | ||
}, | ||
PeerRoleArn: ABSENT, | ||
}); | ||
}); | ||
|
||
test('Peer vpc in my account & the different region', () => { | ||
const stack = new cdk.Stack(); | ||
const vpc = ec2.Vpc.fromVpcAttributes(stack, 'vpc', { vpcId: 'vpc-01234567890123456', availabilityZones: ['ap-northeast-1a'] }); | ||
const peerVpc = new ec2.PeerVpc('vpc-09876543210987654', 'ap-southeast-1'); | ||
new ec2.VpcPeeringConnection(stack, 'peering', { vpc, peerVpc }); | ||
|
||
expect(stack).toHaveResource('AWS::EC2::VPCPeeringConnection', { | ||
VpcId: vpc.vpcId, | ||
PeerOwnerId: { | ||
Ref: 'AWS::AccountId', | ||
}, | ||
PeerRegion: peerVpc.region, | ||
PeerRoleArn: ABSENT, | ||
}); | ||
}); | ||
|
||
test('Peer vpc in another account & the different region', () => { | ||
const stack = new cdk.Stack(); | ||
const vpc = ec2.Vpc.fromVpcAttributes(stack, 'vpc', { vpcId: 'vpc-01234567890123456', availabilityZones: ['ap-northeast-1a'] }); | ||
const peerVpc = new ec2.PeerVpc('vpc-09876543210987654', 'ap-southeast-1', '123456789012'); | ||
const role = iam.Role.fromRoleArn(stack, 'role', `arn:aws:iam:${peerVpc.account}:${peerVpc.region}:role/role-for-vpc-peering-connection`); | ||
new ec2.VpcPeeringConnection(stack, 'peering', { vpc, peerVpc, role }); | ||
|
||
expect(stack).toHaveResource('AWS::EC2::VPCPeeringConnection', { | ||
VpcId: vpc.vpcId, | ||
PeerOwnerId: peerVpc.account, | ||
PeerRegion: peerVpc.region, | ||
PeerRoleArn: role.roleArn, | ||
}); | ||
}); | ||
|
||
test('Peer vpc in another account & the same region', () => { | ||
const stack = new cdk.Stack(); | ||
const vpc = ec2.Vpc.fromVpcAttributes(stack, 'vpc', { vpcId: 'vpc-01234567890123456', availabilityZones: ['ap-northeast-1a'] }); | ||
const peerVpc = new ec2.PeerVpc('vpc-09876543210987654', undefined, '123456789012'); | ||
const role = iam.Role.fromRoleArn(stack, 'role', `arn:aws:iam:${peerVpc.account}:${peerVpc.region}:role/role-for-vpc-peering-connection`); | ||
new ec2.VpcPeeringConnection(stack, 'peering', { vpc, peerVpc, role }); | ||
|
||
expect(stack).toHaveResource('AWS::EC2::VPCPeeringConnection', { | ||
VpcId: vpc.vpcId, | ||
PeerOwnerId: peerVpc.account, | ||
PeerRegion: { | ||
Ref: 'AWS::Region', | ||
}, | ||
PeerRoleArn: role.roleArn, | ||
}); | ||
}); | ||
}); | ||
|
||
describe('Name', () => { | ||
test('With name', () => { | ||
const stack = new cdk.Stack(); | ||
const vpc = ec2.Vpc.fromVpcAttributes(stack, 'vpc', { vpcId: 'vpc-01234567890123456', availabilityZones: ['ap-northeast-1a'] }); | ||
const peerVpc = new ec2.PeerVpc('vpc-09876543210987654'); | ||
const vpcPeeringConnectionName = 'VpcPeeringConnection'; | ||
new ec2.VpcPeeringConnection(stack, 'peering', { vpc, peerVpc, vpcPeeringConnectionName }); | ||
|
||
expect(stack).toHaveResource('AWS::EC2::VPCPeeringConnection', { | ||
Tags: [{ Key: 'Name', Value: vpcPeeringConnectionName }], | ||
}); | ||
}); | ||
|
||
test('Without name', () => { | ||
const stack = new cdk.Stack(); | ||
const vpc = ec2.Vpc.fromVpcAttributes(stack, 'vpc', { vpcId: 'vpc-01234567890123456', availabilityZones: ['ap-northeast-1a'] }); | ||
const peerVpc = new ec2.PeerVpc('vpc-09876543210987654'); | ||
new ec2.VpcPeeringConnection(stack, 'peering', { vpc, peerVpc }); | ||
|
||
expect(stack).toHaveResource('AWS::EC2::VPCPeeringConnection', { | ||
Tags: ABSENT, | ||
}); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('Error', () => { | ||
test('The role is required when you are peering a VPC in a different AWS account.', () => { | ||
const stack = new cdk.Stack(); | ||
const vpc = ec2.Vpc.fromVpcAttributes(stack, 'vpc', { vpcId: 'vpc-01234567890123456', availabilityZones: ['ap-northeast-1a'] }); | ||
expect(() => { | ||
new ec2.VpcPeeringConnection(stack, 'peering', { | ||
vpc, | ||
peerVpc: new ec2.PeerVpc('vpc-09876543210987654', 'ap-northeast-2', '012345678901'), | ||
}); | ||
}).toThrowError('The role is required when you are peering a VPC in a different AWS account.'); | ||
}); | ||
}); |