Peer with a VPC in another AWS account
You can peer with a Virtual Private Cloud (VPC) in another AWS account by using AWS::EC2::VPCPeeringConnection. This creates a networking connection between two VPCs that enables you to route traffic between them so they can communicate as if they were within the same network. A VPC peering connection can help facilitate data access and data transfer.
To establish a VPC peering connection, you need to authorize two separate AWS accounts within a single CloudFormation stack.
For more information about VPC peering and its limitations, see the Amazon VPC Peering Guide.
Prerequisites
-
You need a peer VPC ID, a peer AWS account ID, and a cross-account access role for the peering connection.
Note
This walkthrough refers to two accounts: First is an account that allows cross-account peering (the accepter account). Second is an account that requests the peering connection (the requester account).
-
To accept the VPC peering connection, the cross-account access role must be assumable by you. The resource behaves the same way as a VPC peering connection resource in the same account. For information about how an IAM administrator grants permissions to assume the cross-account role, see Granting a user permissions to switch roles IAM User Guide.
Step 1: Create a VPC and a cross-account role
Create a VPC and a cross-account access role (example)
In this step, you'll create the VPC and role in the accepter account.
-
In the AWS Management Console, choose AWS CloudFormation.
-
Choose Create stack.
-
You have several options. To use AWS CloudFormation Designer to create a new, blank template, choose Create template in Designer.
If you are creating the template in another text editor, choose Template is ready and then Amazon S3 URL or Upload a template file, as appropriate.
-
Use the following example template to create the VPC and the cross-account role allowing another account to achieve peering.
Example JSON
{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "Create a VPC and an assumable role for cross account VPC peering.", "Parameters": { "PeerRequesterAccountId": { "Type": "String" } }, "Resources": { "vpc": { "Type": "AWS::EC2::VPC", "Properties": { "CidrBlock": "10.1.0.0/16", "EnableDnsSupport": false, "EnableDnsHostnames": false, "InstanceTenancy": "default" } }, "peerRole": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Statement": [ { "Principal": { "AWS": { "Ref": "PeerRequesterAccountId" } }, "Action": [ "sts:AssumeRole" ], "Effect": "Allow" } ] }, "Path": "/", "Policies": [ { "PolicyName": "root", "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "ec2:AcceptVpcPeeringConnection", "Resource": "*" } ] } } ] } } }, "Outputs": { "VPCId": { "Value": { "Ref": "vpc" } }, "RoleARN": { "Value": { "Fn::GetAtt": [ "peerRole", "Arn" ] } } } }
Example YAML
AWSTemplateFormatVersion: 2010-09-09 Description: Create a VPC and an assumable role for cross account VPC peering. Parameters: PeerRequesterAccountId: Type: String Resources: vpc: Type: 'AWS::EC2::VPC' Properties: CidrBlock: 10.1.0.0/16 EnableDnsSupport: false EnableDnsHostnames: false InstanceTenancy: default peerRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Statement: - Principal: AWS: !Ref PeerRequesterAccountId Action: - 'sts:AssumeRole' Effect: Allow Path: / Policies: - PolicyName: root PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: 'ec2:AcceptVpcPeeringConnection' Resource: '*' Outputs: VPCId: Value: !Ref vpc RoleARN: Value: !GetAtt - peerRole - Arn
-
Choose Next.
-
Give the stack a name (for example,
VPC-owner
), and then enter the AWS account ID of the requester account in the PeerRequesterAccountId field. -
Accept the defaults, and then choose Next.
-
Choose I acknowledge that AWS CloudFormation might create IAM resources, and then choose Create stack.
Step 2: Create a
template that includes AWS::EC2::VPCPeeringConnection
Now that you've created the VPC and cross-account role, you can peer with the VPC using another AWS account (the requester account).
To create a template that includes the AWS::EC2::VPCPeeringConnection resource (example)
-
Go back to the AWS CloudFormation console home page.
-
Choose Create stack.
-
Choose Create template in Designer to use AWS CloudFormation Designer to create a new, blank template.
If you are creating the template in another text editor, choose Template is ready and then Amazon S3 URL or Upload a template file, as appropriate.
-
Use the following example template to create a VPC and a VPC peering connection using the peer role you created in Step 1.
Example JSON
{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "Create a VPC and a VPC Peering connection using the PeerRole to accept.", "Parameters": { "PeerVPCAccountId": { "Type": "String" }, "PeerVPCId": { "Type": "String" }, "PeerRoleArn": { "Type": "String" } }, "Resources": { "vpc": { "Type": "AWS::EC2::VPC", "Properties": { "CidrBlock": "10.2.0.0/16", "EnableDnsSupport": false, "EnableDnsHostnames": false, "InstanceTenancy": "default" } }, "vpcPeeringConnection": { "Type": "AWS::EC2::VPCPeeringConnection", "Properties": { "VpcId": { "Ref": "vpc" }, "PeerVpcId": { "Ref": "PeerVPCId" }, "PeerOwnerId": { "Ref": "PeerVPCAccountId" }, "PeerRoleArn": { "Ref": "PeerRoleArn" } } } }, "Outputs": { "VPCId": { "Value": { "Ref": "vpc" } }, "VPCPeeringConnectionId": { "Value": { "Ref": "vpcPeeringConnection" } } } }
Example YAML
AWSTemplateFormatVersion: 2010-09-09 Description: Create a VPC and a VPC Peering connection using the PeerRole to accept. Parameters: PeerVPCAccountId: Type: String PeerVPCId: Type: String PeerRoleArn: Type: String Resources: vpc: Type: 'AWS::EC2::VPC' Properties: CidrBlock: 10.2.0.0/16 EnableDnsSupport: false EnableDnsHostnames: false InstanceTenancy: default vpcPeeringConnection: Type: 'AWS::EC2::VPCPeeringConnection' Properties: VpcId: !Ref vpc PeerVpcId: !Ref PeerVPCId PeerOwnerId: !Ref PeerVPCAccountId PeerRoleArn: !Ref PeerRoleArn Outputs: VPCId: Value: !Ref vpc VPCPeeringConnectionId: Value: !Ref vpcPeeringConnection
-
Choose Next.
-
Give the stack a name (for example,
VPC-peering-connection
). -
Accept the defaults, and then choose Next.
-
Choose I acknowledge that AWS CloudFormation might create IAM resources, and then choose Create stack.
Creating a template with a highly restrictive policy
You might want to create a highly restrictive policy for peering your VPC with another AWS account.
The following example template shows how to change the VPC peer owner template (the accepter account created in Step 1 above) so that it's more restrictive.
Example JSON
{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "Create a VPC and an assumable role for cross account VPC peering.", "Parameters": { "PeerRequesterAccountId": { "Type": "String" } }, "Resources": { "peerRole": { "Properties": { "AssumeRolePolicyDocument": { "Statement": [ { "Action": [ "sts:AssumeRole" ], "Effect": "Allow", "Principal": { "AWS": { "Ref": "PeerRequesterAccountId" } } } ] }, "Path": "/", "Policies": [ { "PolicyDocument": { "Statement": [ { "Action": "ec2:acceptVpcPeeringConnection", "Effect": "Allow", "Resource": { "Fn::Sub": "arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:vpc/${vpc}" } }, { "Action": "ec2:acceptVpcPeeringConnection", "Condition": { "StringEquals": { "ec2:AccepterVpc": { "Fn::Sub": "arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:vpc/${vpc}" } } }, "Effect": "Allow", "Resource": { "Fn::Sub": "arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:vpc-peering-connection/*" } } ], "Version": "2012-10-17" }, "PolicyName": "root" } ] }, "Type": "AWS::IAM::Role" }, "vpc": { "Properties": { "CidrBlock": "10.1.0.0/16", "EnableDnsHostnames": false, "EnableDnsSupport": false, "InstanceTenancy": "default" }, "Type": "AWS::EC2::VPC" } }, "Outputs": { "RoleARN": { "Value": { "Fn::GetAtt": [ "peerRole", "Arn" ] } }, "VPCId": { "Value": { "Ref": "vpc" } } } }
Example YAML
AWSTemplateFormatVersion: 2010-09-09 Description: Create a VPC and an assumable role for cross account VPC peering. Parameters: PeerRequesterAccountId: Type: String Resources: peerRole: Properties: AssumeRolePolicyDocument: Statement: - Action: - 'sts:AssumeRole' Effect: Allow Principal: AWS: Ref: PeerRequesterAccountId Path: / Policies: - PolicyDocument: Statement: - Action: 'ec2:acceptVpcPeeringConnection' Effect: Allow Resource: 'Fn::Sub': 'arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:vpc/${vpc}' - Action: 'ec2:acceptVpcPeeringConnection' Condition: StringEquals: 'ec2:AccepterVpc': 'Fn::Sub': 'arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:vpc/${vpc}' Effect: Allow Resource: 'Fn::Sub': >- arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:vpc-peering-connection/* Version: 2012-10-17 PolicyName: root Type: 'AWS::IAM::Role' vpc: Properties: CidrBlock: 10.1.0.0/16 EnableDnsHostnames: false EnableDnsSupport: false InstanceTenancy: default Type: 'AWS::EC2::VPC' Outputs: RoleARN: Value: 'Fn::GetAtt': - peerRole - Arn VPCId: Value: Ref: vpc
To access the VPC, you can use the same requester template as in Step 2 above.