NATゲートウェイ、VPCエンドポイント、インターネットゲートウェイ周りについて [ 備忘録 ]

## インターネットゲートウェイ（IGW）

インターネットゲートウェイは、VPCとインターネット間の通信を可能にするコンポーネントです。

**特徴：**
- VPCごとに1つのIGWを接続可能
- パブリックIPアドレスを持つリソースに対してインターネットアクセスを提供
- 双方向通信をサポート（インバウンド・アウトバウンド）

**使用場面：**
- Webサーバーなど、インターネットからアクセス可能にしたいリソース
- パブリックサブネット内のEC2インスタンスのインターネット接続

## NATゲートウェイ

Network Address Translation（NAT）ゲートウェイは、プライベートサブネット内のリソースにアウトバウンドインターネット接続を提供します。

**特徴：**
- プライベートサブネットのリソースからインターネットへの一方向通信
- インバウンド接続は受け付けない（セキュリティが高い）
- 時間とデータ転送量による課金

**使用場面：**
- 外部APIへのアクセス

## VPCエンドポイント

VPCエンドポイントは、インターネットを経由せずにAWSサービスにプライベート接続する仕組みです。あなたのVPCを「プライベートな住宅街」、AWSサービスを「大きなショッピングモール」に例えると、VPCエンドポイントは「専用の地下通路」のような役割を果たします。

**2つの種類があります：**

**ゲートウェイエンドポイント（特別な専用通路）：**
- **利用可能サービス：** S3とDynamoDBのみ
- **料金：** 完全無料
- **仕組み：** ルートテーブルに自動的にルートが追加される
- **設置場所：** VPCレベル（特定のサブネットに縛られない）

**インターフェースエンドポイント（プライベートな入口）：**
- **利用可能サービス：** ECR、Lambda、SNS、SQS、CloudWatch、Systems Managerなど200以上のAWSサービス
- **料金：** 約月額9ドル/AZ + データ転送料
- **仕組み：** サブネット内にENI（仮想ネットワークカード）を作成
- **設置場所：** 指定したサブネット内（通常はプライベートサブネット）

**ECRなどへの接続例：**
ECRからコンテナイメージをプルする場合、以下のエンドポイントが必要：

**必須のエンドポイント：**
```
1. com.amazonaws.ap-northeast-1.ecr.dkr (ECRデータ/Docker API)
2. com.amazonaws.ap-northeast-1.s3 (S3ゲートウェイエンドポイント)
```

**オプション（API操作が必要な場合）：**
```
3. com.amazonaws.ap-northeast-1.ecr.api (ECR API)
```

**ECR APIエンドポイントが必要なケース：**

**基本的な管理操作：**
- リポジトリの作成・削除（CreateRepository、DeleteRepository）
- リポジトリ一覧の取得（DescribeRepositories）
- イメージ一覧の表示（DescribeImages）
- ライフサイクルポリシーの設定

**認証関連：**
- `aws ecr get-login-password`コマンド（GetAuthorizationToken）
- Dockerクライアントでのログイン処理

**CI/CDパイプラインでの利用：**
- 自動デプロイメント時のリポジトリ存在確認
- イメージタグの一覧取得や管理
- ビルドパイプラインでの動的リポジトリ作成

**単純なpull/push操作のみの場合：**
- ECS Fargate（Linux platform version 1.3.0以前）のようにコンテナ実行のみが目的
- 既存のリポジトリから既知のイメージをpullするだけ
- 事前に認証済み（ログイン済み）の環境

→ この場合は**ECR DKR + S3ゲートウェイエンドポイントのみで十分**

**重要なポイント：**
- ECRはS3を使ってイメージレイヤーを保存しているため、**S3ゲートウェイエンドポイントは必須**
- Amazon ECS Fargate（Linux platform version 1.3.0以前）では、ECR DKRエンドポイントとS3ゲートウェイエンドポイントのみで十分
- インターフェースエンドポイント（ECR DKR/API）は各AZのプライベートサブネットに配置し、**ルートテーブルの変更は不要**でDNSによって自動的にプライベートIP（ENI）に解決される

**VPCエンドポイントのメリット：**
- **セキュリティ向上：** トラフィックがインターネットを経由せずAWSネットワーク内のみを通る
- **レイテンシ削減：** より短い経路での通信が可能
- **コスト削減：** 特にゲートウェイエンドポイントは無料、データ転送料も削減される場合がある

**レイテンシとは：**
ネットワーク通信における「遅延時間」のことです。データが送信されてから相手に届くまでの時間を指します。インターネット経由よりもAWS内部ネットワーク経由の方が、物理的な距離が短く経由するルーターも少ないため、レイテンシが小さく（つまり高速）なります。

# サブネットタイプと配置パターン

## パブリックサブネット

**定義：** インターネットゲートウェイへのルートを持つサブネット

**特徴：**
- パブリックIPアドレスを持つリソースがインターネットと直接通信可能
- Webサーバー、ロードバランサーなどを配置
- インバウンド・アウトバウンド両方向の通信をサポート

**典型的なルートテーブル設定：**
```
送信先              ターゲット
10.0.0.0/16        local
0.0.0.0/0          igw-xxxxxxxxx
```

## プライベートサブネット

**定義：** インターネットゲートウェイへの直接ルートを持たないサブネット

**特徴：**
- 外部からの直接アクセス不可
- データベース、アプリケーションサーバーなどを配置
- インターネットアクセスが必要な場合はNATゲートウェイ経由

**典型的なルートテーブル設定：**
```
送信先              ターゲット
10.0.0.0/16        local
0.0.0.0/0          nat-xxxxxxxxx
```

# 構成パターン別の動作解説

## パターン1：VPCエンドポイントなし・NATゲートウェイあり

**構成：**
- プライベートサブネット内のEC2インスタンス
- NATゲートウェイ経由でインターネット接続
- S3やその他AWSサービスへもインターネット経由でアクセス

**動作：**
1. EC2インスタンスがS3にアクセス
2. トラフィックはNATゲートウェイ経由でインターネットへ
3. パブリックなS3エンドポイントに接続
4. インターネット経由でレスポンスを受信

**メリット・デメリット：**
- メリット：シンプルな構成
- デメリット：データ転送コスト高、レイテンシ大、セキュリティリスク

## パターン2：VPCエンドポイントあり・NATゲートウェイなし

**構成：**
- **プライベートサブネット**内のEC2インスタンス
- S3用ゲートウェイエンドポイント設置
- 他のAWSサービス用インターフェースエンドポイント設置

**プライベートサブネットのルートテーブル設定：**
```
送信先                    ターゲット
10.0.0.0/16              local
pl-12345678 (S3)         vpce-xxxxxxxxx (ゲートウェイEP)
pl-87654321 (DynamoDB)   vpce-yyyyyyyyy (ゲートウェイEP)
```
*注：インターフェースエンドポイントは自動的にDNS解決されるためルート追加不要*

**動作：**
1. EC2インスタンスがS3にアクセス
2. ルートテーブルの設定によりゲートウェイエンドポイント経由
3. AWSネットワーク内でS3に直接接続
4. インターネットを経由しない

**メリット・デメリット：**
- メリット：セキュリティ向上、コスト削減、低レイテンシ
- デメリット：一般的なインターネットアクセス不可、複雑な設定

## パターン3：VPCエンドポイント・NATゲートウェイ両方あり

**構成：**
- **プライベートサブネット**内のEC2インスタンス
- AWSサービス用VPCエンドポイント
- 一般的なインターネットアクセス用NATゲートウェイ

**プライベートサブネットのルートテーブル設定：**
```
送信先                    ターゲット
10.0.0.0/16              local
pl-12345678 (S3)         vpce-xxxxxxxxx (ゲートウェイEP)
pl-87654321 (DynamoDB)   vpce-yyyyyyyyy (ゲートウェイEP)
0.0.0.0/0                nat-zzzzzzzzz (NATゲートウェイ)
```
*注：より具体的なルート（プレフィックスリスト）が優先されるため、S3/DynamoDBはVPCエンドポイント経由、その他はNAT経由*

**動作：**
1. AWSサービス（S3、DynamoDB等）：VPCエンドポイント経由
2. 外部API、ソフトウェア更新等：NATゲートウェイ経由
3. ルートテーブルの設定により自動的に最適経路を選択

**メリット・デメリット：**
- メリット：最高のセキュリティとフレキシビリティ
- デメリット：コスト高、設定の複雑さ

# ルートテーブルとセキュリティグループの違い

## ルートテーブル

**役割：** ネットワークトラフィックの経路制御

**特徴：**
- サブネットレベルでの制御
- 送信先IPアドレス範囲とターゲットの組み合わせ
- Layer 3（ネットワーク層）での動作
- 許可ルールのみ（明示的な拒否なし）

**設定例：**
```
送信先              ターゲット          優先度
10.0.0.0/16        local              最高
172.16.0.0/16      pcx-xxxxxxxxx      中
192.168.1.0/24     vgw-xxxxxxxxx      中
0.0.0.0/0          igw-xxxxxxxxx      最低
```

**制御内容：**
- どの送信先にどの経路でトラフィックを送るか
- VPCエンドポイント、NATゲートウェイ、IGWの使い分け
- 異なるネットワーク間の接続制御

## セキュリティグループ

**役割：** インスタンスレベルでのファイアウォール機能

**特徴：**
- インスタンスレベルでの制御
- ポート、プロトコル、送信元/送信先の組み合わせ
- Layer 4（トランスポート層）での動作
- ステートフル（戻りトラフィックを自動許可）

**設定例：**
```
インバウンドルール：
タイプ      ポート    送信元
HTTP        80       0.0.0.0/0
HTTPS       443      0.0.0.0/0
SSH         22       203.0.113.0/24

アウトバウンドルール：
タイプ      ポート    送信先
All         All      0.0.0.0/0
```

**制御内容：**
- どのポートへのアクセスを許可するか
- どのIPアドレスからのアクセスを許可するか
- アプリケーションレベルでのセキュリティ制御

### 重要な違いまとめ

| 項目 | ルートテーブル | セキュリティグループ |
|------|----------------|----------------------|
| 制御レベル | サブネット | インスタンス |
| 動作レイヤー | Layer 3 | Layer 4 |
| ルールタイプ | 許可のみ | 許可のみ（デフォルト拒否） |
| ステート | ステートレス | ステートフル |
| 主な用途 | 経路制御 | アクセス制御 |

## 実装のベストプラクティス

### セキュリティ重視の設計

1. **最小権限の原則**
   - 必要最小限のポートのみ開放
   - 送信元IPアドレスの適切な制限
   - 不要なインターネット接続の排除

2. **多層防御**
   - ルートテーブルとセキュリティグループの組み合わせ
   - NACLsの追加的な活用
   - VPCエンドポイントによるトラフィック隔離

### コスト最適化

1. **VPCエンドポイントの活用**
   - 頻繁にアクセスするAWSサービスにはゲートウェイエンドポイント
   - データ転送量の多いサービスには特に効果的

2. **NATゲートウェイの最適化**
   - 複数のAZで冗長化しつつ、使用量を最小化
   - インスタンスタイプの適切な選択

### 運用・監視

1. **ログとモニタリング**
   - VPCフローログの有効化
   - CloudWatchメトリクスの監視
   - 異常なトラフィックパターンの検出

2. **定期的な見直し**
   - セキュリティグループルールの棚卸し
   - 不要なルートの削除
   - コスト分析とリソース最適化

## まとめ

**重要なポイント：**

- **インターネットゲートウェイ**：パブリックリソースのインターネット接続
- **NATゲートウェイ**：プライベートリソースのアウトバウンド接続
- **VPCエンドポイント**：AWSサービスへのプライベート接続
- **ルートテーブル**：ネットワークトラフィックの経路制御
- **セキュリティグループ**：インスタンスレベルのアクセス制御

---

# 参考

## インターフェースエンドポイント (VPCエンドポイント)の紐付きをTerraformで理解する

```
# ECR DKR用インターフェースエンドポイント
resource "aws_vpc_endpoint" "ecr_dkr" {
  vpc_id              = var.vpc_id
  service_name        = "com.amazonaws.${var.region}.ecr.dkr"
  vpc_endpoint_type   = "Interface"
  subnet_ids          = var.private_subnet_ids  # プライベートサブネット指定
  security_group_ids  = [aws_security_group.vpc_endpoint_sg.id]
  
  # プライベートDNSを有効化（重要！）
  private_dns_enabled = true
  
  # ポリシー（オプション）
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Principal = "*"
        Action = [
          "ecr:BatchGetImage",
          "ecr:GetDownloadUrlForLayer"
        ]
        Resource = "*"
      }
    ]
  })

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

# ECR API用インターフェースエンドポイント
resource "aws_vpc_endpoint" "ecr_api" {
  vpc_id              = var.vpc_id
  service_name        = "com.amazonaws.${var.region}.ecr.api"
  vpc_endpoint_type   = "Interface"
  subnet_ids          = var.private_subnet_ids
  security_group_ids  = [aws_security_group.vpc_endpoint_sg.id]
  private_dns_enabled = true

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

# S3用ゲートウェイエンドポイント（比較用）
resource "aws_vpc_endpoint" "s3_gateway" {
  vpc_id            = var.vpc_id
  service_name      = "com.amazonaws.${var.region}.s3"
  vpc_endpoint_type = "Gateway"
  route_table_ids   = var.private_route_table_ids  # ルートテーブル指定

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

# VPCエンドポイント用セキュリティグループ
resource "aws_security_group" "vpc_endpoint_sg" {
  name_prefix = "vpc-endpoint-sg"
  vpc_id      = var.vpc_id

  # インバウンド：VPCエンドポイントのENI「への」通信を許可
  # 
  # 通信の流れ：
  # EC2インスタンス(10.0.2.100) → VPCエンドポイントENI(10.0.1.50:443)
  #    送信元                        受信先
  # 
  # この設定は「VPCエンドポイントのENIが、VPC内のリソースからの
  # ポート443への接続を受け入れる」ことを許可している
  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = [var.vpc_cidr]  # VPC内の全IPアドレス範囲から
    description = "Allow HTTPS from VPC resources to VPC Endpoint ENI"
  }

  # アウトバウンド：VPCエンドポイントのENI「からの」通信を許可
  # 
  # 通信の流れ：
  # VPCエンドポイントENI(10.0.1.50) → AWSサービス（プライベート接続）
  #       送信元                        受信先
  # 
  # VPCエンドポイントがAWSサービスと通信するために必要
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
    description = "Allow all outbound from VPC Endpoint ENI to AWS services"
  }

  tags = {
    Name = "vpc-endpoint-security-group"
  }
}

# 変数定義
variable "vpc_id" {
  description = "VPC ID"
  type        = string
}

variable "region" {
  description = "AWS Region"
  type        = string
  default     = "ap-northeast-1"
}

variable "private_subnet_ids" {
  description = "プライベートサブネットIDのリスト"
  type        = list(string)
}

variable "private_route_table_ids" {
  description = "プライベートサブネットのルートテーブルIDのリスト"  
  type        = list(string)
}

variable "vpc_cidr" {
  description = "VPCのCIDR範囲"
  type        = string
  default     = "10.0.0.0/16"
}

# アウトプット（作成されたリソース情報）
output "ecr_dkr_endpoint_id" {
  value = aws_vpc_endpoint.ecr_dkr.id
}

output "ecr_dkr_endpoint_dns_names" {
  value = aws_vpc_endpoint.ecr_dkr.dns_entry
}

output "ecr_api_endpoint_id" {
  value = aws_vpc_endpoint.ecr_api.id
}

output "s3_gateway_endpoint_id" {
  value = aws_vpc_endpoint.s3_gateway.id
}
```

# VPCエンドポイント重要な紐づきポイント

## 1. **サブネットとの紐づき**

```hcl
subnet_ids = var.private_subnet_ids
```

- **インターフェースエンドポイント**：指定したサブネット内にENI（仮想ネットワークカード）を作成
- **ゲートウェイエンドポイント**：ルートテーブルにルートを追加

## 2. **セキュリティグループとの紐づき**

```hcl
security_group_ids = [aws_security_group.vpc_endpoint_sg.id]
```

- インターフェースエンドポイントのENIに適用
- **必須要件**：ポート443（HTTPS）でのVPC内からのアクセスを許可

**通信の向き：**
```
EC2インスタンス(10.0.2.100) ──→ VPCエンドポイントENI(10.0.1.50:443)
     送信元                          受信先（インバウンド許可が必要）

VPCエンドポイントENI(10.0.1.50) ──→ AWSサービス（ECR本体）
        送信元                          受信先（アウトバウンド許可が必要）
```

## 3. **DNS解決の仕組み**

```hcl
private_dns_enabled = true
```

**プライベートDNS解決の通信方向：**

### DNS解決（名前解決）
```
EC2インスタンス ──→ Route53 DNSリゾルバー ──→ プライベートDNS応答
                ↑ DNS クエリー              ↓ IP アドレス応答
```

### 実際の通信フロー
```
1. DNS解決段階：
   EC2インスタンス → DNS問い合わせ → "123456789.dkr.ecr.ap-northeast-1.amazonaws.com は何？"
   DNS応答 ← "10.0.1.100 だよ" ← Route53

2. 実際の通信段階：
   EC2インスタンス → 10.0.1.100（ENIのプライベートIP） → AWSサービス
```

この設定により：
- `123456789.dkr.ecr.ap-northeast-1.amazonaws.com`
- ↓ DNS解決
- `10.0.1.100`（ENIのプライベートIP）

**重要：** `private_dns_enabled = true` により、パブリックなAWSサービス名（例：`*.ecr.amazonaws.com`）を **VPC内からのDNS問い合わせ時のみ** プライベートIPに自動変換します。VPC外からの問い合わせでは通常のパブリックIPが返されます。

## 4. **ゲートウェイエンドポイントとの違い**

### インターフェースエンドポイント：
- `subnet_ids` 指定 → ENI作成
- `security_group_ids` 必要
- `private_dns_enabled = true` で自動DNS解決

### ゲートウェイエンドポイント：
- `route_table_ids` 指定 → ルート追加
- セキュリティグループ不要
- プレフィックスリスト経由

## 5. **実際の動作フロー**

### 作成時
1. **作成時**：指定サブネットにENIが作成される

### アクセス時
2. **アクセス時**：
```bash
docker pull 123456789.dkr.ecr.ap-northeast-1.amazonaws.com/my-app:latest
```

3. **DNS解決**：エンドポイントのプライベートIPに自動解決
4. **通信**：VPC内でプライベート通信

### 詳細な通信フロー
```
1. Dockerクライアント → DNS問い合わせ
2. Route53 → プライベートIP応答（10.0.1.100）
3. Dockerクライアント → VPCエンドポイントENI（10.0.1.100:443）
4. VPCエンドポイントENI → AWSネットワーク経由でECRサービス
5. ECRサービス → レスポンス → VPCエンドポイントENI → Dockerクライアント
```

## まとめ

**サブネット指定でENI作成 + DNS自動解決** により、透過的なプライベート接続が実現されます。

**キーポイント：**
- **DNS解決**：EC2 → Route53（VPC内DNS） → プライベートIP応答
- **実際の通信**：EC2 → ENI → AWSサービス
- **セキュリティ**：ENIへのインバウンド443番ポート許可が必須

---

## OSI参照モデルとは

OSI参照モデルは、ネットワーク通信を7つの層に分けて整理したモデルです。下から順に：

```
Layer 7: アプリケーション層    (HTTP, HTTPS, FTP, SMTP)
Layer 6: プレゼンテーション層  (暗号化, 圧縮)
Layer 5: セッション層         (セッション管理)
Layer 4: トランスポート層     (TCP, UDP) ← 今回の焦点
Layer 3: ネットワーク層       (IP) ← 今回の焦点
Layer 2: データリンク層       (Ethernet, WiFi)
Layer 1: 物理層              (ケーブル, 電波)
```

## Layer 3（ネットワーク層）とは

### 役割
**「どのネットワークのどのホストに送るか」**を決める層

### 主要なプロトコル
- **IP（Internet Protocol）**
- IPアドレスによる宛先識別

### 具体的な動作
```
送信者: 192.168.1.100
受信者: 10.0.2.50

Layer 3での処理:
"192.168.1.100 から 10.0.2.50 にパケットを送る"
```

### 制御内容
- **IPアドレス**による宛先指定
- **ルーティング**（どの経路で送るか）
- **パケットの分割・再組み立て**

### 実例：ルートテーブル
```
送信先              ターゲット           意味
10.0.0.0/16        local               「10.0.x.x宛てはローカルVPC内」
0.0.0.0/0          igw-xxxxxxxxx       「その他全てはインターネットゲートウェイ経由」
```

## Layer 4（トランスポート層）とは

### 役割
**「どのアプリケーション・サービスに送るか」**を決める層

### 主要なプロトコル
- **TCP（Transmission Control Protocol）**
- **UDP（User Datagram Protocol）**

### 具体的な動作
```
送信者: 192.168.1.100:12345 (ポート12345から)
受信者: 10.0.2.50:443 (ポート443へ)

Layer 4での処理:
"HTTPSサービス（ポート443）にTCPで接続する"
```

### 制御内容
- **ポート番号**による宛先サービス指定
- **コネクション管理**（TCP接続の確立・切断）
- **信頼性の確保**（再送制御、順序保証）
- **フロー制御**（送信速度調整）

## Layer 7（アプリケーション層）とは

### 役割
**「どんな内容・形式でデータをやり取りするか」**を決める層

### 主要なプロトコル
- **HTTP/HTTPS**（Webブラウジング）
- **FTP**（ファイル転送）
- **SMTP**（メール送信）
- **DNS**（名前解決）
- **SSH**（リモートログイン）

### 具体的な動作
```
HTTP リクエストの例:
GET /api/users/123 HTTP/1.1
Host: api.example.com
Authorization: Bearer abc123...
Content-Type: application/json

{
  "name": "田中太郎",
  "email": "tanaka@example.com"
}
```

### 制御内容
- **データ形式**の定義（JSON、XML、HTML等）
- **認証・認可**の処理
- **暗号化**の実装（HTTPS）
- **アプリケーション固有のルール**

## 3つのレイヤーの連携例

### ECRからDockerイメージをpullする場合

```
Layer 7（アプリケーション層）:
Docker Registry API v2 プロトコル
GET /v2/my-app/manifests/latest HTTP/1.1
Host: 123456789.dkr.ecr.ap-northeast-1.amazonaws.com
Authorization: Bearer <ECR_TOKEN>
Accept: application/vnd.docker.distribution.manifest.v2+json

Layer 4（トランスポート層）:
- プロトコル: TCP
- 宛先ポート: 443 (HTTPS)
- 送信元ポート: 12345 (自動割り当て)
セキュリティグループ: 「ポート443のTCP通信を許可するか？」

Layer 3（ネットワーク層）:
- 宛先IP: 10.0.1.100 (VPCエンドポイントのENI)
- 送信元IP: 10.0.2.50 (EC2インスタンス)
ルートテーブル: 「10.0.1.100宛てはlocalで送信」
```

### Web閲覧の完全な例

```
ブラウザでhttps://example.com/login にアクセス

Layer 7（アプリケーション層）:
HTTP プロトコル
GET /login HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0...
Accept: text/html,application/xhtml+xml
Cookie: session_id=abc123

Layer 4（トランスポート層）:
- プロトコル: TCP
- 宛先ポート: 443 (HTTPS)
- コネクション確立: 3-way handshake
- SSL/TLS暗号化

Layer 3（ネットワーク層）:
- 宛先IP: 203.0.113.50 (example.comのIP)
- 送信元IP: 192.168.1.100 (あなたのPC)
- ルーティング: デフォルトゲートウェイ経由
```

## AWS Application Load Balancer（ALB）の例

### Layer 7 Load Balancer（ALB）

```hcl
resource "aws_lb" "app_lb" {
  name               = "app-load-balancer"
  load_balancer_type = "application"  # Layer 7で動作
  
  # Layer 7でのルーティング設定
}

resource "aws_lb_listener_rule" "api_rule" {
  listener_arn = aws_lb_listener.app.arn
  priority     = 100

  # Layer 7の内容を解析してルーティング
  condition {
    path_pattern {
      values = ["/api/*"]  # URLパスでルーティング
    }
  }

  condition {
    http_header {
      http_header_name = "User-Agent"  # HTTPヘッダーでルーティング
      values           = ["*mobile*"]
    }
  }

  action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.api_servers.arn
  }
}
```

### Layer 4 Load Balancer（NLB）との違い

```hcl
resource "aws_lb" "network_lb" {
  name               = "network-load-balancer"
  load_balancer_type = "network"  # Layer 4で動作
  
  # Layer 4（ポート・プロトコル）のみでルーティング
}

resource "aws_lb_listener" "network_listener" {
  load_balancer_arn = aws_lb.network_lb.arn
  port              = "80"
  protocol          = "TCP"  # Layer 4プロトコル
  
  # HTTPの内容は見ずに、TCPレベルでルーティング
  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.web_servers.arn
  }
}
```

## 実際のAWSサービスでの活用

### API Gateway（Layer 7）

```hcl
resource "aws_api_gateway_rest_api" "example" {
  name        = "example-api"
  description = "Layer 7でHTTP APIを処理"
}

resource "aws_api_gateway_resource" "users" {
  rest_api_id = aws_api_gateway_rest_api.example.id
  parent_id   = aws_api_gateway_rest_api.example.root_resource_id
  path_part   = "users"
}

resource "aws_api_gateway_method" "get_users" {
  rest_api_id   = aws_api_gateway_rest_api.example.id
  resource_id   = aws_api_gateway_resource.users.id
  http_method   = "GET"  # Layer 7 HTTPメソッド
  authorization = "AWS_IAM"  # Layer 7 認証
}
```

### CloudFront（Layer 7 + キャッシュ）

```hcl
resource "aws_cloudfront_distribution" "example" {
  # Layer 7でHTTPヘッダー、クッキー、クエリパラメータを解析
  
  default_cache_behavior {
    # Layer 7の内容に基づくキャッシュ制御
    cached_methods = ["GET", "HEAD"]
    
    forwarded_values {
      query_string = false
      headers      = ["Authorization"]  # 特定のHTTPヘッダーのみ転送
      
      cookies {
        forward = "whitelist"
        whitelisted_names = ["session_id"]  # 特定のクッキーのみ転送
      }
    }
  }
}
```

## 具体例で理解する

### 郵便配達の例え（3層バージョン）

```
Layer 7 = 手紙の内容・形式
「英語で書かれたビジネス契約書」「日本語の年賀状」
→ どんな種類の文書で、どう処理するか

Layer 4 = 宛名・用途
「田中太郎様 会計部宛て」
→ その家の誰の、どの部署に届けるか

Layer 3 = 住所
「東京都渋谷区〇〇1-2-3 田中宅」
→ どの家に届けるか
```

### レストランの例え

```
Layer 7 = 注文内容・言語
「ハンバーガーセット、ポテトLサイズ、コーラ」（日本語）
「Burger set, large fries, cola」（英語）
→ 何を、どの言語で注文するか

Layer 4 = 注文方法・窓口
「店内注文（カウンター1番）」「ドライブスルー（窓口2番）」
→ どのサービス窓口で注文するか

Layer 3 = 店舗の場所
「渋谷店」「新宿店」「池袋店」
→ どの店舗に行くか
```

```
あなたのPC → Webサーバー への通信

Layer 3（ネットワーク層）の処理:
- 送信元IP: 192.168.1.100
- 宛先IP: 203.0.113.50
- 「203.0.113.50というサーバーに送る」

Layer 4（トランスポート層）の処理:
- 送信元ポート: 12345（自動割り当て）
- 宛先ポート: 443（HTTPS）
- プロトコル: TCP
- 「HTTPSサービス（ポート443）にTCP接続する」
```

### 郵便配達の例え

```
Layer 3 = 住所
「東京都渋谷区〇〇1-2-3 田中宅」
→ どの家に届けるか

Layer 4 = 宛名・用途
「田中太郎様 会計部宛て」
→ その家の誰の、どの部署に届けるか
```

## AWS セキュリティグループとルートテーブルの違い

### ルートテーブル（Layer 3）

```hcl
# 「どのIPアドレス範囲をどこに送るか」を決定
送信先              ターゲット
10.0.0.0/16        local
0.0.0.0/0          nat-xxxxxxxxx
```

**制御内容:**
- IPアドレスベースの経路制御
- パケットの送信先を決定
- ネットワーク全体のトラフィック制御

### セキュリティグループ（Layer 4）

```hcl
# 「どのポート・プロトコルでのアクセスを許可するか」を決定
インバウンドルール:
タイプ      ポート    プロトコル    送信元
HTTP        80       TCP          0.0.0.0/0
HTTPS       443      TCP          0.0.0.0/0
SSH         22       TCP          203.0.113.0/24
```

**制御内容:**
- ポート番号とプロトコルによる制御
- アプリケーション・サービスレベルの制御
- 個別インスタンスのファイアウォール機能

## 実際のパケットフロー

### EC2インスタンスがS3にアクセスする例

```
1. アプリケーション層（Layer 7）
   HTTPSリクエスト: "GET /my-bucket/file.txt"

2. トランスポート層（Layer 4）
   TCP接続: ポート443
   セキュリティグループ確認: 「ポート443のアウトバウンドTCP通信は許可されているか？」

3. ネットワーク層（Layer 3）
   IP宛先: s3.amazonaws.com（DNS解決後のIP）
   ルートテーブル確認: 「このIP宛てはどのターゲットに送るか？」

4. データリンク層（Layer 2）
   Ethernet フレーム作成

5. 物理層（Layer 1）
   電気・光信号での送信
```

## 実用的な設定例

### ルートテーブル設定（Layer 3制御）

```hcl
resource "aws_route_table" "private" {
  vpc_id = aws_vpc.main.id

  # Layer 3: IPアドレスベースのルーティング
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_nat_gateway.main.id
  }

  # S3ゲートウェイエンドポイント用ルート（自動追加）
  # pl-12345678 → vpce-xxxxxxxxx
}
```

### セキュリティグループ設定（Layer 4制御）

```hcl
resource "aws_security_group" "web_server" {
  name_prefix = "web-server"
  vpc_id      = aws_vpc.main.id

  # Layer 4: ポート・プロトコルベースの制御
  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"           # Layer 4プロトコル
    cidr_blocks = ["0.0.0.0/0"]  # Layer 3アドレス範囲
  }

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}
```

## まとめ

| 項目 | Layer 3（ネットワーク層） | Layer 4（トランスポート層） | Layer 7（アプリケーション層） |
|------|---------------------------|----------------------------|-----------------------------|
| **主な役割** | IPアドレスによる宛先決定 | ポート・プロトコルによるサービス識別 | データ内容・形式の処理 |
| **使用する情報** | IPアドレス、サブネット | ポート番号、TCP/UDP | HTTP、JSON、認証情報 |
| **AWS での例** | ルートテーブル | セキュリティグループ | ALB、API Gateway |
| **制御範囲** | ネットワーク全体の経路 | 個別アプリケーション・サービス | アプリケーション固有のロジック |
| **例え** | 郵便の住所 | 郵便の宛名・部署 | 手紙の内容・言語 |

**重要なポイント:**
- **Layer 3**: 「どこに送るか」（Where）
- **Layer 4**: 「何のサービスに送るか」（What service）
- **Layer 7**: 「どんな内容で、どう処理するか」（How & What content）

**実際の通信フロー:**
```
1. Layer 7: アプリケーションがHTTP GETリクエスト作成
2. Layer 4: セキュリティグループがポート443のTCP通信をチェック  
3. Layer 3: ルートテーブルがIP宛先の経路を決定
4. 実際にパケット送信
5. 受信側で逆順に処理（Layer 3→4→7）
```

全てのレイヤーが連携して、初めて完全な通信が可能になります！