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にデプロイする設定が完了しました。

更新履歴