Last active
June 10, 2020 15:04
-
-
Save cb372/fc36a0d1db54f495988a507d5ec8a51c to your computer and use it in GitHub Desktop.
CloudFormation for setting up a VPC
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
AWSTemplateFormatVersion: 2010-09-09 | |
Description: > | |
Creates a cross-account role that your AWS account can assume | |
in order to accept a VPC peering connection in the other account. | |
This is pretty confusing, so to clarify, | |
1. Run this CloudFormation in the OTHER account to create the cross-account role. | |
2. Your account requests a peering connection with the other account. | |
3. Your account assumes the role in order to access the other account | |
and accept the peering connection. | |
Parameters: | |
PeerRequesterAccountId: | |
Type: String | |
Resources: | |
AcceptVpcPeeringRole: | |
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: '*' |
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
--- | |
AWSTemplateFormatVersion: 2010-09-09 | |
Description: | | |
VPC with 3 public and 3 private subnets, | |
and a VPN connection to a corporate network, | |
and a peering to a VPC in another account. | |
Parameters: | |
PeeredVpcId: | |
Type: String | |
Description: The VPC ID of the VPC in another AWS account that you want to peer with | |
PeeredVpcAccountId: | |
Type: String | |
Description: The AWS account ID of the account containing the VPC you want to peer with | |
PeeredVpcCrossAccountRoleName: | |
Type: String | |
Description: The name of the cross-account role in the other AWS account that CloudFormation will assume in order to accept the peering connection | |
Mappings: | |
CidrBlocks: | |
MyAccount: | |
# TODO: Tweak these IP ranges as necessary | |
VPC: 10.128.0.0/19 | |
PublicSubnet1: 10.128.0.0/22 | |
PublicSubnet2: 10.128.4.0/22 | |
PublicSubnet3: 10.128.8.0/22 | |
PrivateSubnet1: 10.128.12.0/22 | |
PrivateSubnet2: 10.128.16.0/22 | |
PrivateSubnet3: 10.131.20.0/22 | |
CorporateNetwork: 10.0.0.0/9 | |
IPAddresses: | |
CorporateNetwork: | |
# TODO: your networks team will be able to tell you this | |
CustomerGateway: 1.2.3.4 | |
Resources: | |
VPC: | |
Type: AWS::EC2::VPC | |
Properties: | |
EnableDnsSupport: true | |
EnableDnsHostnames: true | |
CidrBlock: !FindInMap [ CidrBlocks, MyAccount, VPC ] | |
Tags: | |
- Key: Name | |
Value: My VPC | |
InternetGateway: | |
Type: AWS::EC2::InternetGateway | |
AttachInternetGatewayToVPC: | |
Type: AWS::EC2::VPCGatewayAttachment | |
Properties: | |
VpcId: !Ref VPC | |
InternetGatewayId: !Ref InternetGateway | |
# | |
# Public subnets | |
# | |
PublicSubnet1: | |
Type: AWS::EC2::Subnet | |
Properties: | |
VpcId: !Ref VPC | |
CidrBlock: !FindInMap [ CidrBlocks, MyAccount, PublicSubnet1 ] | |
MapPublicIpOnLaunch: true | |
AvailabilityZone: !Sub "${AWS::Region}a" | |
Tags: | |
- Key: Name | |
Value: Public1 | |
PublicSubnet2: | |
Type: AWS::EC2::Subnet | |
Properties: | |
VpcId: !Ref VPC | |
CidrBlock: !FindInMap [ CidrBlocks, MyAccount, PublicSubnet2 ] | |
MapPublicIpOnLaunch: true | |
AvailabilityZone: !Sub "${AWS::Region}b" | |
Tags: | |
- Key: Name | |
Value: Public2 | |
PublicSubnet3: | |
Type: AWS::EC2::Subnet | |
Properties: | |
VpcId: !Ref VPC | |
CidrBlock: !FindInMap [ CidrBlocks, MyAccount, PublicSubnet3 ] | |
MapPublicIpOnLaunch: true | |
AvailabilityZone: !Sub "${AWS::Region}c" | |
Tags: | |
- Key: Name | |
Value: Public3 | |
# | |
# Routing for public subnets | |
# | |
PublicRouteTable: | |
Type: AWS::EC2::RouteTable | |
Properties: | |
VpcId: !Ref VPC | |
Tags: | |
- Key: Name | |
Value: PublicRouteTable | |
PublicInternetRoute: | |
Type: AWS::EC2::Route | |
DependsOn: AttachInternetGatewayToVPC | |
Properties: | |
RouteTableId: !Ref PublicRouteTable | |
DestinationCidrBlock: 0.0.0.0/0 | |
GatewayId: !Ref InternetGateway | |
PublicSubnet1RouteTableAssociation: | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
SubnetId: !Ref PublicSubnet1 | |
RouteTableId: !Ref PublicRouteTable | |
PublicSubnet2RouteTableAssociation: | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
SubnetId: !Ref PublicSubnet2 | |
RouteTableId: !Ref PublicRouteTable | |
PublicSubnet3RouteTableAssociation: | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
SubnetId: !Ref PublicSubnet3 | |
RouteTableId: !Ref PublicRouteTable | |
# | |
# Network ACL for public subnets | |
# | |
PublicNetworkAcl: | |
Type: AWS::EC2::NetworkAcl | |
Properties: | |
VpcId: !Ref VPC | |
Tags: | |
- Key: Name | |
Value: PublicNetworkAcl | |
# Allow requests from the outside world to HTTPS services inside the VPC | |
InboundHTTPSPublicNetworkAclEntry: | |
Type: AWS::EC2::NetworkAclEntry | |
Properties: | |
NetworkAclId: !Ref PublicNetworkAcl | |
RuleNumber: 100 | |
Protocol: 6 | |
RuleAction: allow | |
Egress: false | |
CidrBlock: 0.0.0.0/0 | |
PortRange: | |
From: 443 | |
To: 443 | |
# Allow TCP responses from the outside world on ephemeral ports | |
InboundEphemeralTcpPublicNetworkAclEntry: | |
Type: AWS::EC2::NetworkAclEntry | |
Properties: | |
NetworkAclId: !Ref PublicNetworkAcl | |
RuleNumber: 101 | |
Protocol: 6 | |
RuleAction: allow | |
Egress: false | |
CidrBlock: 0.0.0.0/0 | |
PortRange: | |
From: 1024 | |
To: 65535 | |
# Allow services inside the VPC to make TCP requests to the outside world | |
# and make TCP responses on ephemeral ports | |
OutboundTcpPublicNetworkAclEntry: | |
Type: AWS::EC2::NetworkAclEntry | |
Properties: | |
NetworkAclId: !Ref PublicNetworkAcl | |
RuleNumber: 100 | |
Protocol: 6 | |
RuleAction: allow | |
Egress: true | |
CidrBlock: 0.0.0.0/0 | |
PortRange: | |
From: 0 | |
To: 65535 | |
PublicSubnet1NetworkAclAssociation: | |
Type: AWS::EC2::SubnetNetworkAclAssociation | |
Properties: | |
SubnetId: !Ref PublicSubnet1 | |
NetworkAclId: !Ref PublicNetworkAcl | |
PublicSubnet2NetworkAclAssociation: | |
Type: AWS::EC2::SubnetNetworkAclAssociation | |
Properties: | |
SubnetId: !Ref PublicSubnet2 | |
NetworkAclId: !Ref PublicNetworkAcl | |
PublicSubnet3NetworkAclAssociation: | |
Type: AWS::EC2::SubnetNetworkAclAssociation | |
Properties: | |
SubnetId: !Ref PublicSubnet3 | |
NetworkAclId: !Ref PublicNetworkAcl | |
# | |
# NAT gateway | |
# | |
NatGatewayElasticIP: | |
Type: AWS::EC2::EIP | |
DependsOn: AttachInternetGatewayToVPC | |
Properties: | |
Domain: vpc | |
# We have to put the NAT gateway in one of the AZs. | |
# We arbitrarily choose 'b'. | |
NatGateway: | |
Type: AWS::EC2::NatGateway | |
Properties: | |
AllocationId: !GetAtt NatGatewayElasticIP.AllocationId | |
SubnetId: !Ref PublicSubnet2 | |
Tags: | |
- Key: Name | |
Value: NatGateway | |
# | |
# Private subnets | |
# | |
PrivateSubnet1: | |
Type: AWS::EC2::Subnet | |
Properties: | |
VpcId: !Ref VPC | |
CidrBlock: !FindInMap [ CidrBlocks, MyAccount, PrivateSubnet1 ] | |
AvailabilityZone: !Sub "${AWS::Region}a" | |
Tags: | |
- Key: Name | |
Value: Private1 | |
PrivateSubnet2: | |
Type: AWS::EC2::Subnet | |
Properties: | |
VpcId: !Ref VPC | |
CidrBlock: !FindInMap [ CidrBlocks, MyAccount, PrivateSubnet2 ] | |
AvailabilityZone: !Sub "${AWS::Region}b" | |
Tags: | |
- Key: Name | |
Value: Private2 | |
PrivateSubnet3: | |
Type: AWS::EC2::Subnet | |
Properties: | |
VpcId: !Ref VPC | |
CidrBlock: !FindInMap [ CidrBlocks, MyAccount, PrivateSubnet3 ] | |
AvailabilityZone: !Sub "${AWS::Region}c" | |
Tags: | |
- Key: Name | |
Value: Private3 | |
# | |
# Routing for private subnets | |
# | |
PrivateRouteTable: | |
Type: AWS::EC2::RouteTable | |
Properties: | |
VpcId: !Ref VPC | |
Tags: | |
- Key: Name | |
Value: PrivateRouteTable | |
PrivateInternetRoute: | |
Type: AWS::EC2::Route | |
DependsOn: NatGateway | |
Properties: | |
RouteTableId: !Ref PrivateRouteTable | |
DestinationCidrBlock: 0.0.0.0/0 | |
NatGatewayId: !Ref NatGateway | |
PrivateSubnet1RouteTableAssociation: | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
SubnetId: !Ref PrivateSubnet1 | |
RouteTableId: !Ref PrivateRouteTable | |
PrivateSubnet2RouteTableAssociation: | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
SubnetId: !Ref PrivateSubnet2 | |
RouteTableId: !Ref PrivateRouteTable | |
PrivateSubnet3RouteTableAssociation: | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
SubnetId: !Ref PrivateSubnet3 | |
RouteTableId: !Ref PrivateRouteTable | |
# | |
# Network ACL for private subnets | |
# | |
PrivateNetworkAcl: | |
Type: AWS::EC2::NetworkAcl | |
Properties: | |
VpcId: !Ref VPC | |
Tags: | |
- Key: Name | |
Value: PrivateNetworkAcl | |
# Allow incoming traffic from anywhere in the VPC | |
InboundAllLocalTrafficPrivateNetworkAclEntry: | |
Type: AWS::EC2::NetworkAclEntry | |
Properties: | |
NetworkAclId: !Ref PrivateNetworkAcl | |
RuleNumber: 100 | |
Protocol: -1 | |
RuleAction: allow | |
Egress: false | |
CidrBlock: !FindInMap [ CidrBlocks, MyAccount, VPC ] | |
# Allow incoming TCP responses from anywhere | |
InboundEphemeralTcpPrivateNetworkAclEntry: | |
Type: AWS::EC2::NetworkAclEntry | |
Properties: | |
NetworkAclId: !Ref PrivateNetworkAcl | |
RuleNumber: 101 | |
Protocol: 6 | |
RuleAction: allow | |
Egress: false | |
CidrBlock: 0.0.0.0/0 | |
PortRange: | |
From: 1024 | |
To: 65535 | |
# Allow incoming SSH requests from corporate network | |
InboundEphemeralTcpPrivateNetworkAclEntry: | |
Type: AWS::EC2::NetworkAclEntry | |
Properties: | |
NetworkAclId: !Ref PrivateNetworkAcl | |
RuleNumber: 102 | |
Protocol: 6 | |
RuleAction: allow | |
Egress: false | |
CidrBlock: !FindInMap [ CidrBlocks, MyAccount, CorporateNetwork ] | |
PortRange: | |
From: 22 | |
To: 22 | |
# Allow outgoing TCP requests to anywhere | |
OutboundTcpPrivateNetworkAclEntry: | |
Type: AWS::EC2::NetworkAclEntry | |
Properties: | |
NetworkAclId: !Ref PrivateNetworkAcl | |
RuleNumber: 100 | |
Protocol: 6 | |
RuleAction: allow | |
Egress: true | |
CidrBlock: 0.0.0.0/0 | |
PortRange: | |
From: 0 | |
To: 65535 | |
PrivateSubnet1NetworkAclAssociation: | |
Type: AWS::EC2::SubnetNetworkAclAssociation | |
Properties: | |
SubnetId: !Ref PrivateSubnet1 | |
NetworkAclId: !Ref PrivateNetworkAcl | |
PrivateSubnet2NetworkAclAssociation: | |
Type: AWS::EC2::SubnetNetworkAclAssociation | |
Properties: | |
SubnetId: !Ref PrivateSubnet2 | |
NetworkAclId: !Ref PrivateNetworkAcl | |
PrivateSubnet3NetworkAclAssociation: | |
Type: AWS::EC2::SubnetNetworkAclAssociation | |
Properties: | |
SubnetId: !Ref PrivateSubnet3 | |
NetworkAclId: !Ref PrivateNetworkAcl | |
# The customer gateway is the endpoint on the corporate-network side of the VPN tunnel | |
CustomerGateway: | |
Type: AWS::EC2::CustomerGateway | |
Properties: | |
Type: ipsec.1 | |
BgpAsn: 65000 | |
IpAddress: !FindInMap [ IPAddresses, CorporateNetwork, CustomerGateway ] | |
Tags: | |
- Key: Name | |
Value: corporate network | |
# The virtual private gateway is the endpoint on the AWS side | |
VirtualPrivateGateway: | |
Type: AWS::EC2::VPNGateway | |
Properties: | |
Type: ipsec.1 | |
Tags: | |
- Key: Name | |
Value: corporate network | |
AttachVPNGatewayToVPC: | |
Type: AWS::EC2::VPCGatewayAttachment | |
DependsOn: VirtualPrivateGateway | |
Properties: | |
VpcId: !Ref VPC | |
VpnGatewayId: !Ref VirtualPrivateGateway | |
VPNGatewayRoutePropagation: | |
Type: AWS::EC2::VPNGatewayRoutePropagation | |
DependsOn: AttachVPNGatewayToVPC | |
Properties: | |
RouteTableIds: | |
- !Ref PrivateRouteTable | |
VpnGatewayId: !Ref VirtualPrivateGateway | |
VPNConnection: | |
Type: AWS::EC2::VPNConnection | |
Properties: | |
Type: ipsec.1 | |
CustomerGatewayId: !Ref CustomerGateway | |
VpnGatewayId: !Ref VirtualPrivateGateway | |
StaticRoutesOnly: true | |
Tags: | |
- Key: Name | |
Value: corporate network | |
VPNConnectionRoute: | |
Type: AWS::EC2::VPNConnectionRoute | |
Properties: | |
DestinationCidrBlock: !FindInMap [ CidrBlocks, MyAccount, CorporateNetwork ] | |
VpnConnectionId: !Ref VPNConnection | |
# Peer with a VPC in another AWS account | |
PeeringConnection: | |
Type: AWS::EC2::VPCPeeringConnection | |
Properties: | |
VpcId: !Ref VPC | |
PeerVpcId: !Ref PeeredVpcId | |
PeerOwnerId: !Ref PeeredVpcAccountId | |
PeerRoleArn: !Sub "arn:aws:iam::${PeeredVpcAccountId}:role/${PeeredVpcCrossAccountRoleName}" | |
Tags: | |
- Key: Name | |
Value: VPC in another AWS account | |
Outputs: | |
VPCCidrBlock: | |
Value: !GetAtt VPC.CidrBlock | |
Export: | |
Name: VPC-CIDR |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment