SAKURUG TECHBLOG

【AWS/Nuxt3/GitHub Actions】④Actions構築と実行

timestampauthor-name
Kota

はじめに

本記事は、AWSとNuxt3環境で自動デプロイを行うGitHub Actions構築ハンズオン連載の、第4回目にあたる記事です。

前回まででAWSとNuxtの環境構築が完了したので、今回は遂にGitHub Actionsを実装する手順について紹介します。

GutHubリポジトリへの環境変数登録

GitHub Actionsのワークフロー内で参照するための環境変数を登録します。

対象リポジトリ > Settings > Secrets end Variables > Actions > Secrets

登録するのは下記の情報です。

  • "AWS_REGION":AWSリージョンの名前(アジアパシフィック(東京)の場合は"ap-northeast-1")
  • "DISTRIBUTION":CloudFrontのディストリビューション名
  • "S3_CONTENTS_BUCKET":S3のバケット名

GitHub Actionsの構築

実装

前回作成したNuxtプロジェクトのルートに下記のディレクトリとymlファイルを追加します。

/
└ .github // 追加
  └ workflows // 追加
    └ main.yml // 追加(このファイル名は任意です。)
└ .nuxt
└ .vscode
└ node_modules
...

main.yml

name: AWS Deploy Nuxt3 Site

on:
  push:
    branches:
      - main

permissions:
  id-token: write
  contents: read

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: setup node
        uses: actions/setup-node@v3
        with:
          node-version: "18.x"

      - name: install modules
        run: npm install

      - name: generate nuxt
        run: npx nuxi generate

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v2
        with:
          role-to-assume: "arn:aws:iam::AWSアカウントID:role/ロール名"
          aws-region: ${{ secrets.AWS_REGION }}

      - name: Upload file to S3
        env:
          S3_CONTENTS_BUCKET: ${{ secrets.S3_CONTENTS_BUCKET }}
        run: |
          aws s3 sync ./.output/public s3://$S3_CONTENTS_BUCKET/

      - name: Clear cache CloudFront
        env:
          DISTRIBUTION: ${{ secrets.DISTRIBUTION }}
        run: |
          aws cloudfront create-invalidation --distribution-id $DISTRIBUTION --paths "/*"

補足:ymlの内容について

トリガー設定

on:
  push:
    branches:
      - main

mainブランチへのpushが行われた時にワークフローを実行します。

権限設定

permissions:
  id-token: write
  contents: read

ワークフローに下記の権限を付与します。

  • OIDCが発行するトークンの参照と書込み
  • リポジトリ内コンテンツの参照

仮想環境設定

runs-on: ubuntu-latest

ジョブが実行される仮想環境(ランナー)として、最新版のubuntuを指定します。

リソース設定

- uses: actions/checkout@v4

actions/checkout@v4を使用し、ランナー上で現在のリポジトリにチェックアウトします。

これにより、リポジトリ内のソースコードにアクセスが可能になります。

ブランチは指定していませんが、on:でmainブランチのpushイベントがトリガーとして設定されているため、暗黙的にmainブランチにチェックアウトされます。

オプションを付与することで、特定のブランチにチェックアウトすることも可能です。

Node環境設定

- name: setup node
  uses: actions/setup-node@v3
  with:
    node-version: "18.x"

actions/setup-node@v3を使用し、ランナー上でNode環境をセットアップします。

後続のジョブでNode環境が必要なためです。

オプションとして、バージョン18系の最新版を使用することを指定しています。

パッケージインストール

- name: install modules
  run: npm install

ランナー上で、package.jsonの内容に基づき、必要なパッケージのインストールを行います。

SSG実行

- name: generate nuxt
  run: npx nuxi generate

ランナー上で、Nuxtプロジェクトの静的サイト生成(SSG)を行います。

AWS認証

- name: Configure AWS credentials
  uses: aws-actions/configure-aws-credentials@v3
  with:
    role-to-assume: "arn:aws:iam::AWSアカウントID:role/ロール名"
    aws-region: ${{ secrets.AWS_REGION }}

aws-actions/configure-aws-credentials@v3を使用し、ランナーからAWSサービスへアクセスするための認証処理を行います。

後続のジョブでS3とCloudFrontを操作するためです。

オプションとして、前々回の記事で作成したIAMロールのARNを使用することと、AWSのリージョンを指定(Secretsの値を参照)しています。

S3へのデプロイ

- name: Upload file to S3
  env:
    S3_CONTENTS_BUCKET: ${{ secrets.S3_CONTENTS_BUCKET }}
  run: |
    aws s3 sync ./.output/public s3://$S3_CONTENTS_BUCKET/

run:のコマンド内容に基づき、S3へのファイルアップロードを行います。

より具体的に説明すると、s3 syncコマンドにより、リポジトリ内の./.output/publicディレクトリの内容とS3のルートディレクトリの内容を比較し、「リポジトリに存在してS3には存在しないファイル、または内容に差分があるファイルのみをS3にアップロード」しています。

類似挙動としては、s3 cpコマンドがあります。

こちらは単純なコピー操作であり、比較した結果「リポジトリに存在してS3には存在しないファイルがあればアップロードを行い、同名のファイルも強制的に上書き」します。

どちらにしても利点と欠点はあるのですが、処理の効率性と拡張性を考慮し、s3 syncコマンドを採用しています。

更新が必要な対象を絞ることでネットワーク帯域を減らせますし、オプションを追加すれば「S3に存在してリポジトリには存在しないファイルを削除する」ことも可能だからです。

要件や環境に応じて柔軟に使い分けましょう。

参考:AWS CLI で高レベル (S3) コマンドを使用する - AWS Command Line Interface

CloudFrontのキャッシュ削除

- name: Clear cache CloudFront
  env:
    DISTRIBUTION: ${{ secrets.DISTRIBUTION }}
  run: |
    aws cloudfront create-invalidation --distribution-id $DISTRIBUTION --paths "/*"

CloudFront(ルートディレクトリ配下の全ファイル)に残る、古いキャッシュの削除を行います。

この処理が正常に動作し、実際のページでリロードを行えば、ページの内容が最新状態に更新されます。

Actionsの動作確認

Actionsログ

yml実装 > mainブランチにpush > Actions >対象のrunを選択し、詳細ログを確認

S3更新ログ

S3コンソール > 対象バケット選択 > /.output/publicディレクトリと一致していることを確認

CloudFrontキャッシュ削除ログ

CloudFrontコンソール > 対象ディストリビューション選択 > キャッシュ削除 > ログが追加されていることを確認

実際のページ

https://xxxxx.cloudfront.net/index.html にアクセス

正常に反映されていることが確認できました。

まとめ

本記事では、表題の技術を扱ったCI構築を行うために、最終段階であるGitHub Actionsの実装手順について紹介しました。

ymlの内容は要件や環境によって様々かと思いますが、今回の内容を参考に柔軟なワークフロー構築に役立てていただければ幸いです。

総括

第1回~第4回までの記事で、AWSでの権限設定・サービス設定・OIDC設定、フロントエンドの環境構築、GitHub Actionsの実装について紹介しました。

そこそこボリュームのある内容でしたが、いかがでしたでしょうか。

僕自身は、これまでフロントエンドの実装を主軸に開発業務を行ってきました。

最近では徐々に責任範囲が拡がり、今回のようなCI・インフラ構築等のキャッチアップも必要になってきています。

第1回目の冒頭でも触れましたが、今回の記事は僕自身が「GitHub Actionsを構築するために体系的な参考資料があればなあ」と感じたことがきっかけの一つでした。

ある程度再現性を持たせた環境と、それぞれを1本の記事として読んでも参考になるよう意識して書いてみました。

深掘りすればまだまだ記事として書けるので、今後の投稿にも期待していただければと思います。

記事をシェアする

ABOUT ME

author-image
Kota
新卒入社3年目。SAKURUG TECHBLOG管理者。社内業務システムやフロントエンド開発を行っています。