Closed5
S3 + CloudFront構成で静的サイトをホスティングする

はじめに
AWS S3 + CloudFront構成で静的サイトをホスティングすることになりました
これは、手順や詰まった箇所などをメモするためのスクラップです
参考サイト

S3バケットの作成
- S3の管理画面からバケットの作成を選択
- バケットタイプは「汎用」を選択します
- 汎用 (Standard): 高可用性と耐久性が必要な場合に最適。デフォルトで選択されます。今回は静的ぺージの配信なのでこちらを選択。
-
ディレクトリ・新規 (One Zone-IA): アクセス頻度が低いデータ向けです。単一のAZ (Availability Zone) での保存となるため、コストが低くなりますが、耐久性は標準タイプより低い。
- オブジェクト所有者は「ACL無効」を選択
- ACL無効 (推奨): この設定を選ぶと、オブジェクトの所有権はバケット所有者に自動的に割り当てらる。推奨設定。
-
ACL有効: ACL (アクセスコントロールリスト) を使用する場合はこのオプションを選択しますが、セキュリティリスクがあるため、必要がない場合は使用を避ける。
- パブリックアクセス設定では「パブリックアクセスをすべて ブロック」にチェックをいれておきます(後からポリシーを設定する)
- バケットのバージョニングは「有効」
- あとはデフォルトのまま「バケットを作成」をクリック

S3 バケットにHTMLファイルと画像の配置
-
index.html
ファイルと必要なファイルを追加 - プロパティタブへ移動し、一番下へスクロール
- 静的ウェブサイトホスティングを次のように設定し保存

CloudFrontを作成
- CloudFrontの管理画面から「ディストリビューションを作成」をクリック
- 「Origin domain」に先ほど作成したバケットを選択
- 次の警告が出てもとりあえず気にせず続ける
- 「Origin path」には
/index.html
と入力 - オリジンアクセスでは「Origin access control settings (recommended)」を選択(S3のサイトにはCloudFrontしかアクセスできるようにするため)
- 「Create new OAC」でコントロール設定を新しく作成する
- ビューワープロトコルポリシーでは「Redirect HTTP to HTTPS」を選択。これでhttpのアクセスもhttpsにリダイレクトしてくれる
- Alternative domain name (CNAMEs) では使用したいドメインを入力
- 証明書はCloudFrontで使う場合はバージニア北部リージョンで証明書を発行しなければならないので、ない場合は新しく発行する。同じドメインで別リージョンに証明書を発行することは問題なく、追加料金もかからない(参考)
- 他はそのままで下へ進み、「デフォルトルートオブジェクト」に
index.html
と入力し「ディストリビューションを作成」をクリック - オリジンタブへ移動し、作成されたディストリビューションのオリジンを選択し、「編集」をクリック
- 「ポリシーをコピー」を選択し、「S3バケットアクセス許可に移動」を選択しS3のバケットポリシーのリンクに移動
- 「アクセス許可」タブの「バケットポリシー」の「編集」をクリックし、コピーしたポリシーを貼り付けて保存
- 「ディストリビューションドメイン名」をコピーしてアクセスし、ページが表示されれば完了
ドメインと紐づけ
- Route53のホストゾーンから使用したいドメインを選択
- 使用したいドメインのAレコードに作成した
CloudFront
ディストリビューションを選択 - 保存し、しばらくしてドメインへアクセス(しばらくかかる)
- 表示されれば完了

GitHub Actions でページを更新できるようにする
参考
IAMロールの作成
今回はIAM ユーザー (アクセスキー) を作成する代わりに、IAM のID プロバイダ (IdP)を使用します。この結果、外部ユーザー ID (GitHub Actions) にAWS アカウント内の AWS リソースに対するアクセス許可を与えることができます。
- IAMの管理画面から「ID プロバイダ」を選択し、「プロバイダを追加」を選択
- プロバイダのタイプ: 「OpenID Connect」
- プロバイダのURL : https://token.actions.githubusercontent.com
- 対象者: sts.amazonaws.com
- 「プロバイダを追加」
- 作成されたら画面上部に出現する「ロールの割り当て」をクリック
- 「新しいロールを作成」のまま次へ
- 「ウェブアイデンティティ」を選択し、それぞれ画像のように指定
- GitHub 組織に任意のものを入力して次へ
- 許可ポリシーは新しく作成し、以下の内容を入力※
[bucket-name]
は実際のバケット名に置き換える{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:ListBucket", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::[bucket-name]", "arn:aws:s3:::[bucket-name]/*" ] } ] }
- 作成したポリシーを割り当ててロールを作成
GitHub Actionsのワークフロー作成
今回は以下のように作成しました
name: 【デプロイ】ページをS3へデプロイ
on:
workflow_dispatch:
push:
branches:
- master
pull_request:
types:
- closed
branches:
- development
env:
AWS_REGION: <your-region>
AWS_ROLENAME: <your-role-name>
AWS_S3_BUCKET: <your-bucket-name>
SOURCE_DIR: '.'
ENV_NAME: html-page
jobs:
Deploy:
name: S3デプロイ
runs-on: ubuntu-22.04
if: (github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged && !startsWith(github.event.pull_request.head.ref, 'renovate/')) || (github.event_name != 'pull_request')
permissions:
id-token: write
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
- name: AWSへの認証情報を設定
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::${{secrets.AWS_ACCOUNT_ID}}:role/${{env.AWS_ROLENAME}}
aws-region: ${{ env.AWS_REGION }}
- name: デプロイを開始をSlackへ通知する
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
text: "デプロイを開始します -> ${{ env.ENV_NAME }}"
fields: repo,message,commit,author,action,eventName,ref,workflow
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
- name: ファイルの整合性チェック
run: |
if [ ! -f "${{ env.SOURCE_DIR }}/index.html" ]; then
echo "Error: index.html not found in ${{ env.SOURCE_DIR }}"
exit 1
fi
- name: Copy files to S3
run: |
aws s3 sync ${{env.SOURCE_DIR}} s3://${{env.AWS_S3_BUCKET}} --exclude '.*git*' --delete
continue-on-error: false
- name: S3デプロイの確認
run: |
aws s3 ls s3://${{env.AWS_S3_BUCKET}} --summarize --human-readable
- name: 結果をSlackに通知
uses: 8398a7/action-slack@v3
if: always()
with:
status: ${{ job.status }}
text: "デプロイ ${{ job.status == 'success' && '成功' || '失敗' }} -> ${{ env.ENV_NAME }}"
fields: repo,message,commit,author,action,eventName,ref,workflow
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
最後に
作成したGitHub Actionsが問題なく実行され、S3上のファイルが更新されれば完了です
このスクラップは2024/09/02にクローズされました