📖

CDKメインのプロジェクトでAmplify Hostingを使う方法

2024/07/09に公開

概要

Amplify Hosting の構築をCDK(CloudFormation)を使って実現する方法の紹介です。

想定読者

  • Next.jsなどのフレームワークをAWSでデプロイしたい人
  • Amplifyを使ってみたいけど他のリソースはCDKで管理している人
  • Amplify Hostingに興味がある人

書かないこと

  • Amplify とはという基本的な内容について
  • Amplify Hosting以外のデプロイについて

前提: Amplifyでアプリケーションを構築する際の選択肢

Amplifyのアプリケーションを作成する選択肢としては大きく分けると以下の選択肢があるかと思います。どれを使ってもできるものとしては同じですが、どのように管理していきたいか、どのように拡張していきたいかによって使うものを選択すると良いでしょう。

  1. マネジメントコンソールを使う
  2. Amplify CLI を使う
    https://docs.amplify.aws/javascript/
  3. CDK(CloudFormation)のaws_amplifyモジュールを使う
    https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_amplify-readme.html

ざっくりとした使い分けのイメージとしては、Amplifyがどんな感じなのか手っ取り早く試したい場合には1.を、Amplifyのプラットフォームでアプリケーション全体を構成管理したい場合は2.を、CDKでアプリケーション全体の構成管理をしたくて一部だけAmplifyを利用したい場合は3.を選択するような形が取れます。

余談: AmplifyとCDK

「Amplify CDK」等で情報を検索していると、Amplify Gen2ではCDKとの連携が強化されたというような情報をよく目にするかもしれません。これ自体は間違っていないと思うのですが、 「Amplifyのプラットフォームで CDKを使ったリソースを扱いやすくなった」というものになります。CDKでAmplifyが扱いやすいかどうかはあまり情報がないように思えますのでご注意ください。

(参考)
https://zenn.dev/ototrip/articles/tech-nextjs-amplify-2

CDK でAmplify Hostingを構成管理する

いよいよ本題です。

CDKのaws_amplifyモジュールを使ってAmplify Hostingを作成していきます。

こちらにサンプルコードを置いています。
https://github.com/kodai305/amplify-nextjs

Next.jsの初期化は省略しますが公式を見れば特に迷うことはないかと思います!!
https://nextjs.org/learn-pages-router/basics/create-nextjs-app/setup

AmplifyアプリケーションをCfnAppで作成する

以下のようにCfnAppを使ってAmplify Applicationを作成します。

AMPLIFY_MONOREPO_APP_ROOTという馴染みのない環境変数を設定していますが、リポジトリのルートを設定するものとして必要なようです。

モノレポに保存されたアプリをデプロイする場合、アプリの環境変数 AMPLIFY_MONOREPO_APP_ROOT は、リポジトリのルートを基準にしたアプリルートのパスと同じ値でなければなりません。

https://docs.aws.amazon.com/ja_jp/amplify/latest/userguide/monorepo-configuration.html#setting-monorepo-environment-variable

buildSpecではビルドのステップを記述します。CodeBuildに慣れている方はお馴染みかもしれません。


    const amplifyApp = new CfnApp(this, "AmplifyApp", {
      name: 'sample-amplify-nextjs',
      oauthToken: githubToken,
      repository: "https://github.com/kodai305/amplify-nextjs",
      environmentVariables: [
        {
          name: "AMPLIFY_MONOREPO_APP_ROOT",
          value: "nextjs-blog",
        },
      ],
      buildSpec: BuildSpec.fromObjectToYaml({
        version: 1,
        applications: [
          {
            appRoot: "nextjs-blog",
            frontend: {
              phases: {
                preBuild: {
                  commands: ["npm install"],
                },
                build: {
                  commands: [
                    "npm run build",
                  ],
                },
              },
              artifacts: {
                baseDirectory: ".next",
                files: ["**/*"],
              },
              cache: {
                paths: ["node_modules/**/*"],
              },
            },
          },
        ],
      }).toBuildSpec(),
      platform: "WEB_COMPUTE",
      customRules: [
        {
          source: "/<*>",
          target: "/index.html",
          status: "404-200",
        },
      ],
    });

CfnBranchでブランチを作成する

Amplifyでは特定のブランチを元にCI/CDパイプライン構築することができます。例えば下のようにブランチを作成するとmainブランチと連携したCI/CDパイプラインを作成することができます。
enableAutoBuildをfalseにするとGitのPushトリガーでCI/CDが動かなくなります。
この方がCDKで構築している場合の既存のCI/CDパイプラインと組み合わせやすくなります(主観)。

    new CfnBranch(this, "AmplifyBranch", {
      appId: amplifyApp.attrAppId,
      branchName: 'main',
      framework: "Next.js - SSR",
      enableAutoBuild: false,
    });

cdk deploy

cdk deploy

でこのスタックをデプロイします。
ここまででできるのはenableAutoBuildにしているのでアプリケーションの枠組みだけができます。

デプロイを開始する

今回は、enableAutoBuild: false にしているため、デプロイのトリガーがありません。
その為、CLIを使ってデプロイの開始をします。

以下のようなコマンドになります。

aws amplify start-job --app-id ${ID} --branch-name ${BRANCH_NAME} --job-type RELEASE

注意事項

このCLIはあくまでもstart-jobつまり、デプロイを開始するだけのコマンドです。デプロイが成功したかどうかに関わらず正常終了します。成功したかどうかをwatchすることはこのコマンド単体ではできません。この解決方法については別記事で書きたいと思います。(ただし綺麗な方法が見つかっているわけではないので知っている方いらっしゃったら教えてください)

2024/07/15
こちらの記事で解決方法について記載しました。
https://zenn.dev/tkg216/articles/7e6b735b47c747

その他の観点

まとめ

以上が、CDKメインのプロジェクトでAmplify Hostingを使う方法の紹介になります。
個人的には複雑なことをする必要がなく導入しやすいように感じました。
CDKメインのプロジェクトでは、CDK PipelineやGitHub ActionsなどでCI/CDパイプラインを構築することが主観も入りますが多いように思います。その為、AmplifyのCI/CDパイプラインをそのまま使うというのがネックになるケースもあるかと思いますが、enableAutoBuild: false にし、CLIでデプロイを開始することで既存のCI/CIパイプラインにも組み込みやすくなるのではないかと思います!!

この記事が誰かのお役に立てれば幸いです!!!!

Discussion