Zenn
🏗️

GitHub Actions で AWS CDK の出力値を利用してビルドした静的サイトをPagesへデプロイする

2025/03/20に公開

本記事では、GitHub Actions を用いて AWS CDK でインフラをデプロイし、その際に得られた API Gateway や CloudFront の URL などの出力値を、静的 Web サイトのビルド時に環境変数として注入する方法をまとめます。これにより、フロントエンドアプリケーション側で動的に生成されたバックエンドのエンドポイント情報を利用することが可能となります。

ワークフロー全体の概要

以下の例は、GitHub Actions のワークフロー定義ファイルの一部です。大きく分けると 3 つのジョブがあります。

  1. deployaws ジョブ
    AWS の認証情報をセットアップし、CDK スタックをデプロイ。デプロイ結果から API Gateway や CloudFront の URL などの出力値を抽出し、ジョブの出力として設定します。

  2. build ジョブ
    deployaws ジョブの出力を利用して、静的 Web サイトのビルドを行います。環境変数として API_ENDPOINT、S3_BUCKET_URL、CLOUDFRONT_URL を渡し、ビルド時に動的な情報を埋め込みます。

  3. deploy-pages ジョブ
    ビルド済みの成果物を GitHub Pages にデプロイします。

deployaws ジョブ:CDK スタックのデプロイと出力値の抽出

まず、deployaws ジョブでは、以下の処理を実施しています。

  1. リポジトリのチェックアウト
    actions/checkout@v3 を利用して、ソースコードを取得します。

  2. AWS 認証情報のセットアップ
    aws-actions/configure-aws-credentials@v4 を使用し、必要なロールを assume して AWS に接続します。

Github Actions からCDK DeployするためのAWS側との認証は以下の記事に沿って行います。

https://zenn.dev/kou_pg_0131/articles/gh-actions-oidc-aws

  1. 依存パッケージのインストールと CDK のデプロイ
    Node.js のセットアップ後、npm install によって依存パッケージをインストールし、npx cdk deploy コマンドで CDK スタックをデプロイします。
    デプロイ時、--outputs-file cdk-outputs.json オプションにより、出力値を JSON ファイルとして保存します。

  2. 出力値の抽出
    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 サイトのビルドを行います。具体的なポイントは以下の通りです。

  1. deployaws ジョブの出力を参照
    needs: deployaws を指定することで、前のジョブの出力値(API_ENDPOINT、S3_BUCKET_URL、CLOUDFRONT_URL)を利用可能にします。

  2. 環境変数として設定
    ビルド時のコマンド実行時に、各環境変数に 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 }}
  1. デバッグステップ
    実際に環境変数が正しく渡されているか、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

ログインするとコメントできます