透過Terraform在AWS上運行NAT Gateway

Terraform AWS NAT Gateway

前言

在 AWS 雲端環境中,網路架構設計是基礎建設的核心。當我們需要保護後端服務(如資料庫、應用程式伺服器)免受外部直接存取時,通常會將這些資源部署在私有子網路(Private Subnet)中。然而,這些私有資源仍然需要存取網際網路來下載更新、存取外部 API 或進行其他對外通訊。

NAT Gateway(Network Address Translation Gateway) 正是解決這個問題的 AWS 託管服務。它允許私有子網路中的資源發起對外連線,同時阻止來自網際網路的主動連入請求,實現了安全與便利的平衡。

NAT Gateway 的核心功能

  1. 出站連線:允許私有子網路的執行個體存取網際網路
  2. 安全隔離:阻止網際網路主動發起的入站連線
  3. IP 位址轉換:將私有 IP 轉換為 Elastic IP 進行對外通訊
  4. 高可用性:AWS 託管服務,在單一可用區域內具備冗餘

適用場景

  • 私有子網路中的 EC2 需要下載系統更新或軟體套件
  • 後端應用程式需要呼叫外部第三方 API
  • 資料庫需要連線到外部資料來源進行同步
  • 容器服務需要從外部 Registry 拉取映像檔

網路架構圖

以下為本文實作的網路架構示意圖:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
                              ┌─────────────────────────────────────────────────────────┐
                              │                        Internet                          │
                              └─────────────────────────────────────────────────────────┘
                              ┌─────────────────────────────────────────────────────────┐
                              │                  Internet Gateway (IGW)                  │
                              └─────────────────────────────────────────────────────────┘
                    ┌───────────────────────────────────┴───────────────────────────────────┐
                    │                           VPC (10.0.0.0/16)                            │
                    │                                                                        │
                    │   ┌─────────────────────────────┐   ┌─────────────────────────────┐   │
                    │   │   Public Subnet             │   │   Private Subnet            │   │
                    │   │   10.0.1.0/24               │   │   10.0.2.0/24               │   │
                    │   │   us-west-2a                │   │   us-west-2a                │   │
                    │   │                             │   │                             │   │
                    │   │   ┌───────────────────┐     │   │   ┌───────────────────┐     │   │
                    │   │   │   EC2 (Public)    │     │   │   │   EC2 (Private)   │     │   │
                    │   │   │   Bastion Host    │     │   │   │   Application     │     │   │
                    │   │   └───────────────────┘     │   │   └───────────────────┘     │   │
                    │   │                             │   │            │                │   │
                    │   │   ┌───────────────────┐     │   │            │                │   │
                    │   │   │   NAT Gateway     │◄────┼───┼────────────┘                │   │
                    │   │   │   + Elastic IP    │     │   │   (透過 NAT GW 上網)        │   │
                    │   │   └───────────────────┘     │   │                             │   │
                    │   │            │                │   │                             │   │
                    │   └────────────┼────────────────┘   └─────────────────────────────┘   │
                    │                │                                                       │
                    │                ▼                                                       │
                    │   Route Table (Public):          Route Table (Private):               │
                    │   0.0.0.0/0 → IGW                0.0.0.0/0 → NAT Gateway              │
                    │                                                                        │
                    └────────────────────────────────────────────────────────────────────────┘

流量路徑說明

  1. Public Subnet 對外流量:EC2 → Route Table → Internet Gateway → Internet
  2. Private Subnet 對外流量:EC2 → Route Table → NAT Gateway → Internet Gateway → Internet
  3. 外部流量無法直接進入 Private Subnet,僅能透過回應封包返回

示意圖

建置環境

檔案結構

1
2
3
4
5
6
terraform-nat-gateway/
├── main.tf                 # 主要資源定義(VPC、EC2、Security Group)
├── internet-gateway.tf     # Public Subnet 相關設定
├── nat-gateway.tf          # Private Subnet 與 NAT Gateway 設定
├── variables.tf            # 變數定義(選用)
└── outputs.tf              # 輸出值定義(選用)

main.tf

此檔案定義了 VPC、安全群組和 EC2 執行個體等核心資源。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# AWS Provider 設定
# 指定要部署資源的 AWS 區域
provider "aws" {
  region = "us-west-2"
}

# VPC (Virtual Private Cloud)
# 建立一個隔離的虛擬網路環境,CIDR 區塊為 10.0.0.0/16
# 可容納 65,536 個 IP 位址
resource "aws_vpc" "vpc" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_hostnames = true  # 啟用 DNS 主機名稱
  enable_dns_support   = true  # 啟用 DNS 解析

  tags = {
    Name = "vpc"
  }
}

# Security Group(安全群組)
# 作為虛擬防火牆,控制進出流量
resource "aws_security_group" "sg" {
  name        = "sg"
  description = "Security group for EC2 instances"
  vpc_id      = aws_vpc.vpc.id

  # 入站規則:允許 SSH 連線(建議在生產環境限制來源 IP)
  ingress {
    description = "SSH access"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]  # 生產環境建議改為特定 IP
  }

  # 出站規則:允許所有對外連線
  egress {
    description = "Allow all outbound traffic"
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "sg"
  }
}

# Public EC2 Instance(公有子網路中的 EC2)
# 作為 Bastion Host,可從外部 SSH 連入
resource "aws_instance" "ec2" {
  ami                    = "ami-0747e613a2a1ff483"
  instance_type          = "t2.micro"
  key_name               = "demo-key-us-west-2"
  subnet_id              = aws_subnet.subnet.id
  vpc_security_group_ids = [aws_security_group.sg.id]

  tags = {
    Name = "ec2"
  }
}

# Private EC2 Instance(私有子網路中的 EC2)
# 無法從外部直接存取,但可透過 NAT Gateway 上網
resource "aws_instance" "ec2-private" {
  ami                    = "ami-0747e613a2a1ff483"
  instance_type          = "t2.micro"
  key_name               = "demo-key-us-west-2"
  subnet_id              = aws_subnet.subnet-private.id
  vpc_security_group_ids = [aws_security_group.sg.id]

  tags = {
    Name = "ec2-private"
  }
}

internet-gateway.tf

這邊主要放與 public subnet 有關的設定,包含 Internet Gateway 和公有路由表。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# Public Subnet(公有子網路)
# 此子網路中的資源可直接存取網際網路
resource "aws_subnet" "subnet" {
  vpc_id                  = aws_vpc.vpc.id
  cidr_block              = "10.0.1.0/24"           # 可容納 256 個 IP
  availability_zone       = "us-west-2a"
  map_public_ip_on_launch = true                     # 自動分配公有 IP

  tags = {
    Name = "subnet"
  }
}

# 公有子網路路由表關聯
# 將公有子網路與公有路由表綁定
resource "aws_route_table_association" "rta" {
  subnet_id      = aws_subnet.subnet.id
  route_table_id = aws_route_table.rt.id
}

# 公有路由表
# 定義公有子網路的路由規則
resource "aws_route_table" "rt" {
  vpc_id = aws_vpc.vpc.id

  # 預設路由:所有對外流量導向 Internet Gateway
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.igw.id
  }

  tags = {
    Name = "rt"
  }
}

# Internet Gateway
# VPC 與網際網路之間的閘道,提供雙向連線能力
resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.vpc.id

  tags = {
    Name = "igw"
  }
}

nat-gateway.tf

這邊主要放與 private subnet 有關的設定,包含 NAT Gateway 和私有路由表。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# Private Subnet(私有子網路)
# 此子網路中的資源無法從外部直接存取
resource "aws_subnet" "subnet-private" {
  vpc_id            = aws_vpc.vpc.id
  cidr_block        = "10.0.2.0/24"           # 可容納 256 個 IP
  availability_zone = "us-west-2a"
  # 注意:不設定 map_public_ip_on_launch,保持私有

  tags = {
    Name = "subnet-private"
  }
}

# 私有子網路路由表關聯
resource "aws_route_table_association" "rta-private" {
  subnet_id      = aws_subnet.subnet-private.id
  route_table_id = aws_route_table.rt-private.id
}

# 私有路由表
# 將所有對外流量導向 NAT Gateway
resource "aws_route_table" "rt-private" {
  vpc_id = aws_vpc.vpc.id

  route {
    cidr_block     = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.ngw.id  # 注意:使用 nat_gateway_id 而非 gateway_id
  }

  tags = {
    Name = "rt-private"
  }
}

# NAT Gateway
# 部署在公有子網路中,允許私有子網路的資源存取網際網路
resource "aws_nat_gateway" "ngw" {
  allocation_id = aws_eip.eip.id        # 關聯 Elastic IP
  subnet_id     = aws_subnet.subnet.id  # 部署在公有子網路

  tags = {
    Name = "ngw"
  }

  # 確保 Internet Gateway 先建立完成
  # NAT Gateway 需要透過 IGW 連線到網際網路
  depends_on = [aws_internet_gateway.igw]
}

# Elastic IP
# NAT Gateway 必須使用 Elastic IP 進行對外通訊
resource "aws_eip" "eip" {
  domain = "vpc"  # 新版 Terraform 語法,舊版使用 vpc = true

  tags = {
    Name = "eip"
  }
}

測試

public subnet 中的 ec2 可正常連網

利用預設路由(也就是 vpc 被建立時就被建立的路由)來透過 public subnet 中的 ec2 連線在 private subnet 中的 ec2,經測試發現該 ec2 可正常連網

透過指令 traceroute 可發現路由透過 NAT Gateway 到 public subnet 後,再利用 Internet Gateway 上網

驗證連線指令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 在 Private EC2 上測試網際網路連線
ping -c 4 8.8.8.8

# 測試 DNS 解析
nslookup google.com

# 追蹤路由路徑
traceroute 8.8.8.8

# 測試 HTTP 連線
curl -I https://aws.amazon.com

高可用性設計(Multi-AZ)

單一 NAT Gateway 部署在單一可用區域,若該區域發生故障,私有子網路將失去對外連線能力。對於生產環境,建議採用多可用區域架構。

多 AZ NAT Gateway 架構

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
                                    Internet
                              ┌─────────┴─────────┐
                              │  Internet Gateway │
                              └─────────┬─────────┘
        ┌───────────────────────────────┴───────────────────────────────┐
        │                         VPC (10.0.0.0/16)                      │
        │                                                                │
        │  ┌────────────────────────┐    ┌────────────────────────┐     │
        │  │     us-west-2a         │    │     us-west-2b         │     │
        │  │                        │    │                        │     │
        │  │  Public: 10.0.1.0/24   │    │  Public: 10.0.3.0/24   │     │
        │  │  ┌──────────────────┐  │    │  ┌──────────────────┐  │     │
        │  │  │  NAT Gateway A   │  │    │  │  NAT Gateway B   │  │     │
        │  │  └──────────────────┘  │    │  └──────────────────┘  │     │
        │  │           ▲            │    │           ▲            │     │
        │  │           │            │    │           │            │     │
        │  │  Private: 10.0.2.0/24  │    │  Private: 10.0.4.0/24  │     │
        │  │  ┌──────────────────┐  │    │  ┌──────────────────┐  │     │
        │  │  │   EC2 App A      │  │    │  │   EC2 App B      │  │     │
        │  │  └──────────────────┘  │    │  └──────────────────┘  │     │
        │  │                        │    │                        │     │
        │  └────────────────────────┘    └────────────────────────┘     │
        │                                                                │
        └────────────────────────────────────────────────────────────────┘

多 AZ Terraform 配置範例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# 定義可用區域
variable "availability_zones" {
  default = ["us-west-2a", "us-west-2b"]
}

# 為每個 AZ 建立 Public Subnet
resource "aws_subnet" "public" {
  count                   = length(var.availability_zones)
  vpc_id                  = aws_vpc.vpc.id
  cidr_block              = "10.0.${count.index * 2 + 1}.0/24"
  availability_zone       = var.availability_zones[count.index]
  map_public_ip_on_launch = true

  tags = {
    Name = "public-subnet-${var.availability_zones[count.index]}"
  }
}

# 為每個 AZ 建立 Private Subnet
resource "aws_subnet" "private" {
  count             = length(var.availability_zones)
  vpc_id            = aws_vpc.vpc.id
  cidr_block        = "10.0.${count.index * 2 + 2}.0/24"
  availability_zone = var.availability_zones[count.index]

  tags = {
    Name = "private-subnet-${var.availability_zones[count.index]}"
  }
}

# 為每個 AZ 建立 Elastic IP
resource "aws_eip" "nat" {
  count  = length(var.availability_zones)
  domain = "vpc"

  tags = {
    Name = "eip-nat-${var.availability_zones[count.index]}"
  }
}

# 為每個 AZ 建立 NAT Gateway
resource "aws_nat_gateway" "nat" {
  count         = length(var.availability_zones)
  allocation_id = aws_eip.nat[count.index].id
  subnet_id     = aws_subnet.public[count.index].id

  tags = {
    Name = "nat-gateway-${var.availability_zones[count.index]}"
  }

  depends_on = [aws_internet_gateway.igw]
}

# 為每個 Private Subnet 建立獨立路由表
resource "aws_route_table" "private" {
  count  = length(var.availability_zones)
  vpc_id = aws_vpc.vpc.id

  route {
    cidr_block     = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.nat[count.index].id
  }

  tags = {
    Name = "rt-private-${var.availability_zones[count.index]}"
  }
}

# 關聯路由表
resource "aws_route_table_association" "private" {
  count          = length(var.availability_zones)
  subnet_id      = aws_subnet.private[count.index].id
  route_table_id = aws_route_table.private[count.index].id
}

成本考量與優化建議

NAT Gateway 的費用是 AWS VPC 中較昂貴的項目之一,了解計費方式有助於成本優化。

NAT Gateway 計費項目

項目費用(以 us-west-2 為例)
每小時使用費$0.045 USD/小時
資料處理費$0.045 USD/GB
跨 AZ 資料傳輸$0.01 USD/GB

月費預估範例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
假設條件:
- 1 個 NAT Gateway 運行 24/7
- 每月處理 100 GB 對外流量

月費計算:
- 使用費:$0.045 × 24 × 30 = $32.40
- 資料處理:$0.045 × 100 = $4.50
- 總計:$36.90/月

多 AZ(2 個 NAT Gateway):
- 總計:$73.80/月

成本優化策略

1. 使用 VPC Endpoints 減少 NAT 流量

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# S3 Gateway Endpoint(免費)
resource "aws_vpc_endpoint" "s3" {
  vpc_id       = aws_vpc.vpc.id
  service_name = "com.amazonaws.us-west-2.s3"

  route_table_ids = [aws_route_table.rt-private.id]

  tags = {
    Name = "s3-endpoint"
  }
}

# DynamoDB Gateway Endpoint(免費)
resource "aws_vpc_endpoint" "dynamodb" {
  vpc_id       = aws_vpc.vpc.id
  service_name = "com.amazonaws.us-west-2.dynamodb"

  route_table_ids = [aws_route_table.rt-private.id]

  tags = {
    Name = "dynamodb-endpoint"
  }
}

# ECR API Interface Endpoint
resource "aws_vpc_endpoint" "ecr_api" {
  vpc_id              = aws_vpc.vpc.id
  service_name        = "com.amazonaws.us-west-2.ecr.api"
  vpc_endpoint_type   = "Interface"
  subnet_ids          = [aws_subnet.subnet-private.id]
  security_group_ids  = [aws_security_group.endpoint_sg.id]
  private_dns_enabled = true

  tags = {
    Name = "ecr-api-endpoint"
  }
}

2. 開發/測試環境使用單一 NAT Gateway

對於非生產環境,可使用單一 NAT Gateway 並讓多個 Private Subnet 共用:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 所有 Private Subnet 共用同一個 NAT Gateway
resource "aws_route_table" "private_shared" {
  vpc_id = aws_vpc.vpc.id

  route {
    cidr_block     = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.ngw.id  # 單一 NAT Gateway
  }

  tags = {
    Name = "rt-private-shared"
  }
}

3. 非上班時間關閉 NAT Gateway(適用開發環境)

使用 Lambda 或 EventBridge 排程自動化管理:

1
2
# 使用 Terraform 的 lifecycle 搭配外部自動化
# 可透過 Lambda 在非工作時間刪除 NAT Gateway 和 EIP

NAT Gateway vs NAT Instance 比較

特性NAT GatewayNAT Instance
管理方式AWS 託管服務自行管理 EC2
可用性區域內高可用(自動冗餘)需自行設定
頻寬最高 100 Gbps依執行個體類型而定
維護AWS 負責修補更新自行負責
成本每小時 + 資料處理費EC2 執行個體費用
安全群組不可關聯可關聯
網路 ACL支援支援
Bastion Host不支援可兼任
Port Forwarding不支援支援
流量監控基本指標完整可自訂

建議使用場景

選擇 NAT Gateway:

  • 生產環境需要高可用性
  • 預期流量較大且穩定
  • 希望減少維運負擔
  • 需要更高的網路頻寬

選擇 NAT Instance:

  • 開發/測試環境成本考量
  • 需要 Port Forwarding 功能
  • 需要更細緻的流量控制
  • 低流量場景(t3.nano 成本較低)

NAT Instance 快速建置範例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 使用 AWS 官方 NAT AMI
data "aws_ami" "nat_ami" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["amzn-ami-vpc-nat-*"]
  }
}

resource "aws_instance" "nat_instance" {
  ami                    = data.aws_ami.nat_ami.id
  instance_type          = "t3.nano"
  subnet_id              = aws_subnet.subnet.id
  vpc_security_group_ids = [aws_security_group.nat_sg.id]
  source_dest_check      = false  # 重要:必須關閉

  tags = {
    Name = "nat-instance"
  }
}

resource "aws_security_group" "nat_sg" {
  name   = "nat-instance-sg"
  vpc_id = aws_vpc.vpc.id

  ingress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["10.0.0.0/16"]  # 僅允許 VPC 內部流量
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

故障排除指南

常見問題與解決方案

1. Private Subnet 無法連線網際網路

檢查清單:

1
2
3
4
5
6
7
8
# 確認路由表設定
aws ec2 describe-route-tables --filters "Name=association.subnet-id,Values=<subnet-id>"

# 確認 NAT Gateway 狀態
aws ec2 describe-nat-gateways --nat-gateway-ids <nat-gateway-id>

# 確認 Security Group 出站規則
aws ec2 describe-security-groups --group-ids <sg-id>

常見原因:

  • 路由表未正確關聯到 Private Subnet
  • NAT Gateway 狀態不是 available
  • Security Group 出站規則限制
  • Network ACL 阻擋流量

2. NAT Gateway 狀態為 Failed

可能原因:

  • Elastic IP 已被其他資源使用
  • 公有子網路沒有正確設定路由到 Internet Gateway
  • 資源配額不足

解決方案:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 確保 EIP 在 VPC 範圍內
resource "aws_eip" "eip" {
  domain = "vpc"

  # 避免 EIP 被其他資源佔用
  tags = {
    Name        = "eip-nat"
    Environment = "production"
  }
}

# 確保依賴關係正確
resource "aws_nat_gateway" "ngw" {
  allocation_id = aws_eip.eip.id
  subnet_id     = aws_subnet.subnet.id

  depends_on = [aws_internet_gateway.igw]

  lifecycle {
    create_before_destroy = true
  }
}

3. 連線速度緩慢

檢查項目:

  • CloudWatch 監控 NAT Gateway 指標
  • 確認是否達到頻寬上限
  • 檢查是否有跨 AZ 流量
1
2
3
4
5
6
7
8
9
# 查看 NAT Gateway 指標
aws cloudwatch get-metric-statistics \
  --namespace AWS/NATGateway \
  --metric-name BytesOutToDestination \
  --dimensions Name=NatGatewayId,Value=<nat-gateway-id> \
  --start-time 2023-05-01T00:00:00Z \
  --end-time 2023-05-02T00:00:00Z \
  --period 3600 \
  --statistics Sum

4. Terraform Apply 失敗

常見錯誤與解決:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 錯誤:InvalidAllocationID.NotFound
# 原因:EIP 尚未建立或已被刪除
# 解決:確保 depends_on 設定正確

resource "aws_nat_gateway" "ngw" {
  allocation_id = aws_eip.eip.id
  subnet_id     = aws_subnet.subnet.id

  depends_on = [
    aws_internet_gateway.igw,
    aws_eip.eip
  ]
}

# 錯誤:Resource limit exceeded
# 解決:檢查 AWS 配額限制
# 預設每個 AZ 5 個 NAT Gateway

監控與警示設定

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# CloudWatch 警示:NAT Gateway 錯誤封包
resource "aws_cloudwatch_metric_alarm" "nat_error_packets" {
  alarm_name          = "nat-gateway-error-packets"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = "2"
  metric_name         = "ErrorPortAllocation"
  namespace           = "AWS/NATGateway"
  period              = "300"
  statistic           = "Sum"
  threshold           = "0"
  alarm_description   = "NAT Gateway port allocation errors"

  dimensions = {
    NatGatewayId = aws_nat_gateway.ngw.id
  }
}

# CloudWatch 警示:高流量警示
resource "aws_cloudwatch_metric_alarm" "nat_high_traffic" {
  alarm_name          = "nat-gateway-high-traffic"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = "3"
  metric_name         = "BytesOutToDestination"
  namespace           = "AWS/NATGateway"
  period              = "300"
  statistic           = "Sum"
  threshold           = "1073741824"  # 1 GB
  alarm_description   = "NAT Gateway traffic exceeds 1 GB in 5 minutes"

  dimensions = {
    NatGatewayId = aws_nat_gateway.ngw.id
  }
}

後記

aws_eip

本次再建立時 NAT Gateway 關鍵在於要自己建立 Elastic IP 給 NAT Gateway,沒辦法透過 public subnetmap_public_ip_on_launch 設定來自動賦予。

注意: 在較新版本的 Terraform AWS Provider(4.0+)中,aws_eipvpc = true 參數已被棄用,應改用 domain = "vpc"

上傳 key 到 ec2

參考 透過 terraform 在 aws 上運行公私有網路 後記:上傳 key 到 ec2

最佳實務總結

  1. 生產環境:每個 AZ 部署獨立的 NAT Gateway
  2. 成本優化:善用 VPC Endpoints 減少 NAT 流量
  3. 監控:設定 CloudWatch 警示監控 NAT Gateway 狀態
  4. 安全:使用 Network ACL 限制 Private Subnet 的流量
  5. 標籤管理:為所有資源添加適當的標籤便於成本追蹤

參考資源

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy