昨年発表されたAmplify Gen2(プレビュー)ですが、日々機能が少しづつ追加されており、完成度が高まってきました。 前回の記事で作成したNextJS Server ComponentsのWebアプリケーションをHostingし、デプロイまで進めてみました。
Ampify Gen2のHostingの概要
従来のAmplifyでWebアプリケーションをHostingする場合、S3を使ったstatic website hostingと、Amplify Hostingの2つがありましたが、Amplify Gen2では「Amplify Publish」のようなコマンドが無くなり、基本の選択肢からS3ホスティングが外れました。
Amplify Gen2はCustom Resourceという、AmplifyのCDKアプリケーションに既存のCDKコンストラクトを追加する機能があるので、お手軽にAmplify Gen2+S3でHostingしたい時は、NextJSのリソースをStatic Exportし、既存のAmplifyスタックからcreateStackして、Hosting用のCDKを追加すると、Amplifyのデプロイ時に一緒にCDKを実行し、デプロイします。
話が逸れつつありますが、概ねこのようなカスタムリソースで動作します。
amplify/data/backend.ts
import { defineBackend } from "@aws-amplify/backend";
import { auth } from "./auth/resource";
import { data } from "./data/resource";
import * as aws_s3 from "aws-cdk-lib/aws-s3";
import {
Distribution,
OriginAccessIdentity,
} from "aws-cdk-lib/aws-cloudfront";
import { RemovalPolicy } from "aws-cdk-lib";
import { BucketDeployment, Source } from "aws-cdk-lib/aws-s3-deployment";
import { S3Origin } from "aws-cdk-lib/aws-cloudfront-origins";
import { Effect, PolicyStatement, ServicePrincipal } from "aws-cdk-lib/aws-iam";
const backend = defineBackend({
auth,
data,
});
const contextJson = JSON.parse(process.env.CDK_CONTEXT_JSON ?? "{}");
const stackprefix =
contextJson["amplify-backend-type"] === "sandbox"
? contextJson["amplify-backend-name"]
: "";
const subStack = backend.createStack(stackprefix + "SubStack");
// Create an S3 bucket for the website
const destinationBucket = new aws_s3.Bucket(subStack, "WebsiteBucket", {
bucketName: `cdk-hogetest-content-bucket`,
blockPublicAccess: aws_s3.BlockPublicAccess.BLOCK_ALL,
autoDeleteObjects: true,
removalPolicy: RemovalPolicy.DESTROY,
});
const originAccessIndetity = new OriginAccessIdentity(subStack, "OAI");
destinationBucket.grantRead(originAccessIndetity);
// Create a CloudFront distribution
const distribution = new Distribution(subStack, "distro", {
defaultBehavior: {
origin: new S3Origin(destinationBucket, {
originAccessIdentity: originAccessIndetity,
}),
},
defaultRootObject: "index.html",
});
// Deploy the contents of the 'website' directory to the S3 bucket
new BucketDeployment(subStack, "DeployWebsite", {
sources: [Source.asset("./out")],
destinationBucket,
distribution,
});
// S3 - BucketPolicy
const destinationBucketPolicyStatement = new PolicyStatement({
actions: ["s3:GetObject"],
effect: Effect.ALLOW,
principals: [new ServicePrincipal("cloudfront.amazonaws.com")],
resources: [`${destinationBucket.bucketArn}/*`],
});
destinationBucket.addToResourcePolicy(destinationBucketPolicyStatement);
next.config.mjs
/** @type {import('next').NextConfig} */
const nextConfig = {
output: "export",
};
export default nextConfig;
tsconfig.json
...
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules/*", "amplify/*", "amplify-backup/*"]. //amplifyフォルダを除外
}
とはいえ、今回はNextJSのServer Componentsを使いたいので、Amplify Hostingを選ぶことになります。
Amplify HostingのドキュメントはAmplify Gen2内には存在しないのですが Ampligy Gen2用のUIが用意されています。プレビュー版で、幾つか開発中の機能はあるものの、大幅に使いやすくなっていると感じました。
今回はGithubと連携し、Pushに合わせてリソースをデプロイするオーソドックスなデプロイを構築します。
デプロイ
Amplifyのホスティングのページに進むと、Amplify Gen2のSuggestが表示されています。
今回は、既にNextJSのソースコードがGitHubに配置されているものとします。
githubと連携し、リポジトリとブランチを指定します。
リポジトリをスキャンし、フレームワークが自動選択されることが分かります。
詳細設定からビルドイメージを選択できます。 執筆時点では、デフォルトの設定のままデプロイまで行うことが出来ており、特に設定を変えていません。
最後まで進めると、デプロイが完了しました。初回は10分ほど掛かりました。 ビルド・デプロイの項目をクリックすると、それぞれのプロセスの標準出力を確認し、異常がなかったかどうかを確認できます。
ここは従来のAmplify Hostingと同様、amplify.ymlで設定されたものが反映されます。 過去のデプロイの履歴の確認や、再デプロイも可能です。切り戻しに便利ですね。
Amplify Gen2のUIメニュー
これも従来のAmplify Hostingと同様ですが、環境変数やSecretを設定でき、ブランチ毎に値を出し分ける事ができます。 環境変数は、Amplify Hostingで管理し、CDK・フロントエンドで使用することができます。 Secretは、SSM Parameter Storeで管理し、Amplifyで作成したBackendサービスに適用できます。 記事には含めていませんが、Function(Lambda)を作成して、環境変数としてセキュアな値を受け取りたい時に便利でした。
リポジトリの設定は、ブランチの管理がポイントで、ブランチ名で判断し、GitHub上でのアクションが発生した時、自動でビルド処理を走らせるかどうかの調整ができます。
ビルドの設定では、amplify.ymlを編集し、ビルドとデプロイの設定を変更することができます。 また、ビルド時の通知や、incoming WebHookを飛ばし、例えばCodeCatalyst等の他アプリケーションと連携するような設定を行います。
カスタムドメインはまだ使えない
本来は、このメニューから、Route53や、独自に取得したドメインを簡単に設定できるのですが まだ利用できませんでした。ご注意下さい(見落としていて、痛い目を見ました・・・)
おまけ:デプロイ環境のローカルテスト
デプロイした環境をローカルで動作チェックしたい時、デプロイした環境とsandboxで作成した環境は別になります。 この環境を識別するファイルが、Amplify V6から用意された、amplifyconfiguration.jsonです(以前のaws-exports)。
generate configコマンドで、デプロイされたamplifyのスタックを選択することで、指定した環境のamplifyconfiguration.jsonを生成できるようになりました。以前の、Amplify env checkoutと似たような動きとして使えそうです。デプロイ時も、内部でこのコマンドが実行されているようです。
npx amplify generate config --stack hogehoge
ただ、執筆時点では、変更したCognitoのパスワードポリシーがconfigに反映されないといった不具合も確認されており プレビュー中ということもあり、正式版の発表が待たれる所ではあります。
その他、CLIを使用したリファレンスはこちらでまとめられています。
まとめ
Amplifyの基本的なアプリ作成とデプロイまでを紹介しました。 まだまだプレビュー版のAmplify Gen2ですが、ツールファーストからコードファーストに切り替わり、これまでのAmplifyの知識からのアップデートが必要と感じました。