AWS S3 + Github Actions で静的サイトを継続デリバリー

AWS S3の準備

 まずは、s3のバケットを作成します。バケット名はドメインと同じにします。

 ブロックパブリックアクセスをすべてブロックするのチェックを外します。

 次に、バケットのプロパティから「静的ウェブサイトホスティング」を有効にします。インデックスドキュメントにindex.htmlを指定します。

 その後、バケットポリシーを編集します。以下のように記述します。バケット名はドメインと同じにします。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicReadGetObject",
      "Effect": "Allow",
      "Principal": "*",
      "Action": [
        "s3:GetObject"
      ],
      "Resource": [
        "arn:aws:s3:::example-bucket/*"
      ]
    }
  ]
}

 DNSにCNAMEレコードを追加します。レコード値はバケットのエンドポイントを指定します。

IAMの作成

 Github ActionsからS3にアクセスするためのIAMを作成します。IDプロバイダを登録するかアクセスキーを作成します。

IDプロバイダの登録

 OpenID Connectを選択し、プロバイダのURLにhttps://token.actions.githubusercontent.comを入力し、サムプリントを取得を実行します。対象者にはsts.amazonaws.comを指定し、プロバイダを追加します。

次に、新しいロールを作成でウェブアイデンティを選択し、先ほど作成したIDプロバイダを選択します。その後、S3の書き込み権限を付与します。ロールARNをコピーします。

アクセスキーの作成

 IAMのユーザーを作成し、アクセスキーを作成します。アクセスキーIDとシークレットアクセスキーをコピーします。

Github Actionsの設定

 Githubのリポジトリに.github/workflowsディレクトリを作成し、deploy.ymlを作成します。

 リポジトリの設定からsecrets and variablesを選択します。新しいシークレットを追加します。 これは、設定例です。AWS_ROLE_ARN: arn:aws:iam::xxxxxxxxxxxx:role/ロール名

 Nextjsでエクスポートした静的サイトをデプロイする場合のworkflowは以下のようになります。html拡張子を削除してからアップロードしています。

name: Upload html files to S3

on:
  push:
    branches:
      - main

env:
  REGION: ap-northeast-1
  S3_BUCKET: sample-bucket
  SOURCE_DIR: ./out

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write
    outputs:
      files: ${{ steps.build.outputs.files }}
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Use Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "18.x"

      - name: Install dependencies
        run: yarn

      - name: Build
        run: yarn build

      - name: Configure AWS credentials from Cross Account Role
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-region: ${{ env.REGION }}

          # プロバイダのARN
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}

          or

          # アクセスキー
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          # シークレットアクセスキー
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

      - name: Find html files & set output
        id: build
        run: |
          echo "files="$(find ${{ env.SOURCE_DIR }} -name "*.html" -type f)"" >> $GITHUB_ENV

      - name: Upload to S3
        run: |
          aws s3 sync ${{ env.SOURCE_DIR }} s3://${{ env.S3_BUCKET }}/ --delete --exclude '.*git*'

      - name: Attach text/html metadata to html files
        run: |
          for filepath in ${{ env.files }}; do
            path=${filepath#./out/}
            key=${path%.html}
            aws s3 mv s3://${{ env.S3_BUCKET }}/$path s3://${{ env.S3_BUCKET }}/$key --metadata-directive REPLACE --content-type "text/html"
          done

 GithubのリポジトリのSettingsからSecretsを選択し、先ほど設定した環境変数を設定します。

 これで、Github ActionsでS3にデプロイする設定が完了しました。

更新履歴