AWS CloudFrontとS3による静的ウェブサイトホスティング


## はじめに
- トラフィックに応じた低コストな従量課金制（小規模サイトで月額数ドル程度）
- マネジメントコンソールとAWS CLI、両方の手順を解説
- 実際のエラー対応例と解決手順も網羅

## アーキテクチャと仕組み

このシステムは以下のように動作します：

1. **アクセスフロー**
   - ユーザーがウェブサイトにアクセス → 最寄りのCloudFrontエッジロケーションに到達
   - CloudFrontがキャッシュを確認 → キャッシュがある場合は即座に応答
   - キャッシュがない場合、CloudFrontがOAI経由でS3からコンテンツを取得
   - 取得したコンテンツをキャッシュし、ユーザーに配信

2. **主なメリット**
   - 世界中のエッジロケーションによる高速配信
   - S3への直接アクセスを防ぎ、セキュリティを確保
   - キャッシュによる負荷軽減とコスト削減

## 前提条件

### 必要なもの
1. **AWSアカウント**
   - 未作成の場合：[AWS公式サイト](https://aws.amazon.com/)から作成（クレジットカード必要）
   - 無料利用枠：12ヶ月間、以下のサービスが無料
     - S3: 5GB
     - CloudFront: 50GB/月のデータ転送

2. **作業環境**
   - ブラウザ（AWSマネジメントコンソール用）
   - （オプション）AWS CLI
     - Windows: [インストーラー](https://awscli.amazonaws.com/AWSCLIV2.msi)からインストール
     - Mac: `brew install awscli`

3. **用意するもの**
   - 公開したいウェブサイトのファイル（HTML/CSS/画像など）
   - 最低限必要なファイル：
     ```
     index.html  # トップページ
     error.html  # エラーページ（オプション）
     ```

## 1. S3バケットの設定

### マネジメントコンソールでの設定

1. **バケット作成**
   - S3コンソールにアクセス → 「バケットを作成」
   - バケット名：`website-[YYYYMMDD]-[一意の文字列]`
     ```
     例：website-20240101-mysite
     ```
   - リージョン：アジアパシフィック（東京）
   - パブリックアクセス：すべてブロック（重要）

2. **バケットの詳細設定**
   - バージョニング：有効化（推奨）
   - 暗号化：有効化（デフォルトでオン）

### AWS CLIでの設定

```bash
# バケット作成
aws s3api create-bucket \
    --bucket website-20240101-mysite \
    --region ap-northeast-1 \
    --create-bucket-configuration LocationConstraint=ap-northeast-1

# バージョニング有効化
aws s3api put-bucket-versioning \
    --bucket website-20240101-mysite \
    --versioning-configuration Status=Enabled
```

### ファイルのアップロード

```bash
# ローカルのウェブサイトファイルをアップロード
aws s3 sync ./website-files s3://website-20240101-mysite

# または、マネジメントコンソールからドラッグ&ドロップでアップロード
```

## 2. CloudFrontの設定

### 基本設定（マネジメントコンソール）

1. **ディストリビューションの作成**
   - CloudFrontコンソール → 「ディストリビューションを作成」
   - オリジンドメイン：作成したS3バケットを選択
   - S3バケットアクセス：「OAIを使用」→ 新しいOAIを作成
   - バケットポリシー：「はい、ポリシーを更新」

2. **重要な設定項目**
   - デフォルトルートオブジェクト：`index.html`
   - プライスクラス：「アジアおよびヨーロッパのみ使用」（コスト最適化）
   - SSLサポート：「ビューワーとの通信時にHTTPSを要求」

### キャッシュ設定

```yaml
# おすすめの設定値
HTML files:
  TTL: 3600秒（1時間）
  パターン: *.html
  
Static files:
  TTL: 2592000秒（30日）
  パターン: 
    - /images/*
    - /css/*
    - /js/*
```

## 3. セキュリティ設定

### S3バケットポリシー
以下のポリシーが自動的に設定されます（手動で確認・調整可能）：

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::website-20240101-mysite/*",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": "arn:aws:cloudfront::account-id:distribution/distribution-id"
                }
            }
        }
    ]
}
```

**重要**: このポリシーにより、CloudFront経由のアクセスのみが許可され、S3への直接アクセスは拒否されます。

### WAFの設定（推奨）

1. **基本的な保護設定**
   - AWS WAFコンソールにアクセス
   - 「ウェブACLの作成」を選択
   - 以下のルールを追加：
     ```yaml
     Rate limiting:
       - 1,000リクエスト/IP/5分
       設定手順：
       1. Add rules → Rate-based rule
       2. Rate limit: 1000
       3. Time period: 5 minutes
     
     基本的なセキュリティルール:
       - SQLインジェクション対策
       - XSS対策
       - 不正なユーザーエージェントのブロック
       設定手順：
       1. Add rules → AWS managed rules
       2. Core rule set を選択
     ```

## 4. 動作確認とトラブルシューティング

### 基本的な動作確認

1. **CloudFrontのドメインでアクセス確認**
   ```
   https://[distribution-id].cloudfront.net/
   ```

2. **HTTP → HTTPS自動リダイレクトの確認**
   ```bash
   curl -I http://[distribution-id].cloudfront.net/
   # Expected: 301 Moved Permanently
   ```

### よくあるエラーと解決方法

1. **403 Forbidden**
   - **症状**: ウェブサイトにアクセスできない
   - **確認手順**:
     ```bash
     # バケットポリシーの確認
     aws s3api get-bucket-policy --bucket website-20240101-mysite
     
     # CloudFront OAIの確認
     aws cloudfront get-distribution-config --id [distribution-id]
     ```
   - **解決方法**:
     1. バケットポリシーが正しいか確認
     2. CloudFrontのOAI設定を確認
     3. S3バケットの暗号化設定を確認

2. **キャッシュの問題**
   - **症状**: コンテンツの更新が反映されない
   - **解決方法**:
     ```bash
     # キャッシュの無効化
     aws cloudfront create-invalidation \
         --distribution-id [distribution-id] \
         --paths "/*"
     ```

## 5. パフォーマンス最適化

### CloudFrontの最適化設定

```yaml
圧縮設定:
  - Gzip圧縮: 有効
  - Brotli圧縮: 有効
  対象ファイル:
    - text/html
    - text/css
    - application/javascript
    - image/svg+xml

キャッシュ最適化:
  - Query strings: なしの場合はキャッシュしない
  - Cookie: 必要な場合のみ転送
  - Headers: 必要最小限に制限
```

### コスト最適化のポイント

1. **プライスクラスの選択**
   - アジアのみ: 最も安価
   - グローバル: 最も高価だが、全世界で高速

2. **キャッシュ戦略**
   ```yaml
   静的コンテンツ:
     - 長めのTTL設定（30日）
     - バージョニングで更新管理
   
   動的コンテンツ:
     - 短めのTTL設定（1時間以内）
     - 必要に応じて個別に無効化
   ```

## 6. 運用とモニタリング

### CloudWatchによる監視設定

```bash
# エラーレートアラームの設定
aws cloudwatch put-metric-alarm \
    --alarm-name "HighErrorRate" \
    --alarm-description "Error rate > 1%" \
    --metric-name "5xxErrorRate" \
    --namespace "AWS/CloudFront" \
    --statistic Average \
    --period 300 \
    --threshold 1 \
    --comparison-operator GreaterThanThreshold \
    --evaluation-periods 2 \
    --alarm-actions [your-sns-topic-arn]
```

### 定期的なメンテナンスタスク

週次/月次で以下を確認：
1. セキュリティ更新の有無
2. コスト推移
3. エラーログの確認
4. パフォーマンスメトリクスの確認

## まとめ

セットアップ後の確認事項チェックリスト：
- □ HTTPS経由でサイトにアクセス可能
- □ キャッシュが正しく機能している
- □ エラーページが適切に表示される
- □ CloudWatchアラームが設定されている
- □ バックアップ戦略が整っている

次のステップ：
1. カスタムドメインの設定
2. CI/CDパイプラインの構築
3. コンテンツ更新フローの確立