0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

S3 + CloudFront 構成の静的サイトを自動デプロイする手順(GitHub Actions CI/CD)

Posted at

はじめに

本記事では、S3 + CloudFront構成で静的サイト(例:React / Vue / HTML)をホスティングし、
GitHub Actionsによる自動デプロイ(CI/CD)を導入する方法を解説します。

対象読者:

  • AWS S3で静的サイトを公開している人

  • CloudFrontでキャッシュ配信している人

  • 手動アップロードから卒業して自動化したい人

構成図

GitHub
  ↓ (push)
GitHub Actions
  ↓
AWS CLI
  ↓
S3  ← CloudFront(キャッシュ配信)

前提条件

  • AWSアカウントを保有

  • S3バケットを作成済(静的ウェブホスティング有効)

  • CloudFrontディストリビューションを設定済

  • GitHubリポジトリにソースコードを配置済

S3 + CloudFront + WAF でReactのデフォルトアプリケーションを公開する方法について詳しくは、下記の記事で解説しています。
https://qiita.com/cho-tehu/items/8dc94961f8d88ced890c

S3バケットの設定

  • バケットポリシーにCloudFrontからのアクセスのみ許可(OAC設定推奨)

  • パブリックアクセスはブロック

  • デプロイ対象:/build ディレクトリ(Reactの場合)

CloudFrontの設定

  • オリジン:S3バケット

  • キャッシュ無効化を自動化するため、CloudFrontの Distribution ID を控える
    → 後で aws cloudfront create-invalidation コマンドで使用します。

IAMユーザの作成

コンソールでIAMを開き、[ユーザー]を選択
スクリーンショット 2025-11-16 193239.png

[ユーザーの作成]を選択
スクリーンショット 2025-11-16 193353.png

任意の名前を入力して[次へ]を選択
スクリーンショット 2025-11-16 193517.png

[ポリシーを直接アタッチする]を選択し、[ポリシーの作成]を選択
スクリーンショット 2025-11-16 193902.png

別タブでポリシー作成画面が開くので、ポリシーを作成する。
スクリーンショット 2025-11-16 194652.png

スクリーンショット 2025-11-16 195036.png

IAMポリシー例(最小権限):
arn:aws:s3:::my-static-site-bucket は自身のs3バケットのARNと置き換えてください。
S3 のプロパティから確認できます。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:ListBucket",
        "s3:DeleteObject"
      ],
      "Resource": [
        "arn:aws:s3:::my-static-site-bucket",
        "arn:aws:s3:::my-static-site-bucket/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": "cloudfront:CreateInvalidation",
      "Resource": "*"
    }
  ]
}

IAM ユーザー作成画面に戻り、更新ボタンを押したのち、作成したポリシー名で検索をし、選択
次へ
スクリーンショット 2025-11-16 195218.png

作成する
スクリーンショット 2025-11-16 195435.png

アクセスキーの作成

IAMユーザー一覧から作成したユーザーを選択
スクリーンショット 2025-11-16 195936.png

セキュリティ認証情報タグから[アクセスキーを作成]を選択
スクリーンショット 2025-11-16 200104.png

[コマンドラインインターフェイス (CLI)]を選択し、[次へ]を選択
スクリーンショット 2025-11-16 200405.png

任意で説明を入力し、[アクセスキーを作成]を選択
スクリーンショット 2025-11-16 200531.png

ここで表示されるアクセスキー、シークレットアクセスキーをメモっておく。
csvでダウンロードすることもできる。
スクリーンショット 2025-11-16 200644.png

GitHub Secrets設定

GitHubリポジトリ → Settings → Secrets and variables → Actions

スクリーンショット 2025-11-16 192343.png

スクリーンショット 2025-11-16 192548.png

今回はRepository secretsとして登録する。
スクリーンショット 2025-11-16 192817.png

スクリーンショット 2025-11-16 201635.png

以下を登録:

Name Value
AWS_ACCESS_KEY_ID IAMユーザーのアクセスキー
AWS_SECRET_ACCESS_KEY シークレットキー
AWS_REGION デプロイ先のAWSリージョン。東京リージョンの場合は「ap-northeast-1」
S3_BUCKET デプロイ先のS3バケット名。静的サイトをアップロードする先のバケット(例:my-static-site-bucket)
DISTRIBUTION_ID CloudFrontのディストリビューションID(一覧から確認)

GitHub Actionsワークフロー例

.github/workflows/deploy.yml を追加し、プッシュする。

name: Deploy to S3 and CloudFront

on:
  push:
    branches:
      - main  # mainブランチにpush時デプロイ

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout source
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 22

      - name: Build project
        run: |
          npm ci
          npm run build

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ secrets.AWS_REGION }}

      - name: Deploy to S3
        run: |
          aws s3 sync build/ s3://${{ secrets.S3_BUCKET }} --delete

      - name: Invalidate CloudFront cache
        run: |
          aws cloudfront create-invalidation \
            --distribution-id ${{ secrets.DISTRIBUTION_ID }} \
            --paths "/*"

デプロイの流れ

  1. mainブランチにpush
  2. GitHub Actionsが自動でビルド
  3. build/ディレクトリをS3へアップロード
  4. CloudFrontのキャッシュを自動無効化
  5. 数分後にサイトが最新化

動作確認

App.jsを適当に編集して、プッシュする。

src/App.js
import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <div>自動デプロイ成功</div>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

プッシュ前
image.png

プッシュ後
image.png

これで完了です!
おつかれさまでした!

補足

Environment secrets と Repository secrets の違い

GitHub Actions では、ワークフロー内で使用する機密情報(API キーやトークンなど)を Secrets として安全に管理できます。Secrets には主に以下の 2 種類があり、用途やスコープが異なります。

1. Repository secrets(リポジトリ単位のシークレット)

特徴

  • そのリポジトリ内のすべてのワークフローから参照可能
  • リポジトリ単位 で管理したい値に向いている
  • フォークされたリポジトリには自動では引き継がれない
  • CI 全体で共通して使う API Key などを置きやすい

例:

  • AWS アクセスキー
  • Stripe や PayPay の API Key
  • DB 接続情報

利用箇所:
Settings → Secrets and variables → Actions → Repository secrets

2. Environment secrets(環境単位のシークレット)

特徴

  • GitHub Actions の “Environment(環境)” に紐づいた Secret
  • 本番 / 開発 / ステージング など環境ごとに値を分けたい場合に最適
  • Environment に “デプロイ保護ルール” を設定可能
    • Approver(承認者)必須
    • デプロイ前にレビューが必要
    • 特定ブランチのみデプロイ許可
  • 本番環境のキーを誤って開発用ワークフローで使う事故を防げる

例:

  • production 用 AWS アクセスキー
  • staging 用 API Gateway URL
  • 本番専用の外部サービスシークレット(Webhook secret など)

利用箇所:
Settings → Environments → (environment 名) → Environment secrets

まとめ

  • デプロイ用 IAM ユーザーは 最小権限・APIアクセスのみ
  • GitHub Secrets を使って 機密情報を安全に管理
  • CloudFront のキャッシュ無効化も自動化すると手動操作不要
  • Environment secrets を使うと 本番環境の安全性をさらに向上 できる

最後に

本記事では、S3 + CloudFront を使った静的サイトの自動デプロイ(CI/CD)を、GitHub Actions で実現する手順を解説しました。
ポイントを押さえれば、手動アップロードの手間をなくし、常に最新の状態でサイトを公開できる環境を構築できます。
S3で静的ウェブサイトをホストする場合、手動デプロイもかなりシンプルなので、結構わかりやすかったと思います。
次の機会には、EC2などデプロイ手順がS3より複雑なものも紹介していきたいと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?