Argano の松田です。 この記事では Vite で作成したプロジェクトを AWS の S3 と CloudFront を使用して公開する方法について紹介します。 サンプルでは React を使用しますが、Vue や Svelte でも同様の手順で公開できます。
※ AWS アカウントが存在すること、Node.js がインストールされていることを前提としています。
Vite プロジェクトの作成
まずは Vite のプロジェクトを作成します。
npm create vite@latest my-react-app -- --template react-swc-ts
cd my-react-app
npm install
npm run dev # 開発サーバーを起動
npm run build # プロダクションビルド
npm run preview # プロダクションビルドしたものをローカルで確認
Git で管理します。後々 Github Actions を使用するため、Github にリポジトリを作成してください。
git init
git add .
git commit -m "Initial commit"
S3 バケットの作成
ビルド結果を格納する S3 バケットを作成します。
AWS のコンソールにログイン後、S3 サービスに移動し、「バケットを作成」をクリックします。
バケット名に任意の値を入力します。バケット名はグローバルで一意である必要があります。
バケット名以外の設定はデフォルトのままで問題ありません。S3 には CloudFront 経由でアクセスするため、直接アクセスすることはありません。そのため、「このバケットのブロックパブリックアクセス設定」セクションの、「パブリックアクセスをすべてブロック」にチェックが入っていることを確認してください。
「バケットを作成」をクリックします。
CloudFront ディストリビューションの作成
サイトを配信する CloudFront ディストリビューションを作成します。
CloudFront サービスに移動し、「CloudFront ディストリビューションを作成」をクリックします。
「Origin domain」に先ほど作成した S3 バケットを選択します。「オリジンアクセス」は「Origin access control settings」を選択、「Origin access control」は「Create new OAC」ボタンから作成します。 「ウェブアプリケーションファイアウォール (WAF)」は「セキュリティ保護を有効にする」にチェックを入れます。 「デフォルトルートオブジェクト」は「index.html」を設定します。他の設定はデフォルトのままで問題ありません。キャッシュの設定などは必要に応じて変更してください。
「ディストリビューションを作成」をクリックします。
作成が完了すると、ディストリビューションの詳細画面が表示されます。この画面にて「S3 バケットポリシーを更新する必要があります」というメッセージが表示されていると思いますので「ポリシーをコピー」をクリックします。
S3 バケットポリシーの設定
先ほどコピーしたポリシーを S3 バケットの「アクセス許可」タブの「バケットポリシー」に貼り付けます。バケット名、AWS アカウント ID、CloudFront ディストリビューション ID を適切な値に置き換えたら保存します。
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "AllowCloudFrontServicePrincipal",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::{バケット名}/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::{AWSアカウントID}:distribution/{CloudFrontディストリビューションID}"
}
}
}
]
}
CloudFront エラーページの設定
CloudFront ディストリビューションの「エラーページ」タブに移動し、「カスタムエラーレスポンスを作成」をクリックします。
「HTTP エラーコード」に 「403: Forbidden」 を選択します。また、「エラーレスポンスをカスタマイズ」で「はい」を選択し、「レスポンスページのパス」に 「/」、「HTTP レスポンスコード」に 「200: OK」を設定します。
「カスタムエラーレスポンスを作成」をクリックします。
この設定は React Router などを使用して、複数ページ表示する SPA の場合に有効です。この設定がないと、ユーザーが /about を直接開こうとした場合に、about.html が存在しないため 403 エラーが返されてしまいます。
GitHub Actions で OIDC を使用して AWS 認証する
Github Actions から Vite のビルド結果を S3 へアップロードするために必要な設定を行います。
ID プロバイダの作成
AWS コンソールの IAM > ID プロバイダ に移動し、「プロバイダを追加」をクリックします。
「プロバイダのタイプ」を「OpenID Connect」に、「プロバイダの URL」を「 https://token.actions.githubusercontent.com」 に設定します。入力後、 「サムプリントを取得」をクリックします。対象者は「sts.amazonaws.com」にします。
「プロバイダを追加」をクリックします。
IAM ポリシーの作成
IAM > ポリシー に移動し、「ポリシーの作成」をクリックします。
ポリシーエディタで JSON を選択し、以下の JSON を貼り付けます。バケット名、AWS アカウント ID、CloudFront ディストリビューション ID を適切な値に置き換えたら「次へ」をクリックします。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:ListBucket",
"s3:DeleteObject",
"cloudfront:CreateInvalidation"
],
"Resource": [
"arn:aws:s3:::{バケット名}",
"arn:aws:s3:::{バケット名}/*",
"arn:aws:cloudfront::{AWSアカウントID}:distribution/{CloudFrontディストリビューションID}"
]
}
]
}
ポリシー名に任意の値を入力し、「ポリシーの作成」をクリックします。
IAM ロールの作成
IAM > ロール に移動し、「ロールを作成」をクリックします。
信頼されたエンティティタイプで「カスタム信頼ポリシー」を選択します。
カスタム信頼ポリシーには、以下の JSON を貼り付けます。AWS アカウント ID、GitHub ユーザー名、GitHub リポジトリ名を適切な値に置き換えたら「次へ」をクリックします。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<AWSアカウントID>:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
},
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:<GitHubユーザー名>/<GitHubリポジトリ名>:*"
}
}
}
]
}
許可ポリシーには、先ほど作成した IAM ポリシーを選択します。
ロールの名前に任意の値を入力し、「ロールの作成」をクリックします。
Github Actions ワークフローの作成
Vite のビルド結果を S3 にアップロードする Github Actions ワークフローを作成します。アップロード後、CloudFront のキャッシュを削除することで、最新のビルド結果を反映させます。
.github/workflows/deploy.yml
ファイルを作成します。AWS アカウント ID、IAM ロール名、バケット名、CloudFront ディストリビューション ID を適切な値に置き換えたら保存します。
name: Deploy
on:
push:
branches:
- main
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: "npm"
- run: npm ci
- run: npm run build
- uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ap-northeast-1
role-to-assume: arn:aws:iam::{AWSアカウントID}:role/{IAMロール名}
- name: Deploy
run: |
aws s3 sync --exact-timestamps --delete dist s3://{バケット名}
- name: Clear Cache
run: |
aws cloudfront create-invalidation --distribution-id {CloudFrontディストリビューションID} --paths '/*'
デプロイ
作成した Github Actions のワークフローは main ブランチへのプッシュや手動で実行できます。
git add .
git commit -m "Deploy"
git push origin main
動作確認
CloudFront ディストリビューションの「ディストリビューションドメイン名」にアクセスすると、Vite プロジェクトが公開されていることを確認できます。