GitHub Actions で AWS CDK の出力値を利用してビルドした静的サイトをPagesへデプロイする
本記事では、GitHub Actions を用いて AWS CDK でインフラをデプロイし、その際に得られた API Gateway や CloudFront の URL などの出力値を、静的 Web サイトのビルド時に環境変数として注入する方法をまとめます。これにより、フロントエンドアプリケーション側で動的に生成されたバックエンドのエンドポイント情報を利用することが可能となります。
ワークフロー全体の概要
以下の例は、GitHub Actions のワークフロー定義ファイルの一部です。大きく分けると 3 つのジョブがあります。
-
deployaws ジョブ
AWS の認証情報をセットアップし、CDK スタックをデプロイ。デプロイ結果から API Gateway や CloudFront の URL などの出力値を抽出し、ジョブの出力として設定します。 -
build ジョブ
deployaws ジョブの出力を利用して、静的 Web サイトのビルドを行います。環境変数として API_ENDPOINT、S3_BUCKET_URL、CLOUDFRONT_URL を渡し、ビルド時に動的な情報を埋め込みます。 -
deploy-pages ジョブ
ビルド済みの成果物を GitHub Pages にデプロイします。
deployaws ジョブ:CDK スタックのデプロイと出力値の抽出
まず、deployaws ジョブでは、以下の処理を実施しています。
-
リポジトリのチェックアウト
actions/checkout@v3
を利用して、ソースコードを取得します。 -
AWS 認証情報のセットアップ
aws-actions/configure-aws-credentials@v4
を使用し、必要なロールを assume して AWS に接続します。
Github Actions からCDK DeployするためのAWS側との認証は以下の記事に沿って行います。
-
依存パッケージのインストールと CDK のデプロイ
Node.js のセットアップ後、npm install
によって依存パッケージをインストールし、npx cdk deploy
コマンドで CDK スタックをデプロイします。
デプロイ時、--outputs-file cdk-outputs.json
オプションにより、出力値を JSON ファイルとして保存します。 -
出力値の抽出
jq
コマンドを利用して、JSON ファイルから API_ENDPOINT、S3_BUCKET_URL、CLOUDFRONT_URL を抽出し、GitHub Actions の出力変数として設定します。
これにより、次のジョブでこれらの値を参照できるようになります。
以下は該当部分の抜粋です:
- name: Deploy CDK stack
run: npx cdk deploy --require-approval never --outputs-file cdk-outputs.json
- name: Extract CDK outputs
id: cdk-outputs
run: |
echo "API_ENDPOINT=$(jq -r '.[].ApiUrl' cdk-outputs.json)" >> $GITHUB_OUTPUT
echo "S3_BUCKET_URL=$(jq -r '.[].BucketURL' cdk-outputs.json)" >> $GITHUB_OUTPUT
echo "CLOUDFRONT_URL=$(jq -r '.[].CloudFrontDomain' cdk-outputs.json)" >> $GITHUB_OUTPUT
このようにすることで、デプロイ後に得られた各種 URL を後続ジョブに引き継げます。
build ジョブ:環境変数を注入して静的サイトをビルド
次に、build ジョブでは、deployaws ジョブから取得した出力値を環境変数として渡し、静的 Web サイトのビルドを行います。具体的なポイントは以下の通りです。
-
deployaws ジョブの出力を参照
needs: deployaws
を指定することで、前のジョブの出力値(API_ENDPOINT、S3_BUCKET_URL、CLOUDFRONT_URL)を利用可能にします。 -
環境変数として設定
ビルド時のコマンド実行時に、各環境変数に deployaws ジョブで抽出した値を設定しています。たとえば、npm run build
の際に次のように環境変数を渡しています。
- name: Build
run: npm run build
env:
PUBLIC_URL: /s3-public-contents
API_ENDPOINT: ${{ needs.deployaws.outputs.API_ENDPOINT }}
CLOUDFRONT_URL: ${{ needs.deployaws.outputs.CLOUDFRONT_URL }}
S3_BUCKET_URL: ${{ needs.deployaws.outputs.S3_BUCKET_URL }}
-
デバッグステップ
実際に環境変数が正しく渡されているか、echo コマンドで確認するステップも用意しています。
この仕組みにより、ビルド時に最新のバックエンド API や CDN のエンドポイント情報が組み込まれ、静的サイト内で適切な通信先を参照できるようになります。
deploy-pages ジョブ:GitHub Pages へのデプロイ
最後に、deploy-pages ジョブでは、ビルド済みの成果物(例では ./dist
ディレクトリ内のファイル)を GitHub Pages にデプロイします。
actions/deploy-pages@v4
を使用して、簡単にデプロイプロセスが完了します。
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: "./dist"
- name: Deploy to GitHub Pages
uses: actions/deploy-pages@v4
これにより、最新の API エンドポイントや CloudFront の URL を組み込んだ静的サイトが自動的に公開されます。
まとめ
今回の記事では、GitHub Actions を利用した以下のポイントについて解説しました。
-
AWS CDK を利用したインフラのデプロイ
CDK でデプロイした際に、API Gateway や CloudFront の URL などの出力値を JSON ファイルとして保存する方法。 -
ジョブ間での出力値の引き継ぎ
deployaws ジョブで抽出した出力値を GitHub Actions の出力変数として設定し、build ジョブで参照する手法。 -
環境変数としての注入
静的 Web サイトのビルド時に、最新のバックエンド情報を環境変数として渡すことで、動的なエンドポイント情報をサイト内に組み込む方法。
これらの手法により、インフラ側の変更があっても静的サイト側のビルド時に自動で最新情報が反映され、運用の手間を大幅に削減できます。さらに、GitHub Actions のワークフローを活用することで、CI/CD パイプラインがシンプルかつ柔軟に構築できる点も魅力です。
deploy.ymlファイル全体
最後に今回のデプロイ用のファイルの全体像を残します。
name: Deploy GitHub Pages
on:
push:
branches: ["main"]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: true
jobs:
deployaws:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
outputs:
API_ENDPOINT: ${{ steps.cdk-outputs.outputs.API_ENDPOINT }}
S3_BUCKET_URL: ${{ steps.cdk-outputs.outputs.S3_BUCKET_URL }}
CLOUDFRONT_URL: ${{ steps.cdk-outputs.outputs.CLOUDFRONT_URL }}
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ secrets.AWS_ROLE_NAME }}
aws-region: ap-northeast-1
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 20
- name: Install dependencies
run: npm install
- name: Deploy CDK stack
run: npx cdk deploy --require-approval never --outputs-file cdk-outputs.json
- name: Extract CDK outputs
id: cdk-outputs
run: |
echo "API_ENDPOINT=$(jq -r '.[].ApiUrl' cdk-outputs.json)" >> $GITHUB_OUTPUT
echo "S3_BUCKET_URL=$(jq -r '.[].BucketURL' cdk-outputs.json)" >> $GITHUB_OUTPUT
echo "CLOUDFRONT_URL=$(jq -r '.[].CloudFrontDomain' cdk-outputs.json)" >> $GITHUB_OUTPUT
build:
runs-on: ubuntu-latest
needs: deployaws
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Pages
uses: actions/configure-pages@v3
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 20
- name: Install dependencies
run: npm install
- name: Build
run: npm run build
env:
PUBLIC_URL: /s3-public-contents
API_ENDPOINT: ${{ needs.deployaws.outputs.API_ENDPOINT }}
CLOUDFRONT_URL: ${{ needs.deployaws.outputs.CLOUDFRONT_URL }}
S3_BUCKET_URL: ${{ needs.deployaws.outputs.S3_BUCKET_URL }}
- name: Debug
run: echo $API_ENDPOINT |
echo $CLOUDFRONT_URL |
echo $S3_BUCKET_URL
env:
API_ENDPOINT: ${{ needs.deployaws.outputs.API_ENDPOINT }}
CLOUDFRONT_URL: ${{ needs.deployaws.outputs.CLOUDFRONT_URL }}
S3_BUCKET_URL: ${{ needs.deployaws.outputs.S3_BUCKET_URL }}
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: "./dist"
deploy-pages:
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
uses: actions/deploy-pages@v4
Discussion