Amazon S3+CloudFront環境へGitHub Actionsをつかってデプロイする
静的サイトの配信のために、Amazon S3にファイルを設置してCloudFrontで配信する方法はよく行われていると思いますが、私の管理するアプリケーションでもこのような構成のものがあります。
というわけで、もっとかんたんにデプロイできるようにしたいな~ということで、GitHub Actionsでデプロイできるようにしたので、備忘録としてまとめました。
成果物のWorkflow
こんなかんじのWorkflowを定義します。私のアプリケーションの場合は事前にnode環境のセットアップ(actions/setup-node@v1
)をしたり、ビルド( npm run build
)してからS3にファイルを設置していますが、このへんはそれぞれのケースに応じて調整します。
Workflowのトリガは、今回は workflow_dispatch
として任意のタイミングで実行することとしましたが、このへんもそれぞれのケースに応じて調整するとよさそうです。
name: Deploy to s3 on: workflow_dispatch jobs: upload: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 # 成果物を生成する - uses: actions/setup-node@v1 with: node-version: '16.x' - name: Cache dependencies uses: actions/cache@v2 with: path: | **/node_modules key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} - run: npm install - run: npm run build # S3にアップロードしてInvalidationリクエストを投げる - uses: aws-actions/configure-aws-credentials@v1 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: (region) - run: aws s3 sync ./build s3://example-bucket - run: aws cloudfront create-invalidation --distribution-id (distribution-id) --paths "/*"
やっていることは概ねこんな感じです。
- aws-actions/configure-aws-credentials@v1 をつかって認証情報をセットアップする
- これを使うとawsコマンドを認証が済んだ状態+Regionをセットした状態で使うことができます。
(region)
を任意のRegionに設定します。
aws s3 sync
コマンドでビルドした成果物(など)をS3 Bucketに送信するaws cloudfront create-invalidation
でファイルの無効化を行い、CDNのサーバのコンテンツを差し替える(--paths "/*"
とすることですべてのファイルを無効化する)(distribution-id)
の部分は任意のDistribution IDに置き換えます。- Invalidationにはお金がかかります。 CloudFrontのドキュメント によると、1000件までの無効化パスまでは無料のようです。頻繁にこのActionsを実行する場合はこのことも考慮される必要がありそうです。
Workflowを動かすためのAWSアクセスキーの準備
各種awsコマンドが使えるように、アクセスキーを準備します。上記Actionsで用いるコマンド( aws s3 sync
, aws cloudfront create-invalidation
)には以下の権限が必要です。
(s3 sync
に必要な権限は、 こちらの記事 を参照しました)
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::(bucket-name)/*" ] }, { "Sid": "VisualEditor1", "Effect": "Allow", "Action": [ "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::(bucket-name)" ] }, { "Sid": "VisualEditor2", "Effect": "Allow", "Action": [ "cloudfront:CreateInvalidation" ], "Resource": [ "arn:aws:cloudfront::(aws-account-id):distribution/(distribution-id)" ] } ] }
(bucket-name)
はアップロード先のBucket名を設定します。(aws-account-id)
は、アカウントIDを設定します。- こちらのドキュメント に従ってアカウントIDを確認できます。
(distribution-id)
は、CloudFrontのDistribution ID を設定します。
これらのアクセス権限を持つIAM Userを作成し、アクセスキーとシークレットアクセスキーを取得します。これらを AWS_ACCESS_KEY_ID
と AWS_SECRET_ACCESS_KEY
として、それぞれGitHubリポジトリのSecretsに保存します
これで、さきほど定義したWorkflowが動作するようになります。
そのほか参考にしたもの
ビルドやアップロード周りを自動化することで、うっかりアップロードしちゃいけないファイルをアップロードするなどのミスが減るので、気軽にデプロイができるようになりますね。ではでは~