使用serverless framework設定EC2的VPC、Subnet和對外連線

Judy Huang
Judy’s aws sharing
13 min readApr 7, 2024

在前面使用serverless framework建置AWS EC2這篇文章的cloudformation去產生的EC2,assign的VPC和subnet是預先產生的。

假如想再產生EC2的時候,也一起產生network的相關設定,一樣也可以透過serverless產生,只要撰寫VPC、subnet、Internet Gateway、route、route table和Security Group的config,就可以設定好EC2的網路。

Example diagram from AWS docs

如果部署的resource需要透過network互相溝通,並且需要跟其他不相關resource的網路做隔離,可以透過VPC(Virtual Private Cloud)建立一個虛擬隔離網路,並設定這個VPC底下的ip範圍和可以擁有多少ip,就可以有一個獨立的網路。

resources:
Resources:
MyVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
Tags:
- Key: Name
Value: MyVPC

Reference:

建立好VPC之後,可再切分子網段。如果整個系統非常龐大,request量也很大,可以透過subnet更好的切分每個部分分配到的ip範圍,這樣可以讓request更快速的找到目的地,減少網路傳輸時間,就像是房子的郵遞區號,讓郵差可以更快的分送信件。

Subnet example diagram from AWS docs

需要特別注意的是,MapPublicIpOnLaunch這個欄位需要設為true,才能夠有一組對外的ip,這樣才能接收外部網路的request,也才能ssh進去EC2或透過其他port存取這個resource。

resources:
Resources:
EC2Subnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
CidrBlock: 10.0.0.0/24
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: MySubnet

Reference:

如果說subnet是郵遞區號,那Router就像一間郵局,記錄每個郵遞區號應該要送往哪一區,將信件快速分類,避免信件送錯地方或迷路。Router需要設定Route Table和Route,指定每個Destination的Target,這樣才能讓request送到指定的目標。這邊要注意的是,如果resource有對外部網路連線的需求(ex: ssh),需要有Route Table指到Internet Gateway,封包才能夠送的出去,外部網路也才可以連到這個VPC底下的resource。

Router example diagram from AWS docs

serverless的部分,除了設定Route和RouteTable,還需要設定SubnetRouteTableAssociation,指定subnet參考的RouteTable,就像每個地址都有隸屬的郵局,這樣才能知道要在哪裡收信和寄信!

resources:
Resources:
MyPublicRoute:
Type: AWS::EC2::Route
DependsOn: InternetGatewayAttachment
Properties:
RouteTableId: !Ref MyPublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref MyInternetGateway

MyPublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref MyVPC

MySubnetRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId:
Ref: EC2Subnet
RouteTableId:
Ref: MyPublicRouteTable

Reference:

為了能夠讓外面的網路可以透過ssh連線到EC2或其他resource,還需要Internet Gateway當作Route這座郵局的對外窗口,才能夠順利地跟別人連線。

Internet Gateway example diagram from AWS docs

另外還需要InternetGatewayAttachment,指定Internet Gateway為哪個VPC服務,才能夠準確地把request導到指定的VPC底下。

resources:
Resources:
MyInternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: stack
Value: dev

InternetGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref MyInternetGateway
VpcId: !Ref MyVPC

Reference:

最後還需要Security Group,限制有哪些request可以進入VPC,哪些可以出去,可以用protocol、port和ip範圍去做限制。

resources:
Resources:
EC2SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !Ref MyVPC
GroupDescription: Allow SSH and HTTP traffic
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0

Reference:

完整範例

service: my-ec2-service
provider:
name: aws
region: us-east-1
resources:
Resources:
MyVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
Tags:
- Key: Name
Value: MyVPC
MyInternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: stack
Value: dev
InternetGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref MyInternetGateway
VpcId: !Ref MyVPC
MyPublicRoute:
Type: AWS::EC2::Route
DependsOn: InternetGatewayAttachment
Properties:
RouteTableId: !Ref MyPublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref MyInternetGateway
MyPublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref MyVPC
MySubnetRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId:
Ref: EC2Subnet
RouteTableId:
Ref: MyPublicRouteTable
EC2SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !Ref MyVPC
GroupDescription: Allow SSH and HTTP traffic
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
EC2Subnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
CidrBlock: 10.0.0.0/24
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: MySubnet
EC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-0885b1f6bd170450c
KeyName: test-blue-green
InstanceType: t2.micro
SubnetId: !Ref EC2Subnet
SecurityGroupIds:
- !GetAtt EC2SecurityGroup.GroupId

完整範例部署到aws後,長出來的網路會像下面這張圖,有線連在一起的部分,代表這兩個resource有association,可以在VPC的Resource map找到這些關聯,確認serverless的yaml檔是不是有寫錯設定。

Reference:

--

--