MENU

【AWS】S3 + CloudFrontで高速・低コストな静的サイトホスティングを構築する

コーポレートサイトやドキュメントサイトなどの静的コンテンツは、S3 + CloudFrontで配信するのが最もコスト効率が良い方法です。EC2やECSを使う必要がなく、サーバー管理も不要。この記事ではACM証明書によるHTTPS化まで含めた構築手順を解説します。

目次

アーキテクチャ概要

構成はシンプルで、ユーザー → CloudFront → S3(OAC経由)という流れです。S3バケットはパブリックアクセスを完全にブロックし、CloudFrontからのみアクセスを許可します。OAC(Origin Access Control)を使うことで、S3の静的ウェブサイトホスティング機能を使わずに安全に配信できます。

S3バケットの設定

resource "aws_s3_bucket" "site" {
  bucket = "my-static-site-bucket"
}

resource "aws_s3_bucket_public_access_block" "site" {
  bucket = aws_s3_bucket.site.id

  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

resource "aws_s3_bucket_policy" "site" {
  bucket = aws_s3_bucket.site.id
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Sid       = "AllowCloudFrontOAC"
        Effect    = "Allow"
        Principal = { Service = "cloudfront.amazonaws.com" }
        Action    = "s3:GetObject"
        Resource  = "${aws_s3_bucket.site.arn}/*"
        Condition = {
          StringEquals = {
            "AWS:SourceArn" = aws_cloudfront_distribution.site.arn
          }
        }
      }
    ]
  })
}

CloudFrontディストリビューションの設定

ポイントはOACの設定とデフォルトルートオブジェクトの指定です。SPAの場合はカスタムエラーレスポンスで404を /index.html にリダイレクトする設定も必要です。

resource "aws_cloudfront_distribution" "site" {
  origin {
    domain_name              = aws_s3_bucket.site.bucket_regional_domain_name
    origin_id                = "S3Origin"
    origin_access_control_id = aws_cloudfront_origin_access_control.site.id
  }

  enabled             = true
  default_root_object = "index.html"

  default_cache_behavior {
    allowed_methods        = ["GET", "HEAD"]
    cached_methods         = ["GET", "HEAD"]
    target_origin_id       = "S3Origin"
    viewer_protocol_policy = "redirect-to-https"

    forwarded_values {
      query_string = false
      cookies { forward = "none" }
    }

    min_ttl     = 0
    default_ttl = 86400
    max_ttl     = 31536000
    compress    = true
  }

  viewer_certificate {
    acm_certificate_arn      = aws_acm_certificate.site.arn
    ssl_support_method       = "sni-only"
    minimum_protocol_version = "TLSv1.2_2021"
  }

  restrictions {
    geo_restriction { restriction_type = "none" }
  }
}

デプロイの自動化

GitHub Actionsを使えば、mainブランチへのpush時に自動でS3にアップロードし、CloudFrontのキャッシュを無効化できます。

# .github/workflows/deploy.yml
name: Deploy to S3
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Sync to S3
        run: aws s3 sync ./dist s3://my-static-site-bucket --delete
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_REGION: ap-northeast-1
      - name: Invalidate CloudFront
        run: |
          aws cloudfront create-invalidation \
            --distribution-id ${{ secrets.CF_DISTRIBUTION_ID }} \
            --paths "/*"

まとめ

S3 + CloudFrontは静的サイトのホスティングにおいて、コスト・パフォーマンス・セキュリティのすべてで優れた選択肢です。月間100万PV程度のサイトでも月額数百円で運用できるため、EC2で静的サイトを配信している場合は移行を検討する価値があります。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

目次