為什麼需要 Public 與 Private Subnet?
AWS VPC 網路架構的核心設計理念
在 Amazon Web Services (AWS) 的 Virtual Private Cloud (VPC) 架構中,Public Subnet 與 Private Subnet 的設計並非任意區分,而是基於「最小權限原則」與「縱深防禦」的資安最佳實踐。這種網路分層設計能有效降低攻擊面,保護關鍵資源,同時保持必要的外部連線能力。
1. 安全性分層防護
Public Subnet 的暴露風險:
- 直接暴露於網際網路,面臨更高的攻擊風險(DDoS、掃描、暴力破解)
- 必須具備強大的安全防護(Security Group、NACL、WAF)
- 適合放置「必須對外服務」的元件(Load Balancer、NAT Gateway、Bastion Host)
Private Subnet 的隔離保護:
- 完全隔離於網際網路直接訪問,大幅降低攻擊面
- 僅能透過特定管道訪問(Bastion Host、VPN、AWS Systems Manager)
- 適合放置「不應對外」的敏感資源(資料庫、應用伺服器、內部服務)
實際案例:2023 年某企業因將 RDS 資料庫放在 Public Subnet 並開放 0.0.0.0/0 訪問,導致資料外洩。若採用 Private Subnet + 嚴格的 Security Group,此類事故可完全避免。
2. 成本優化與效能提升
- NAT Gateway 集中管理:Private Subnet 中的所有實例共用 NAT Gateway 出站,節省 Elastic IP 成本
- VPC Endpoint 省流量費:Private Subnet 可透過 VPC Endpoint 訪問 AWS 服務(S3, DynamoDB),流量不經網際網路,免除資料傳輸費用
- 降低頻寬成本:內部服務間通訊保持在 VPC 內,避免昂貴的外網流量費用
3. 合規性需求
許多合規標準(GDPR、HIPAA、PCI-DSS)要求:
- 敏感資料必須儲存在隔離環境
- 資料庫不得直接暴露於網際網路
- 需有明確的網路存取控制與稽核
Private Subnet 的設計天然符合這些要求,能大幅簡化合規性驗證流程。
Public Subnet 詳解
定義與特徵
Public Subnet 是指其內部的 EC2 實例可以直接與網際網路雙向通訊的子網路。關鍵特徵:
- ✅ 路由表包含指向 Internet Gateway (IGW) 的路由(0.0.0.0/0 → IGW)
- ✅ 實例具備 Public IP 或 Elastic IP (EIP)
- ✅ Security Group 允許來自網際網路的入站流量(特定埠)
- ✅ Network ACL 允許進出流量
完整配置步驟
1. 建立 VPC 與 Internet Gateway
# 建立 VPC
aws ec2 create-vpc --cidr-block 10.0.0.0/16 --tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=MyVPC}]'
# 建立 Internet Gateway
aws ec2 create-internet-gateway --tag-specifications 'ResourceType=internet-gateway,Tags=[{Key=Name,Value=MyIGW}]'
# 將 IGW 附加到 VPC
aws ec2 attach-internet-gateway --vpc-id vpc-xxxxxxxx --internet-gateway-id igw-yyyyyyyy
2. 建立 Public Subnet
# 建立 Public Subnet(使用可用區 us-east-1a)
aws ec2 create-subnet
--vpc-id vpc-xxxxxxxx
--cidr-block 10.0.1.0/24
--availability-zone us-east-1a
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=PublicSubnet-1A}]'
# 啟用自動分配 Public IP
aws ec2 modify-subnet-attribute
--subnet-id subnet-xxxxxxxx
--map-public-ip-on-launch
3. 設定路由表
# 建立路由表
aws ec2 create-route-table
--vpc-id vpc-xxxxxxxx
--tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=PublicRouteTable}]'
# 新增指向 IGW 的路由
aws ec2 create-route
--route-table-id rtb-xxxxxxxx
--destination-cidr-block 0.0.0.0/0
--gateway-id igw-yyyyyyyy
# 將路由表關聯至 Public Subnet
aws ec2 associate-route-table
--route-table-id rtb-xxxxxxxx
--subnet-id subnet-xxxxxxxx
4. 設定 Security Group
# 建立 Security Group(允許 HTTP/HTTPS 入站)
aws ec2 create-security-group
--group-name WebServerSG
--description "Allow HTTP/HTTPS from internet"
--vpc-id vpc-xxxxxxxx
# 允許 HTTP 入站
aws ec2 authorize-security-group-ingress
--group-id sg-xxxxxxxx
--protocol tcp
--port 80
--cidr 0.0.0.0/0
# 允許 HTTPS 入站
aws ec2 authorize-security-group-ingress
--group-id sg-xxxxxxxx
--protocol tcp
--port 443
--cidr 0.0.0.0/0
# 允許 SSH(建議限制來源 IP)
aws ec2 authorize-security-group-ingress
--group-id sg-xxxxxxxx
--protocol tcp
--port 22
--cidr YOUR_IP/32
適用場景
- Web 伺服器:Apache、Nginx、IIS 等需直接接受使用者請求的伺服器
- Application Load Balancer (ALB):分散流量至後端應用伺服器
- NAT Gateway:為 Private Subnet 提供出站網際網路訪問
- Bastion Host (Jump Server):作為進入 Private Subnet 的安全跳板
- VPN Gateway:企業內部網路與 AWS VPC 的連線端點
Private Subnet 詳解
定義與特徵
Private Subnet 是指其內部的 EC2 實例無法直接與網際網路雙向通訊的子網路。關鍵特徵:
- ✅ 路由表「不包含」指向 Internet Gateway 的路由
- ✅ 實例「不分配」Public IP(僅有 Private IP)
- ✅ 出站網際網路訪問需透過 NAT Gateway 或 NAT Instance
- ✅ 入站訪問僅能透過 VPC 內部或 VPN/Direct Connect
完整配置步驟
1. 建立 Private Subnet
# 建立 Private Subnet(使用可用區 us-east-1a)
aws ec2 create-subnet
--vpc-id vpc-xxxxxxxx
--cidr-block 10.0.10.0/24
--availability-zone us-east-1a
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=PrivateSubnet-1A}]'
# 確認不自動分配 Public IP(預設即為關閉)
aws ec2 describe-subnets --subnet-ids subnet-xxxxxxxx --query 'Subnets[0].MapPublicIpOnLaunch'
2. 建立 NAT Gateway(讓 Private Subnet 可出站訪問網際網路)
# 先分配 Elastic IP
aws ec2 allocate-address --domain vpc
# 建立 NAT Gateway(必須放在 Public Subnet)
aws ec2 create-nat-gateway
--subnet-id subnet-PUBLIC-SUBNET-ID
--allocation-id eipalloc-xxxxxxxx
--tag-specifications 'ResourceType=nat-gateway,Tags=[{Key=Name,Value=MyNATGateway}]'
3. 設定 Private Subnet 路由表
# 建立路由表
aws ec2 create-route-table
--vpc-id vpc-xxxxxxxx
--tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=PrivateRouteTable}]'
# 新增指向 NAT Gateway 的路由
aws ec2 create-route
--route-table-id rtb-xxxxxxxx
--destination-cidr-block 0.0.0.0/0
--nat-gateway-id nat-xxxxxxxx
# 將路由表關聯至 Private Subnet
aws ec2 associate-route-table
--route-table-id rtb-xxxxxxxx
--subnet-id subnet-xxxxxxxx
4. 設定 Security Group(僅允許 VPC 內部訪問)
# 建立 Security Group(僅允許來自 VPC 內部的流量)
aws ec2 create-security-group
--group-name PrivateAppSG
--description "Allow traffic only from VPC"
--vpc-id vpc-xxxxxxxx
# 允許來自 Public Subnet 的 HTTP 流量(例如來自 ALB)
aws ec2 authorize-security-group-ingress
--group-id sg-xxxxxxxx
--protocol tcp
--port 8080
--source-group sg-PUBLIC-SG-ID
# 允許來自 Bastion Host 的 SSH
aws ec2 authorize-security-group-ingress
--group-id sg-xxxxxxxx
--protocol tcp
--port 22
--source-group sg-BASTION-SG-ID
適用場景
- 資料庫伺服器:RDS、Aurora、自建 MySQL/PostgreSQL/MongoDB
- 應用伺服器:後端 API、微服務、處理業務邏輯的伺服器
- 快取層:ElastiCache (Redis/Memcached)
- 訊息佇列:Amazon MQ、RabbitMQ、Kafka
- 批次處理伺服器:資料分析、ETL 任務、排程作業
Public vs Private Subnet 對比表
| 特性 | Public Subnet | Private Subnet |
|---|---|---|
| Internet Gateway | ✅ 路由表指向 IGW | ❌ 路由表不指向 IGW |
| Public IP | ✅ 自動分配或手動綁定 EIP | ❌ 僅有 Private IP |
| 入站網際網路訪問 | ✅ 允許(需 Security Group 開放) | ❌ 禁止 |
| 出站網際網路訪問 | ✅ 直接透過 IGW | ✅ 透過 NAT Gateway/Instance |
| 安全性風險 | ⚠️ 高(直接暴露) | ✅ 低(隔離保護) |
| 適用資源 | ALB、Web Server、Bastion | RDS、App Server、Cache |
| NAT Gateway 費用 | 不需要 | 需要($0.045/小時 + 流量費) |
| VPC Endpoint | 可選 | 強烈建議(省流量費) |
常見問題 FAQ
Q1: Private Subnet 中的 EC2 如何更新軟體套件?
答案:透過 NAT Gateway 或 VPC Endpoint
方案 1:使用 NAT Gateway(適用於一般網際網路訪問)
# 在 Private Subnet 的 EC2 上執行
sudo yum update -y # Amazon Linux
sudo apt update && sudo apt upgrade -y # Ubuntu
# 流量路徑:EC2 → NAT Gateway → Internet Gateway → 網際網路
方案 2:使用 VPC Endpoint(適用於 AWS 服務,免流量費)
# 建立 S3 VPC Endpoint (Gateway Endpoint,免費)
aws ec2 create-vpc-endpoint
--vpc-id vpc-xxxxxxxx
--service-name com.amazonaws.us-east-1.s3
--route-table-ids rtb-PRIVATE-ROUTE-TABLE
# 建立 Systems Manager VPC Endpoint (Interface Endpoint,每小時 $0.01)
aws ec2 create-vpc-endpoint
--vpc-id vpc-xxxxxxxx
--vpc-endpoint-type Interface
--service-name com.amazonaws.us-east-1.ssm
--subnet-ids subnet-xxxxxxxx
--security-group-ids sg-xxxxxxxx
成本對比:
- NAT Gateway:$0.045/小時 + $0.045/GB 流量 ≈ $33/月 + 流量費
- VPC Endpoint (S3):免費
- VPC Endpoint (Interface):$0.01/小時 ≈ $7.2/月
Q2: 如何從本地連線到 Private Subnet 的資料庫?
答案:三種常見方案
方案 1:透過 Bastion Host (Jump Server)
# SSH 隧道連線
ssh -i mykey.pem -L 3306:rds-endpoint.amazonaws.com:3306 ec2-user@BASTION-PUBLIC-IP
# 本地連線資料庫
mysql -h 127.0.0.1 -P 3306 -u admin -p
方案 2:使用 AWS Systems Manager Session Manager(無需 Bastion Host)
# 安裝 Session Manager Plugin
curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/mac/sessionmanager-bundle.zip" -o "sessionmanager-bundle.zip"
unzip sessionmanager-bundle.zip
sudo ./sessionmanager-bundle/install -i /usr/local/sessionmanagerplugin -b /usr/local/bin/session-manager-plugin
# 透過 SSM 建立 Port Forwarding
aws ssm start-session
--target i-PRIVATE-INSTANCE-ID
--document-name AWS-StartPortForwardingSessionToRemoteHost
--parameters '{"host":["rds-endpoint.amazonaws.com"],"portNumber":["3306"], "localPortNumber":["3306"]}'
# 本地連線資料庫
mysql -h 127.0.0.1 -P 3306 -u admin -p
方案 3:使用 VPN 或 Direct Connect(企業級方案)
- 建立 AWS Client VPN Endpoint
- 本地透過 VPN 連線進入 VPC
- 直接訪問 Private Subnet 資源
Q3: NAT Gateway 故障會影響 Private Subnet 的服務嗎?
答案:視服務類型而定
不受影響的場景:
- ✅ VPC 內部通訊(例如 ALB → App Server → RDS)
- ✅ 透過 VPC Endpoint 訪問 AWS 服務(S3, DynamoDB)
- ✅ 已建立連線的長期任務(若無需新建出站連線)
受影響的場景:
- ❌ 需要訪問外部 API(例如第三方支付、簡訊服務)
- ❌ 需要下載網際網路資源(apt/yum update、Docker pull)
- ❌ 需要發送外部通知(Email、Webhook)
高可用性方案:
# 在每個可用區建立獨立的 NAT Gateway
# AZ 1a
aws ec2 create-nat-gateway --subnet-id subnet-public-1a --allocation-id eipalloc-1a
# AZ 1b
aws ec2 create-nat-gateway --subnet-id subnet-public-1b --allocation-id eipalloc-1b
# 各 Private Subnet 的路由表指向同可用區的 NAT Gateway
# PrivateSubnet-1A → NAT-1A
# PrivateSubnet-1B → NAT-1B
成本影響:每個 NAT Gateway $33/月,雙 AZ 部署 = $66/月 + 流量費
Q4: Public Subnet 中的資源是否一定不安全?
答案:不一定,關鍵在於正確配置
Public Subnet 安全配置最佳實踐:
- 最小化開放埠
# ✅ 僅開放必要埠 Security Group: 允許 80, 443 (HTTP/HTTPS) 禁止: 22 (SSH), 3389 (RDP), 3306 (MySQL) # ❌ 危險設定 0.0.0.0/0:0-65535 ALLOW - 使用 ALB/NLB 作為前端
- ALB/NLB 放在 Public Subnet
- 實際應用伺服器放在 Private Subnet
- ALB 提供 WAF、SSL Termination、DDoS 防護
- 啟用 VPC Flow Logs
# 建立 Flow Logs(監控可疑流量) aws ec2 create-flow-logs --resource-type VPC --resource-ids vpc-xxxxxxxx --traffic-type ALL --log-destination-type cloud-watch-logs --log-group-name /aws/vpc/flowlogs - 定期安全掃描
- 使用 AWS Inspector 掃描漏洞
- 使用 GuardDuty 偵測異常行為
- 使用 Security Hub 統一管理安全狀態
Q5: 可以將 RDS 放在 Public Subnet 嗎?
答案:技術上可行,但強烈不建議
為什麼不建議:
- ❌ 違反最小權限原則:資料庫無需直接對外訪問
- ❌ 增加攻擊面:暴露於網際網路掃描與攻擊
- ❌ 合規性問題:違反 PCI-DSS、HIPAA 等標準
- ❌ 意外風險:錯誤配置 Security Group 可能導致資料外洩
正確架構:
網際網路
↓
Internet Gateway
↓
ALB (Public Subnet)
↓
App Server (Private Subnet)
↓
RDS (Private Subnet - 使用 DB Subnet Group)
例外情況:
- 開發/測試環境需要外部工具直接連線(不建議,應使用 Bastion 或 SSM)
- 臨時 POC 驗證(務必在測試後立即遷移至 Private Subnet)
Q6: 如何選擇 NAT Gateway 還是 NAT Instance?
答案:大多數情況推薦 NAT Gateway
| 特性 | NAT Gateway(推薦) | NAT Instance |
|---|---|---|
| 可用性 | ✅ AWS 管理,高可用性 | ❌ 單點故障,需自建 HA |
| 效能 | ✅ 最高 100 Gbps | ⚠️ 受限於實例規格 |
| 維護成本 | ✅ 零維護 | ❌ 需自行管理、打補丁 |
| 費用 | ⚠️ $0.045/小時 + 流量費 | ✅ 僅 EC2 費用 |
| 適用場景 | 生產環境 | 開發/測試、成本敏感 |
NAT Instance 設定範例(僅供參考):
# 啟動 NAT Instance(使用 AWS 官方 NAT AMI)
aws ec2 run-instances
--image-id ami-xxxxxxxxxxxx
--instance-type t3.micro
--subnet-id subnet-PUBLIC-SUBNET
--security-group-ids sg-xxxxxxxx
# 停用來源/目標檢查(必要設定)
aws ec2 modify-instance-attribute
--instance-id i-xxxxxxxx
--no-source-dest-check
# 修改 Private Subnet 路由表指向 NAT Instance
aws ec2 create-route
--route-table-id rtb-xxxxxxxx
--destination-cidr-block 0.0.0.0/0
--instance-id i-NAT-INSTANCE-ID
Q7: VPC Peering 或 Transit Gateway 環境下如何配置 Subnet?
答案:需調整路由表以支援跨 VPC 通訊
場景:VPC-A 與 VPC-B 透過 VPC Peering 連線
# VPC-A (10.0.0.0/16) ←→ VPC-B (10.1.0.0/16)
# 在 VPC-A 的 Private Subnet 路由表新增指向 VPC-B 的路由
aws ec2 create-route
--route-table-id rtb-VPC-A-PRIVATE
--destination-cidr-block 10.1.0.0/16
--vpc-peering-connection-id pcx-xxxxxxxx
# 在 VPC-B 的 Private Subnet 路由表新增指向 VPC-A 的路由
aws ec2 create-route
--route-table-id rtb-VPC-B-PRIVATE
--destination-cidr-block 10.0.0.0/16
--vpc-peering-connection-id pcx-xxxxxxxx
Transit Gateway 架構(推薦用於多 VPC 環境):
VPC-A (10.0.0.0/16) ─┐
VPC-B (10.1.0.0/16) ─┼─→ Transit Gateway ←─ On-Premises (192.168.0.0/16)
VPC-C (10.2.0.0/16) ─┘
# 各 VPC 的路由表新增指向 TGW 的路由
aws ec2 create-route
--route-table-id rtb-VPC-A-PRIVATE
--destination-cidr-block 0.0.0.0/0
--transit-gateway-id tgw-xxxxxxxx
最佳實踐
架構設計
- 三層架構標準配置
Public Subnet: ALB, NAT Gateway, Bastion Host Private Subnet: Application Servers, Lambda (in VPC) Data Subnet: RDS, ElastiCache, Redshift (更嚴格的 Security Group) - 多可用區部署(高可用性)
- 每個 AZ 都配置 Public Subnet 與 Private Subnet
- 每個 AZ 都配置獨立的 NAT Gateway
- RDS 使用 Multi-AZ 部署
- CIDR 規劃原則
VPC: 10.0.0.0/16 (65536 個 IP) Public-1A: 10.0.1.0/24 (256 個 IP) Public-1B: 10.0.2.0/24 Private-1A: 10.0.10.0/24 Private-1B: 10.0.11.0/24 Data-1A: 10.0.20.0/24 Data-1B: 10.0.21.0/24 預留: 10.0.100.0/22 (未來擴充)
安全性
- Security Group 最小化原則
- 僅開放必要埠
- 使用 Security Group ID 而非 CIDR(例如:允許來自 sg-alb 的流量)
- 禁止 0.0.0.0/0 訪問敏感埠
- Network ACL 作為第二道防線
# 阻擋已知惡意 IP 段 aws ec2 create-network-acl-entry --network-acl-id acl-xxxxxxxx --rule-number 10 --protocol -1 --rule-action deny --cidr-block 123.45.67.0/24 - 啟用 VPC Flow Logs 與 GuardDuty
成本優化
- 使用 VPC Endpoint 取代 NAT Gateway(適用於 AWS 服務)
- S3, DynamoDB 使用 Gateway Endpoint(免費)
- 其他服務使用 Interface Endpoint($0.01/小時,但省流量費)
- 評估 NAT Gateway 必要性
- 若僅需訪問 AWS 服務 → 使用 VPC Endpoint
- 若需訪問外部 API → 保留 NAT Gateway
- 使用 Reserved Capacity(長期使用)
維運管理
- 使用 AWS Systems Manager 取代 Bastion Host
- 無需維護跳板機
- 完整的稽核記錄
- 支援 Session Manager, Port Forwarding
- 自動化備份與災難復原
- 使用 Terraform/CloudFormation 管理基礎設施
- 定期測試災難復原流程
- 監控與告警
- 監控 NAT Gateway 流量與錯誤率
- 監控 VPC Flow Logs 異常流量
- 設定 CloudWatch Alarm 通知
實戰案例:三層架構完整部署
架構圖
網際網路
↓
Internet Gateway
↓
┌───────────────────┴───────────────────┐
│ Public Subnet │
│ - ALB (443, 80) │
│ - NAT Gateway (AZ-1A, AZ-1B) │
│ - Bastion Host (SSH 僅限公司 IP) │
└───────────────────┬───────────────────┘
↓
┌───────────────────┴───────────────────┐
│ Private Subnet │
│ - App Servers (Auto Scaling) │
│ - Lambda Functions (in VPC) │
│ - ElastiCache Redis │
└───────────────────┬───────────────────┘
↓
┌───────────────────┴───────────────────┐
│ Data Subnet │
│ - RDS Aurora (Multi-AZ) │
│ - Redshift Cluster │
└───────────────────────────────────────┘
完整部署腳本(使用 AWS CLI)
#!/bin/bash
# 三層架構部署腳本
# 變數設定
VPC_CIDR="10.0.0.0/16"
PUBLIC_SUBNET_1A="10.0.1.0/24"
PUBLIC_SUBNET_1B="10.0.2.0/24"
PRIVATE_SUBNET_1A="10.0.10.0/24"
PRIVATE_SUBNET_1B="10.0.11.0/24"
DATA_SUBNET_1A="10.0.20.0/24"
DATA_SUBNET_1B="10.0.21.0/24"
# 1. 建立 VPC
VPC_ID=$(aws ec2 create-vpc --cidr-block $VPC_CIDR --query 'Vpc.VpcId' --output text)
aws ec2 create-tags --resources $VPC_ID --tags Key=Name,Value=Production-VPC
# 2. 建立 Internet Gateway
IGW_ID=$(aws ec2 create-internet-gateway --query 'InternetGateway.InternetGatewayId' --output text)
aws ec2 attach-internet-gateway --vpc-id $VPC_ID --internet-gateway-id $IGW_ID
# 3. 建立 Public Subnets
PUBLIC_SUBNET_1A_ID=$(aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block $PUBLIC_SUBNET_1A --availability-zone us-east-1a --query 'Subnet.SubnetId' --output text)
PUBLIC_SUBNET_1B_ID=$(aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block $PUBLIC_SUBNET_1B --availability-zone us-east-1b --query 'Subnet.SubnetId' --output text)
# 4. 建立 Private Subnets
PRIVATE_SUBNET_1A_ID=$(aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block $PRIVATE_SUBNET_1A --availability-zone us-east-1a --query 'Subnet.SubnetId' --output text)
PRIVATE_SUBNET_1B_ID=$(aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block $PRIVATE_SUBNET_1B --availability-zone us-east-1b --query 'Subnet.SubnetId' --output text)
# 5. 建立 Data Subnets
DATA_SUBNET_1A_ID=$(aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block $DATA_SUBNET_1A --availability-zone us-east-1a --query 'Subnet.SubnetId' --output text)
DATA_SUBNET_1B_ID=$(aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block $DATA_SUBNET_1B --availability-zone us-east-1b --query 'Subnet.SubnetId' --output text)
# 6. 建立 NAT Gateways(每個 AZ 一個)
EIP_1A=$(aws ec2 allocate-address --domain vpc --query 'AllocationId' --output text)
EIP_1B=$(aws ec2 allocate-address --domain vpc --query 'AllocationId' --output text)
NAT_1A=$(aws ec2 create-nat-gateway --subnet-id $PUBLIC_SUBNET_1A_ID --allocation-id $EIP_1A --query 'NatGateway.NatGatewayId' --output text)
NAT_1B=$(aws ec2 create-nat-gateway --subnet-id $PUBLIC_SUBNET_1B_ID --allocation-id $EIP_1B --query 'NatGateway.NatGatewayId' --output text)
# 等待 NAT Gateway 建立完成
aws ec2 wait nat-gateway-available --nat-gateway-ids $NAT_1A $NAT_1B
# 7. 設定路由表
# Public Route Table
PUBLIC_RT=$(aws ec2 create-route-table --vpc-id $VPC_ID --query 'RouteTable.RouteTableId' --output text)
aws ec2 create-route --route-table-id $PUBLIC_RT --destination-cidr-block 0.0.0.0/0 --gateway-id $IGW_ID
aws ec2 associate-route-table --route-table-id $PUBLIC_RT --subnet-id $PUBLIC_SUBNET_1A_ID
aws ec2 associate-route-table --route-table-id $PUBLIC_RT --subnet-id $PUBLIC_SUBNET_1B_ID
# Private Route Tables (每個 AZ 獨立)
PRIVATE_RT_1A=$(aws ec2 create-route-table --vpc-id $VPC_ID --query 'RouteTable.RouteTableId' --output text)
aws ec2 create-route --route-table-id $PRIVATE_RT_1A --destination-cidr-block 0.0.0.0/0 --nat-gateway-id $NAT_1A
aws ec2 associate-route-table --route-table-id $PRIVATE_RT_1A --subnet-id $PRIVATE_SUBNET_1A_ID
PRIVATE_RT_1B=$(aws ec2 create-route-table --vpc-id $VPC_ID --query 'RouteTable.RouteTableId' --output text)
aws ec2 create-route --route-table-id $PRIVATE_RT_1B --destination-cidr-block 0.0.0.0/0 --nat-gateway-id $NAT_1B
aws ec2 associate-route-table --route-table-id $PRIVATE_RT_1B --subnet-id $PRIVATE_SUBNET_1B_ID
# Data Route Table (無網際網路訪問)
DATA_RT=$(aws ec2 create-route-table --vpc-id $VPC_ID --query 'RouteTable.RouteTableId' --output text)
aws ec2 associate-route-table --route-table-id $DATA_RT --subnet-id $DATA_SUBNET_1A_ID
aws ec2 associate-route-table --route-table-id $DATA_RT --subnet-id $DATA_SUBNET_1B_ID
echo "VPC 部署完成!"
echo "VPC ID: $VPC_ID"
echo "Public Subnets: $PUBLIC_SUBNET_1A_ID, $PUBLIC_SUBNET_1B_ID"
echo "Private Subnets: $PRIVATE_SUBNET_1A_ID, $PRIVATE_SUBNET_1B_ID"
echo "Data Subnets: $DATA_SUBNET_1A_ID, $DATA_SUBNET_1B_ID"
總結
AWS VPC 的 Public 與 Private Subnet 設計是雲端架構安全性與可靠性的基石。正確理解與配置這兩種子網路,能有效:
- 🔒 提升安全性:透過網路隔離降低攻擊面,保護敏感資源
- 💰 優化成本:使用 VPC Endpoint 降低流量費用,合理配置 NAT Gateway
- ⚡ 確保效能:合理的網路架構設計避免不必要的跳轉與延遲
- ✅ 符合合規:滿足 GDPR、HIPAA、PCI-DSS 等法規要求
關鍵要點:
- ✅ Public Subnet 僅放置「必須對外」的資源(ALB、NAT Gateway、Bastion)
- ✅ Private Subnet 放置「不應對外」的敏感資源(RDS、App Server、Cache)
- ✅ 使用 NAT Gateway 而非 NAT Instance(除非成本極度敏感)
- ✅ 多可用區部署提升可用性(每個 AZ 獨立 NAT Gateway)
- ✅ 使用 VPC Endpoint 降低成本(S3、DynamoDB 免費,其他服務省流量費)
- ✅ 永遠不要將 RDS 放在 Public Subnet
- ✅ 使用 Security Group ID 而非 CIDR 定義規則(更易管理)
- ✅ 啟用 VPC Flow Logs 與 GuardDuty 監控安全威脅
透過本文的詳細說明、實戰案例與常見問題解答,您應該能夠設計與部署符合企業級標準的 AWS VPC 網路架構。記住:安全性設計應從網路層開始,Public 與 Private Subnet 的正確配置是雲端安全的第一道防線。