Skip to content

Instantly share code, notes, and snippets.

@efi-mk
Last active January 13, 2023 14:52
Show Gist options
  • Save efi-mk/d6586669a472be8ea16b6cf8e9c6ba7f to your computer and use it in GitHub Desktop.
Save efi-mk/d6586669a472be8ea16b6cf8e9c6ba7f to your computer and use it in GitHub Desktop.
A cloud formation script to create a vpc with 2 private subnets and 1 public subnet
AWSTemplateFormatVersion: 2010-09-09
Description: My Network Environment
Resources:
# VPC containing 3 subnets, 1 is public, while the other 2 are private for RDS
MyVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsSupport: 'true'
EnableDnsHostnames: 'true'
InstanceTenancy: 'default'
Tags:
- Key: Name
Value: my-vpc
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
CidrBlock: 10.0.1.0/24
AvailabilityZone: !Select [ 0, !GetAZs ]
Tags:
- Key: Name
Value: my-public-subnet1
PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
CidrBlock: 10.0.2.0/24
AvailabilityZone: !Select [ 0, !GetAZs ]
Tags:
- Key: Name
Value: my-private-subnet1
PrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
CidrBlock: 10.0.3.0/24
AvailabilityZone: !Select [ 1, !GetAZs ]
Tags:
- Key: Name
Value: my-private-subnet2
# Setup connectivity by creating an internet GW + NAT
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: my-igw
AttachGateway:
Type: "AWS::EC2::VPCGatewayAttachment"
Properties:
InternetGatewayId: !Ref InternetGateway
VpcId: !Ref MyVPC
ElasticIP:
Type: AWS::EC2::EIP
Properties:
Domain: vpc
NatGateway:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt ElasticIP.AllocationId
SubnetId: !Ref PublicSubnet1
# Create private routing table that connects the private subnets to the NAT
PrivateRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref MyVPC
Tags:
- Key: Name
Value: rt-to-nat"
DefaultPrivateRoute:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NatGateway
Private1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PrivateRouteTable
SubnetId: !Ref PrivateSubnet1
Private2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PrivateRouteTable
SubnetId: !Ref PrivateSubnet2
# Create a public routing table that connects the public subnet to the IGW
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref MyVPC
Tags:
- Key: Name
Value: rt-to-igw
DefaultPublicRoute:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
Public1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PublicRouteTable
SubnetId: !Ref PublicSubnet1
ProfileServiceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: profile-service-sg
GroupDescription: Allow https to client host
VpcId: !Ref MyVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '443'
ToPort: '443'
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: '5432'
ToPort: '5432'
CidrIp: 0.0.0.0/0
Tags:
- Key: Name
Value: Profile service security group
Outputs:
PrivateSubnet1:
Description: Private Subnet ID 1
Value: !Ref PrivateSubnet1
PrivateSubnet2:
Description: Private Subnet ID 2
Value: !Ref PrivateSubnet2
SecurityGroup:
Description: Security group for the lambda service
Value: !Ref ProfileServiceSecurityGroup
@laboro18
Copy link

laboro18 commented Jul 17, 2018

Hi @efi-mk,

Thanks for sharing the gist. I'm still trying to understand the typical setup for a VPC, especially in the context of the serverless framework.

  1. Are these yaml codes a part of your serverless.yml or a CloudFormation thing?
    I would think that these config need only be setup once right?

  2. Why 2 private subnets and 1 public subnet?
    My guess is that the 1 public subnet is for the internet gateway, and that you made individual private subnets for each resource you intend to have. Something about maximum availability?

@efi-mk
Copy link
Author

efi-mk commented Jul 18, 2018

  1. These configuration are a single CloudFormation template file. You are right, need to set them up only once when creating the environment.
  2. To be honest, I don't remember, I think it's related somehow to high availability of the subnets, but maybe I'm just talking nonsense.

I'm attaching an image on how it's suppose to look like at the end
network_architecture

@haywiremk
Copy link

So before I dug in and properly learned VPC/subnets for AWS this diagram and all examples were confusing from a generic network standpoint. The public and private moniker I assumed backwards to be the desired need vs use need. This diagram omits the VPC router that lives between subnets in the VPC. The VPC router will connect all subnets in the VPC together automatically using (local). A public subnet means the default route is to the Internet gateway (ig). To get out you need a public IP address assigned to an object(elastic or dynamic). The NAT in the public subnet has an elastic ip attached and therefore default routes out of this subnet from the nat will goto the internet gateway. The private subnet default route is set to be the nat gateway (nat). So non-VPC(local) destinations will go through the VPC router connecting the subnets and send the packets to the nat in the public subnet to be translated to the public elastic IP to then route back to the VPC router and out the ig. If you don't understand the VPC router the diagram and cloudformation template is head scratcher. Also this diagram should have the ig on the VPC boundry if you are trying to access the S3 bucket(SNS notifications do not come from external internet). I was trying to get RDS and S3 access from the same lambda invocation. Hopefully this helps others who land here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment