😎AWS 3 Tier架構建置(CloudFormation)-第二章:建立基本網路架構

haha1811
31 min readNov 4, 2023

--

😙 第二章新增Security Group、RDS、NAT及EC2..等雲端資源的建置。

🌳 AWS 3層架構文件

1. KeyPair

🤓 功能說明: KeyPair 是 AWS 中用於安全連接到虛擬機器 (EC2) 的密鑰對。它包括一個公開金鑰和一個私有金鑰。公開金鑰存儲在 EC2 實例上,而私有金鑰通常存儲在您的本地計算機上。通過在 EC2 啟動時關聯 KeyPair,您可以通過 SSH 或其他加密協議對 EC2 進行安全的遠程訪問。

  NewKeyPair:
Type: "AWS::EC2::KeyPair"
Properties:
KeyName: haha-test-key
KeyFormat: pem
KeyType: rsa
Tags:
- Key: Name
Value: haha-test-key

2. Security Group

🤓 功能說明: Security Group 是一個虛擬防火牆,用於控制 EC2 實例的流量。您可以配置 Security Group 規則以允許或拒絕特定端口和 IP 地址的訪問。這是保護 EC2 實例免受未經授權訪問的關鍵元件,同時確保了安全性。

hahaTestWebSg:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: hahaTestWebSg
VpcId: !Ref VPC
Tags:
- Key: Name
Value: "haha-Test-Web-SG"

WebBaseIngress1:
Type: "AWS::EC2::SecurityGroupIngress"
Properties:
GroupId: !Ref hahaTestWebSg
IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 210.64.53.104/32
Description: "Allow from PTC IP"

WebBaseIngress2:
Type: "AWS::EC2::SecurityGroupIngress"
Properties:
GroupId: !Ref hahaTestWebSg
IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 10.0.0.0/16
Description: "Allow from VPC"

WebBaseIngress3:
Type: "AWS::EC2::SecurityGroupIngress"
Properties:
GroupId: !Ref hahaTestWebSg
IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 210.64.53.104/32
Description: "Allow from PTC IP"

hahaTestApSg:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: hahaTestApSg
VpcId: !Ref VPC
Tags:
- Key: Name
Value: "haha-Test-AP-SG"

APBaseIngress1:
Type: "AWS::EC2::SecurityGroupIngress"
Properties:
GroupId: !Ref hahaTestApSg
IpProtocol: tcp
FromPort: 80
ToPort: 80
SourceSecurityGroupId: !GetAtt hahaTestWebSg.GroupId
Description: "Allow from hahaTestWebSg"

APBaseIngress2:
Type: "AWS::EC2::SecurityGroupIngress"
Properties:
GroupId: !Ref hahaTestApSg
IpProtocol: tcp
FromPort: 22
ToPort: 22
SourceSecurityGroupId: !GetAtt hahaTestWebSg.GroupId
Description: "Allow from hahaTestWebSg"

hahaTestRdsSg:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: hahaTestRdsSg
VpcId: !Ref VPC
Tags:
- Key: Name
Value: "haha-Test-RDS-SG"

RDSBaseIngress1:
Type: "AWS::EC2::SecurityGroupIngress"
Properties:
GroupId: !Ref hahaTestRdsSg
IpProtocol: tcp
FromPort: 3306
ToPort: 3306
SourceSecurityGroupId: !GetAtt hahaTestWebSg.GroupId
Description: "Allow from hahaTestWebSg"

RDSBaseIngress2:
Type: "AWS::EC2::SecurityGroupIngress"
Properties:
GroupId: !Ref hahaTestRdsSg
IpProtocol: tcp
FromPort: 3306
ToPort: 3306
SourceSecurityGroupId: !GetAtt hahaTestApSg.GroupId
Description: "Allow from hahaTestApSg"

3. Elastic IP (EIP)

🤓 功能說明: Elastic IP 是一個可用於靈活映射到 EC2 實例的靜態 IPv4 地址。這是 AWS 的彈性 IP 地址服務,允許您輕松地將 IP 地址分配給 EC2 實例,以確保您的應用程序保持連接性,即使實例被停止和重新啟動。

NATGatewayEIP:
Type: AWS::EC2::EIP
Properties:
Domain: vpc
Tags:
- Key: "Name"
Value: "haha-test-eip-a"

4. NAT (Network Address Translation)

🤓 功能說明: NAT 是一種網絡服務,用於將私有子網中的流量轉換為公共子網或互聯網流量。它通常與私有子網中的 EC2 實例一起使用,以實現這些實例能夠訪問互聯網,同時保持內部網絡的安全性。NAT 選項包括 NAT 閘道和NAT 代理,用於不同的情況。

NATGateway:
DependsOn: PrivateSubnet1
Type: AWS::EC2::NatGateway
Properties:
SubnetId: !Ref PublicSubnet1
AllocationId: !GetAtt
- NATGatewayEIP
- AllocationId
Tags:
- Key: "Name"
Value: "haha-test-nat-a"

NATGatewayRoute:
Type: AWS::EC2::Route
Properties:
RouteTableId:
Ref: PrivateRouteTable
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId:
Ref: NATGateway

5. EC2 (Elastic Compute Cloud)

🤓 功能說明: Elastic Compute Cloud (EC2) 是 AWS 提供的虛擬機器服務。它允許用戶彈性地啟動、停止和管理虛擬機器,並在這些虛擬機器上運行各種應用程序。EC2 實例提供不同的計算能力和配置選項,以滿足不同應用程序和工作負載的需求。

Web01: # Ubuntu 22.04
Type: "AWS::EC2::Instance"
Properties:
ImageId: !Ref Ubuntu2204
InstanceType: !Ref InstanceType
KeyName: !Ref NewKeyPair
# SubnetId: !Ref PublicSubnet1
# SecurityGroupIds:
# - Ref: "hahaTestWebSg"
NetworkInterfaces:
[
{
"AssociatePublicIpAddress": "True",
"DeleteOnTermination": "True",
"SubnetId": { "Ref": "PublicSubnet1" },
"DeviceIndex": "0",
"GroupSet": [{ "Ref": "hahaTestWebSg" }],
},
]
Tags:
- Key: Name
Value: "haha-test-Web-01"
BlockDeviceMappings:
- DeviceName: /dev/sda1
Ebs:
VolumeType: gp3
VolumeSize: "8" # Linux/UNIX Need 8G
# DeleteOnTermination: "true"
Encrypted: "false"

AP01: # Ubuntu 22.04
Type: "AWS::EC2::Instance"
Properties:
ImageId: !Ref Ubuntu2204
InstanceType: !Ref InstanceType
KeyName: !Ref NewKeyPair
SubnetId: !Ref PrivateSubnet1
SecurityGroupIds:
- Ref: "hahaTestApSg"
Tags:
- Key: Name
Value: "haha-test-AP-01"
BlockDeviceMappings:
- DeviceName: /dev/sda1
Ebs:
VolumeType: gp3
VolumeSize: "8" # Linux/UNIX Need 8G
DeleteOnTermination: "true"
Encrypted: "false"

6. RDS (Relational Database Service)

🤓 功能說明: Relational Database Service (RDS) 是 AWS 提供的受管關係型數據庫服務。RDS 支持多種關係型數據庫引擎,包括MySQL、PostgreSQL、Oracle、SQL Server等。它簡化了數據庫的設置、配置、備份和維護,同時提供高可用性選項,使您能夠建立可靠的數據庫基礎架構。

 myDBSubnetGroup:
Type: AWS::RDS::DBSubnetGroup
Properties:
DBSubnetGroupDescription: haha-test-rds-subnet-group
DBSubnetGroupName: haha-test-rds-subnet-group
SubnetIds:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
Tags:
- Key: Name
Value: haha-test-rds-subnet-group

MyRDSInstance:
Type: AWS::RDS::DBInstance
Properties:
AllocatedStorage: 20
DBInstanceClass: db.t2.micro
Engine: mysql
DBInstanceIdentifier: database-1 # Set the custom identifier
MasterUsername: !Ref DBUser
MasterUserPassword: !Ref DBPassword
VPCSecurityGroups:
- !GetAtt hahaTestRdsSg.GroupId
DBSubnetGroupName: !Ref myDBSubnetGroup
MultiAZ: false
PubliclyAccessible: false
StorageType: gp3 # Set to gp3 to use the default IOPS value
CACertificateIdentifier: rds-ca-rsa2048-g1 # Specify the CA Certificate
BackupRetentionPeriod: 0 # Set to 0 to disable automatic backups
Tags:
- Key: Name
Value: haha-test-rds

以上是此章節新增會建置的AWS資源項目。

完整的yaml檔如下:

AWSTemplateFormatVersion: 2010-09-09
Description: Haha Teach template

# Lab VPC with 2 public + 2 private subnets
# Route Public + Route Private
# IGW for Public + Public Subnet

# Key Pair
# Security Group
# RDS Subnet Group
# NAT + Route Tables
# EC2
# RDS

Parameters:
InstanceType:
Description: EC2 instance type
Type: String
Default: t2.micro
ConstraintDescription: Please choose a valid instance type.

Ubuntu2204:
Type: String
Default: "ami-0fc5d935ebf8bc3bc"
Description: "Canonical, Ubuntu, 22.04 LTS, amd64 jammy image build on 2023-09-19"

DBUser:
Default: admin
NoEcho: "true"
Description: The database admin account username
Type: String
MinLength: "1"
MaxLength: "16"
AllowedPattern: "[a-zA-Z][a-zA-Z0-9]*"
ConstraintDescription: must begin with a letter and contain only alphanumeric characters.
DBPassword:
Default: Dev12876266
NoEcho: "true"
Description: The database admin account password
Type: String
MinLength: "8"
MaxLength: "41"
AllowedPattern: "[a-zA-Z0-9]*"
ConstraintDescription: must contain only alphanumeric characters.

Resources:
###########
# VPC with Internet Gateway
###########

# Create VPC
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: haha-test-VPC

# Create Internet Gateways (IGW)
IGW:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: haha-test-IGW

# VPC↔IGW Connect
VPCtoIGWConnection:
Type: AWS::EC2::VPCGatewayAttachment
DependsOn:
- IGW
- VPC
Properties:
InternetGatewayId: !Ref IGW
VpcId: !Ref VPC

###########
# Public Route Table
###########

PublicRouteTable:
Type: AWS::EC2::RouteTable
DependsOn: VPC
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: haha-test-Public-Route

PublicRoute:
Type: AWS::EC2::Route
DependsOn:
- PublicRouteTable
- VPCtoIGWConnection
Properties:
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref IGW
RouteTableId: !Ref PublicRouteTable

###########
# Private Route Table
###########

PrivateRouteTable:
Type: AWS::EC2::RouteTable
DependsOn: VPC
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: haha-test-Private-Route

###########
# Public Subnets x 2
###########

PublicSubnet1:
Type: AWS::EC2::Subnet
DependsOn: VPC
Properties:
VpcId: !Ref VPC
MapPublicIpOnLaunch: true
CidrBlock: 10.0.1.0/24
AvailabilityZone: !Select
- 0
- !GetAZs
Ref: AWS::Region
Tags:
- Key: Name
Value: haha-test-PublicSubnet-1

PublicSubnet2:
Type: AWS::EC2::Subnet
DependsOn: VPC
Properties:
VpcId: !Ref VPC
MapPublicIpOnLaunch: true
CidrBlock: 10.0.2.0/24
AvailabilityZone: !Select
- 1
- !GetAZs
Ref: AWS::Region
Tags:
- Key: Name
Value: haha-test-PublicSubnet-2

PublicRouteTableAssociation1:
Type: AWS::EC2::SubnetRouteTableAssociation
DependsOn:
- PublicRouteTable
- PublicSubnet1
Properties:
RouteTableId: !Ref PublicRouteTable
SubnetId: !Ref PublicSubnet1

PublicRouteTableAssociation2:
Type: AWS::EC2::SubnetRouteTableAssociation
DependsOn:
- PublicRouteTable
- PublicSubnet2
Properties:
RouteTableId: !Ref PublicRouteTable
SubnetId: !Ref PublicSubnet2

###########
# Private Subnets x 2
###########

PrivateSubnet1:
Type: AWS::EC2::Subnet
DependsOn: VPC
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.3.0/24
AvailabilityZone: !Select
- 0
- !GetAZs
Ref: AWS::Region
Tags:
- Key: Name
Value: haha-test-PrivateSubnet-1

PrivateSubnet2:
Type: AWS::EC2::Subnet
DependsOn: VPC
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.4.0/24
AvailabilityZone: !Select
- 1
- !GetAZs
Ref: AWS::Region
Tags:
- Key: Name
Value: haha-test-PrivateSubnet-2

PrivateRouteTableAssociation1:
Type: AWS::EC2::SubnetRouteTableAssociation
DependsOn:
- PrivateRouteTable
- PrivateSubnet1
Properties:
RouteTableId: !Ref PrivateRouteTable
SubnetId: !Ref PrivateSubnet1

PrivateRouteTableAssociation2:
Type: AWS::EC2::SubnetRouteTableAssociation
DependsOn:
- PrivateRouteTable
- PrivateSubnet2
Properties:
RouteTableId: !Ref PrivateRouteTable
SubnetId: !Ref PrivateSubnet2

###########
# KeyPair
###########

# key-0e3fd04c9ad7242ed
# aws ssm get-parameter --name /ec2/keypair/key-0e3fd04c9ad7242ed --with-decryption --query Parameter.Value --output text > haha-test-key.pem

NewKeyPair:
Type: "AWS::EC2::KeyPair"
Properties:
KeyName: haha-test-key
KeyFormat: pem
KeyType: rsa
Tags:
- Key: Name
Value: haha-test-key

###########
# Security Group
###########

hahaTestWebSg:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: hahaTestWebSg
VpcId: !Ref VPC
Tags:
- Key: Name
Value: "haha-Test-Web-SG"

WebBaseIngress1:
Type: "AWS::EC2::SecurityGroupIngress"
Properties:
GroupId: !Ref hahaTestWebSg
IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 210.64.53.104/32
Description: "Allow from PTC IP"

WebBaseIngress2:
Type: "AWS::EC2::SecurityGroupIngress"
Properties:
GroupId: !Ref hahaTestWebSg
IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 10.0.0.0/16
Description: "Allow from VPC"

WebBaseIngress3:
Type: "AWS::EC2::SecurityGroupIngress"
Properties:
GroupId: !Ref hahaTestWebSg
IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 210.64.53.104/32
Description: "Allow from PTC IP"

hahaTestApSg:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: hahaTestApSg
VpcId: !Ref VPC
Tags:
- Key: Name
Value: "haha-Test-AP-SG"

APBaseIngress1:
Type: "AWS::EC2::SecurityGroupIngress"
Properties:
GroupId: !Ref hahaTestApSg
IpProtocol: tcp
FromPort: 80
ToPort: 80
SourceSecurityGroupId: !GetAtt hahaTestWebSg.GroupId
Description: "Allow from hahaTestWebSg"

APBaseIngress2:
Type: "AWS::EC2::SecurityGroupIngress"
Properties:
GroupId: !Ref hahaTestApSg
IpProtocol: tcp
FromPort: 22
ToPort: 22
SourceSecurityGroupId: !GetAtt hahaTestWebSg.GroupId
Description: "Allow from hahaTestWebSg"

hahaTestRdsSg:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: hahaTestRdsSg
VpcId: !Ref VPC
Tags:
- Key: Name
Value: "haha-Test-RDS-SG"

RDSBaseIngress1:
Type: "AWS::EC2::SecurityGroupIngress"
Properties:
GroupId: !Ref hahaTestRdsSg
IpProtocol: tcp
FromPort: 3306
ToPort: 3306
SourceSecurityGroupId: !GetAtt hahaTestWebSg.GroupId
Description: "Allow from hahaTestWebSg"

RDSBaseIngress2:
Type: "AWS::EC2::SecurityGroupIngress"
Properties:
GroupId: !Ref hahaTestRdsSg
IpProtocol: tcp
FromPort: 3306
ToPort: 3306
SourceSecurityGroupId: !GetAtt hahaTestApSg.GroupId
Description: "Allow from hahaTestApSg"

###########
# Elastic IPs
###########

NATGatewayEIP:
Type: AWS::EC2::EIP
Properties:
Domain: vpc
Tags:
- Key: "Name"
Value: "haha-test-eip-a"

###########
# NAT Gateway
###########

NATGateway:
DependsOn: PrivateSubnet1
Type: AWS::EC2::NatGateway
Properties:
SubnetId: !Ref PublicSubnet1
AllocationId: !GetAtt
- NATGatewayEIP
- AllocationId
Tags:
- Key: "Name"
Value: "haha-test-nat-a"

NATGatewayRoute:
Type: AWS::EC2::Route
Properties:
RouteTableId:
Ref: PrivateRouteTable
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId:
Ref: NATGateway

###########
# EC2 Instance
###########

Web01: # Ubuntu 22.04
Type: "AWS::EC2::Instance"
Properties:
ImageId: !Ref Ubuntu2204
InstanceType: !Ref InstanceType
KeyName: !Ref NewKeyPair
# SubnetId: !Ref PublicSubnet1
# SecurityGroupIds:
# - Ref: "hahaTestWebSg"
NetworkInterfaces:
[
{
"AssociatePublicIpAddress": "True",
"DeleteOnTermination": "True",
"SubnetId": { "Ref": "PublicSubnet1" },
"DeviceIndex": "0",
"GroupSet": [{ "Ref": "hahaTestWebSg" }],
},
]
Tags:
- Key: Name
Value: "haha-test-Web-01"
BlockDeviceMappings:
- DeviceName: /dev/sda1
Ebs:
VolumeType: gp3
VolumeSize: "8" # Linux/UNIX Need 8G
# DeleteOnTermination: "true"
Encrypted: "false"

AP01: # Ubuntu 22.04
Type: "AWS::EC2::Instance"
Properties:
ImageId: !Ref Ubuntu2204
InstanceType: !Ref InstanceType
KeyName: !Ref NewKeyPair
SubnetId: !Ref PrivateSubnet1
SecurityGroupIds:
- Ref: "hahaTestApSg"
Tags:
- Key: Name
Value: "haha-test-AP-01"
BlockDeviceMappings:
- DeviceName: /dev/sda1
Ebs:
VolumeType: gp3
VolumeSize: "8" # Linux/UNIX Need 8G
DeleteOnTermination: "true"
Encrypted: "false"

###########
# RDS Subnet Group
###########

myDBSubnetGroup:
Type: AWS::RDS::DBSubnetGroup
Properties:
DBSubnetGroupDescription: haha-test-rds-subnet-group
DBSubnetGroupName: haha-test-rds-subnet-group
SubnetIds:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
Tags:
- Key: Name
Value: haha-test-rds-subnet-group

###########
# RDS Instance
###########

MyRDSInstance:
Type: AWS::RDS::DBInstance
Properties:
AllocatedStorage: 20
DBInstanceClass: db.t2.micro
Engine: mysql
DBInstanceIdentifier: database-1 # Set the custom identifier
MasterUsername: !Ref DBUser
MasterUserPassword: !Ref DBPassword
VPCSecurityGroups:
- !GetAtt hahaTestRdsSg.GroupId
DBSubnetGroupName: !Ref myDBSubnetGroup
MultiAZ: false
PubliclyAccessible: false
StorageType: gp3 # Set to gp3 to use the default IOPS value
CACertificateIdentifier: rds-ca-rsa2048-g1 # Specify the CA Certificate
BackupRetentionPeriod: 0 # Set to 0 to disable automatic backups
Tags:
- Key: Name
Value: haha-test-rds

🌲 將檔案上傳至S3 bucket,並取得檔案連結:

🌲 在CloudFormation快速佈署建置:

👍 VPC 建置完成

👍 NAT 建置完成

👍 Private Subnet 透過 NAT 上 Internet 的 Route tables 設定完成

👍 Web 及 AP 二台 EC2 主機建置完成

👍 Web、AP 及 RDS 安全組 Security Group 建置完成

👍 EIP 建置完成

👍 RDS 資料庫建置完成

👍 KeyPair 建置完成

🗑️清理您的環境

在您成功建立了基本網路架構之後,請不要忘記清理您的AWS環境。這對於避免不必要的費用和資源浪費至關重要。

👉 刪除中,約需10多分鐘才能完成資源刪除。

👉 所有資源刪除完成

👉 可以至剛剛的每個資源畫面進行確認:

🥳 此次練習所建置的資源,已確認全數刪除完成。

🚩後續預告

後續的章節,將深入探討建立高可用性的3-Tier架構。我們將學習如何避免單機或單點障害的 3-Tier 架構規劃。

🤝請繼續關注,我們下次見 ^_^..

--

--