S3バケットとCloudFrontを使用して複数のアプリを1つのドメインにデプロイする方法

この記事では、Amazon S3バケットとAWS CloudFrontを使用して、複数のアプリを1つのドメイン(example.com)にデプロイする方法を解説します。これにより、2つの異なるアプリをそれぞれのサブディレクトリ(/site1および/site2)にデプロイできます。

経緯

静的サイトジェネレーターの更新の際にプロジェクトが大きくなるに連れてビルドの時間がどんどんかかるので、example.com/site1example.com/site2のようにプロジェクトを分割して、デプロイできるようになれば、大規模化の際のビルド時間の短縮とコスト削減につながると考えた。

ざっくりやったこと

  • hugoのプロジェクトを2つ作成
  • S3の空のバケットを二つ作成
  • github actionでworkflowを作成しs3に自動でアップロードするようにする。
  • S3を静的サイトにする
  • 上記を二つのリポジトリで行う
  • cloudfrontでexample.com/site1example.com/site2のルーティング設定を行う
  • route 53で 独自ドメインの設定を行う

AWS S3バケットの作成と設定

まずは、アップロードする先となるAWS S3バケットを作成しましょう。

  • AWSコンソールにログインし、S3サービスページにアクセスしてください。
  • 「バケットを作成」ボタンをクリックし、バケット名を入力し、リージョンを選択して、「バケットを作成」ボタンをクリックしてください。
  • 作成したバケットに対して、適切なアクセス権限を設定してください。GitHub Actionsからアクセスできるようにするために、専用のIAMユーザーを作成し、S3へのアクセス権限を付与することをお勧めします。

GitHubリポジトリの準備

次に、GitHubリポジトリを作成し、ファイルをアップロードしたいディレクトリを準備します。例えば、public/ディレクトリを作成し、その中にアップロード対象のファイルを配置してください。

自分は今回はhugoを使用しました。

github actionでworkflowを作成しs3に自動でアップロードするようにする

github actionの使用方法は/.github/workflows/deploy.ymlに下記のような記述を書いて、pushするだけです GitHubリポジトリ内に、ワークフロー設定ファイル(YAML形式)を作成してください。

[.github/workflows/deploy.yml]

name: Deploy to S3

on:
  push:
    branches:
      - main # or the name of your default branch

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout
      uses: actions/checkout@v2
      with:
        submodules: recursive
    - name: Setup Hugo
      uses: peaceiris/actions-hugo@v2
      with:
        hugo-version: '0.76.2' # specify the Hugo version you are using

    - name: Build
      run: hugo --minify --theme hugo-book

    - name: Deploy
      uses: jakejarvis/s3-sync-action@v0.5.1
      with:
        args: --acl public-read --follow-symlinks --delete
      env:
        AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }}
        AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
        AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        AWS_REGION: ${{ secrets.AWS_REGION }}   # optional: defaults to us-east-1
        SOURCE_DIR: 'public'      # optional: defaults to entire repository

このワークフローは、mainブランチへのプッシュをトリガーに実行されます。それぞれのステップについて説明します。

Checkout: リポジトリの内容をチェックアウトします。actions/checkout@v2アクションを使用し、submodulesオプションをrecursiveに設定して、リポジトリ内のすべてのサブモジュールもチェックアウトします。

Setup Hugo: Hugoの環境をセットアップします。peaceiris/actions-hugo@v2アクションを使用して、hugo-versionで指定したバージョンのHugoをインストールします。

Build: Hugoを使用して静的サイトをビルドします。hugo --minify --theme hugo-bookコマンドを実行して、指定したテーマを使用し、生成されたファイルを最小化します。

Deploy: ビルドされた静的サイトをAWS S3にデプロイします。jakejarvis/s3-sync-action@v0.5.1アクションを使用して、argsオプションに指定されたオプションでS3に同期します。環境変数には、GitHubのSecretsからAWSの認証情報やS3バケット名、リージョンなどを取得します。SOURCE_DIRは、デプロイするディレクトリを指定します。この例ではpublicディレクトリが指定されています。

シークレット情報

secrets.AWS_ACCESS_KEY_ID は、GitHubリポジトリのシークレット(Secrets)に設定する必要があります。シークレットは、機密情報を安全に保存し、ワークフローで使用できるようにするための機能です。以下の手順でシークレットを設定します。

GitHubリポジトリのメインページにアクセスしてください。 右上の「Settings(設定)」タブをクリックします。 左側のメニューから「Secrets」を選択します。 「New repository secret」ボタンをクリックし、シークレットの名前と値を入力します。この場合、名前は AWS_ACCESS_KEY_ID で、値はAWSで作成したIAMユーザーのアクセスキーIDを入力します。 「Add secret」ボタンをクリックしてシークレットを保存します。 同様に、他のシークレットも設定してください(AWS_SECRET_ACCESS_KEY、AWS_S3_BUCKET、AWS_REGIONなど)。これらのシークレットは、GitHub Actionsワークフロー内で ${{ secrets.SECRET_NAME }} の形式で参照できます。シークレットは暗号化されており、ワークフローのログに表示されることはありません。

S3バケットを公開し、静的ウェブサイトホスティングを有効にします。

作成したS3バケットで静的ウェブサイトホスティングを有効にします。 作成したバケットの名前をクリックして、バケットの詳細ページにアクセスします。 2.2. 「プロパティ」タブをクリックし、「静的ウェブサイトホスティング」ボックスを探します。 2.3. 「静的ウェブサイトホスティング」ボックスをクリックし、「このバケットを使用してウェブサイトをホストする」を選択します。 2.4. インデックスドキュメントとエラードキュメントのファイル名を入力します。通常、インデックスドキュメントは index.html、エラードキュメントは error.html です。 2.5. 「保存」ボタンをクリックして変更を保存します。

SSL証明書の取得

AWS Certificate Manager(ACM)で、example.comドメイン用のSSL証明書を発行します。 証明書は、米国東部 (バージニア北部) リージョン (us-east-1) にある必要があります。

CloudFrontディストリビューションの作成と設定

AWS CloudFrontを使用して、新しいディストリビューションを作成します。 このディストリビューションのオリジンとして、前述の2つのS3バケットを追加します。 CloudFrontディストリビューションの「Behavior」設定で、それぞれのS3バケットに対応するパスパターンを作成します。

Site1:
Path pattern: /site1/*
Origin: Site1 S3バケット
Site2:
Path pattern: /site2/*
Origin: Site2 S3バケット

CloudFrontディストリビューションで、ACMで発行されたSSL証明書を選択し、example.comをカスタムドメインとして設定します。

DNS設定の更新

最後に、route 53でexample.comドメインをCloudFrontディストリビューションにポイントさせるように設定します。 通常は、CNAMEレコードやAレコード(ALIAS)を使用して設定します。

まとめ:

この記事では、Amazon S3バケットとAWS CloudFrontを使用して、複数のアプリを1つのドメインにデプロイする方法を解説しました。これにより、同じドメインで異なるアプリをサブディレクトリにデプロイすることが可能になります。この方法を使用すれば、それぞれのアプリの開発とデプロイが独立して行われるため、開発プロセスに影響を与えることなく、一つのサイト内に複数のアプリを運用することができます。

おまけ

cloudfrontのキャッシュをリセットする方法

  • AWS Management Consoleにサインインします。
  • サービスメニューから「CloudFront」を選択します。
  • CloudFrontディストリビューションリストから、キャッシュをリセットしたいディストリビューションを探してクリックします。
  • ディストリビューションの詳細ページで、「Invalidations」タブをクリックします。
  • 「Create Invalidation」ボタンをクリックします。
  • 「Invalidation Request」ダイアログボックスにて、無効化したいオブジェクトのパスを入力します。特定のオブジェクトを無効化する場合は、そのオブジェクトのパス(例:/images/example.jpg)を入力します。全てのオブジェクトを無効化する場合は、ワイルドカード(/*)を入力します。
  • 「Invalidate」ボタンをクリックして無効化処理を開始します。
Nakano
Nakano
Back-end engineer

AWS,Rails,UE4,vue.js,hugo,その他なんでもやりたい

関連項目