🌍

【AWS Amplify Gen2】Next14(App Router)+Amplify HostingでDeployした感想-PMLinc

2024/02/02に公開

Amplify Gen2について

PML(Purpom Media Lab)では、AWS Amplify Stackをベースとした開発を行ってるですが、
2023年のAWS re:Invent 2023において、TypeScriptをベースとした新しいAmplifyの開発体験を提供するGen2がPreviewで発表されました。
https://aws.amazon.com/jp/blogs/news/introducing-amplify-gen2/

今回試すにあたって参考にした記事は、こちらです。

https://docs.amplify.aws/gen2/start/quickstart/nextjs-app-router-server-components/

ちなみに、AWS amplify Gen2は、まだdomain自体成長中で、多々実際に動かしてみたけど動かないなどの問題が発生することがあります。筆者も、この記事を書く中で、Amplify Gen2の環境を構築する際に、社内ではSSOログインが標準となっているため、SSOでGen2に対してログインを行ったのですが、SSOログインできず、Issueも上がっていたので、postしました。

https://github.com/aws-amplify/amplify-backend/issues/888#issuecomment-1916553996

Hello! Purpom Media Lab

Purpom Media Lab incでは、AWS Amplifyや、LambdaなどのServerless Stackを中心とした高速MVP構築及びサービス価値の検証を行っています。
https://purpom-media-lab.com/

また、MVPを構築するだけではなく、AWS Amplifyを中心としたオープンソースの機能改善なども行っています。

https://zenn.dev/purpom/articles/c00ee32f8024f4

https://github.com/aws-amplify/amplify-backend/pull/857

https://zenn.dev/kaiki_kk/articles/24c5b95df8daa8

今回構築する構成

今回試した、構成について紹介します。

下記の図で全てを表現できてるかかなり微妙なのですが、

1.Gen2を用いて実際にコードを書いた時に、backendリソース(今回は、authとdata)の挙動(Gen2から導入されたsandbox環境)

2.実際に完成したコードをDeployして、Userにアクセスさせる

を意識して描いた構成です。

今回使用した、Github Repository
https://github.com/purpom-media-lab/amplify_gen2_next_app_router_research

1.について、

いわゆるGen2のドキュメントに書いてある、

npx amplify sandbox

で立ち上げると立ち上がる環境。これを実行すると、開発者につき、1環境開発環境が構築される。
これが開発するときに、とてつもなく便利。

イメージで言うとnpm run devでlocalhostを立ち上げる。感覚で、インフラリソースを立ち上げる感じ。

実際に、npx amplify sandboxした状態。

開発を止めるときは、localhostを止めるような感覚で、Ctrl+Cでインフラリソースを削除できる。(もちろんインフラ自体を残すこともできる。)

正確には、Gen2では、AWSCDK経由でDeployされて、さらにCDKのhotswap機能が導入されてる。
さらに、hotswap機能が効いてる事で、 例えば、data/で定義した、schemaに変更を加えると、その変更を検知して、awsリソース(dynamoDBのschema)を変更してくれるのです。(まじで開発体験めっちゃいい)、
つまり、開発中に、いちいち、schema変えてmigrateコマンドを打って実行を待たなくても、コードを変更しただけで、あとはamplify-cliで動く、CDK(hotswap)がなんとか自動でdeployしてくれます。(まじですごい。大事な事だから2回言った。)

/amplify/data/resource.ts

import { type ClientSchema, a, defineData } from '@aws-amplify/backend';

/*== STEP 1 ===============================================================
The section below creates a Todo database table with a "content" field. Try
adding a new "isDone" field as a boolean. The authorization rules below
specify that owners, authenticated via your Auth resource can "create",
"read", "update", and "delete" their own records. Public users,
authenticated via an API key, can only "read" records.
=========================================================================*/
const schema = a.schema({
  Todo: a
    .model({
      content: a.string(),
+     title: a.string(),
    })
    .authorization([a.allow.owner(), a.allow.public().to(['read'])]),
});

つまり、terraformエンジニアで言う、terraform applyを監視した感じ、コマンドでは存在しないけど、言うなれば、terraform apply --watchみたいな状態

ディレクトリで言うと、amplify resourceが自動で作成される形です。

.
├── README.md
├── amplify //NOTE: amplify backendリソースが自動で作成される。
├── amplifyconfiguration.json
├── next-env.d.ts
├── next.config.mjs
├── node_modules
├── package-lock.json
├── package.json
├── public
├── src
└── tsconfig.json

2.について、

環境にdeployするときは、今までのamplify pushコマンドを使用して、2024年01月時点では、
そのようなcommandが存在しなく、awsのconsoleからしかDeployできないそうです。
なので、下記画像のように「アプリを作成」から、deployの設定などを設定できるようになります。

実際にGithub RepositoryとAmplify(Gen2式deploy)を連携すると、Github Repositoryの中身のコードの内容から、どのようなframeworkで書かれてるのかをsuggestしてくれます。

また、設定項目中、amplify.ymlファイルで、buildの設定ができます。今回は、frontendbackendの項目に分けてDeployをします。

amplifyで使用したい、dataauthは、backendリソースに値するもので、下記コマンドを実行することで、環境にDeployできるみたいです。さらに、別のamplify projectだけど、amplifyのbackendリソースは共通して使いたい時などにも使用します。

npx amplify pipeline-deploy --branch $AWS_BRANCH --app-id $AWS_APP_ID

https://docs.amplify.aws/gen2/deploy-and-host/fullstack-branching/custom-pipelines/

Nextjs(AppRouter)SSRを使用して、実際にDeployしての感想とつまずいたポイント

NextjsをGen2で使用するときにいくつか制約条件がある!

1. 2024/01時点でNextjs14のnodeのversionは最低18.17必要

gen2のdocumentにしれっと書いてあるので、注意ですね。

https://docs.amplify.aws/gen2/start/quickstart/nextjs-pages-router/#connect-branch-in-the-amplify-console

2.  Next.jsをSSRモードで動かすには、adapterモジュールのinstallが必要+configureする時に、ssr:trueとする必要がある。

Next.jsをServer-Side-Renderingで動かすには、@aws-amplify/adapter-nextjsを入れる必要があるみたいです。

npm add @aws-amplify/adapter-nextjs

さらに、nextjsをrunさせるときに、amplify configureさせる必要があるのですが、下記のようにssr: trueとひと加えする必要があります。

  • ConfigureAmplifyClientSide.tsを新しく作成(※中身のコードが重要なので、fileを新規作成しなくてもよい)
src/app/ConfigureAmplifyClientSide.ts
import {Amplify} from "aws-amplify";
//NOTE: ↓ npx amplify sandboxをすると、jsonファイルができるので、読み込む
import config from '../../amplifyconfiguration.json';

//TODO: SSRをtrueにしてあげる
Amplify.configure(config, {ssr: true})

export default function ConfigureAmplifyClientSide() {
    return null;
}
src/app/layout.tsx
import type {Metadata} from "next";
import {Inter} from "next/font/google";
import "./globals.css";
import {ReactNode} from "react";
import ConfigureAmplifyClientSide from "@/app/ConfigureAmplifyClientSide";

const inter = Inter({subsets: ["latin"]});

export const metadata: Metadata = {
    title: "Create Next App",
    description: "Generated by create next app",
};

export default function RootLayout({
                                       children,
                                   }: Readonly<{
    children: ReactNode;
}>) {
    return (
        <html lang="en">
        <body className={inter.className}>
        <>
//TODO: import
            <ConfigureAmplifyClientSide/>
            {children}
        </>
        </body>
        </html>
    );
}

https://docs.amplify.aws/gen2/build-a-backend/server-side-rendering/

3. (重要)環境にDeployする時に、Advanced SettingsにBuild Imageにamplify:al2023を指定しないといけない。

これを設定しないと、Deployの時に落ちます。すでに、environmentを作ってしまったprojectには、environment settingsに_CUSTOM_IMAGE:amplify:al2023を指定するそうです。

筆者は、これを見逃していて、buildの段階でerrorが発生して、中々解決しなくて困った。

https://docs.amplify.aws/gen2/start/quickstart/nextjs-pages-router/#connect-branch-in-the-amplify-console

まとめ

今回は、基本的な、Next14 AppRouter-SSRのprojectをstartさせて、実際に開発する手順とDeployするまでにつまずいた所をまとめました。
つまずいたとはいえ、以前のamplifyのversionより、開発体験も大幅に向上していることがわかりまいた。

  • amplify/の構造が明確でコードが書きやすいこと、
  • amplify backendで変更したコードがすぐにdeployされて確認できること。

はとても大きいです。別projectで、認証部分はfirebase authenticationの方が使いやすいので、firebaseを選択、それ以外は、AWSリソースと言った、two select cloud providerになっていましたが、amplifyのGen2のcognitoの連携簡素化によって、awsで完結できそうですね。

今後は、具体的な、amplify backend resourceの制約条件など躓いた所をまとめていきたいと思います。

Qiitaの方でも技術記事についてはまとめています。
https://qiita.com/magisystem0408

https://www.wantedly.com/companies/strategy-jp/post_articles/871116

https://note.com/magi_melchior

PURPM MEDIA LAB Tech blog

Discussion