Amplify x CDK でカスタムリソースを作る& CDK v2 に移行する
はじめに
これはAWS Amplify Advent Calendar 2021 18 日目の記事です。
Amplify CLI で CDK または CloudFormation を使ってカスタムリソースを作れるようになりました。この記事では Amazon IVS のプライベートチャネルを作ってみます。またどうも Amplify CLI 7.6.4 時点ではカスタムリソースを作るのに CDK v1 が使われているようなので CDK v2 に移行してみました。
なぜこの記事を書こうと思ったか
あまり言ってないのですが私は Amplify が好きです。最初は AppSync のリゾルバを簡単に作れるところが気に入って(なので Amplify CLI を AppSync SDK みたいに思っていた)、最近は Amplify Console を使って git push するだけでウェブサイトをホストできるところが気に入ってます。AWS Copilot CLI や CDK Pipelines もそうですが簡単に CI/CD を整備できるのはいいものです。
またこれはよく言っているのですが私は AWS CDK も好きです。IaC は最初 CloudFormation から入ったので YAML を書けと言われたら書くだろうけど、TypeScript を使った少ない記述量で様々な AWS サービスを柔軟に作れる CDK は触っていて楽しいです。
そして今年は Amplify で生成されたバックエンドリソースを CDK でカスタマイズできるようになったり、CDK か CloudFormation でカスタムリソースを作れるようになったりと Amplify x CDK が熱いです。
うどんが好きでカレーも好きな人はカレーうどんももちろん好きですよね?同じように Amplify が好きで CDK も好きな私のような人間にとってはこうしたアップデートはめちゃめちゃ気になる訳です。というわけで早速触ってみました。
実際に触ってみる
環境の確認
以下の環境で動作を確認しています。
$ node --version
v16.13.1
$ npm --version
8.1.2
$ amplify --version
7.6.4
React アプリの初期化
React アプリの初期化には Vite を使います。この記事では本格的に React アプリを開発するわけではないので Create React App でもいいっちゃいいんですがまぁ速く動く方が嬉しいですからね。
$ npm init vite@latest amplify-cdk-app -- --template react-ts
$ cd amplify-cdk-app
$ npm install
$ npm run dev
Amplify プロジェクトの初期化
以下のコマンドを実行します。
$ amplify configure
$ amplify init
Note: It is recommended to run this command from the root of your app directory
? Enter a name for the project amplifycdkapp
The following configuration will be applied:
Project information
| Name: amplifycdkapp
| Environment: dev
| Default editor: Visual Studio Code
| App type: javascript
| Javascript framework: react
| Source Directory Path: src
| Distribution Directory Path: build
| Build Command: npm run-script build
| Start Command: npm run-script start
? Initialize the project with the above configuration? Yes
Using default provider awscloudformation
? Select the authentication method you want to use: AWS profile
For more information on AWS Profiles, see:
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html
? Please choose the profile you want to use default
カスタムリソースの追加
いよいよお待ちかねのカスタムリソースを作成します。リソース名は customIVSChannel
とします。
$ amplify add custom
✔ How do you want to define this custom resource? · AWS CDK
✔ Provide a name for your custom resource · customIVSChannel
✅ Created skeleton CDK stack in amplify/backend/custom/customIVSChannel directory
✔ Do you want to edit the CDK stack now? (Y/n) · no
すると amplicy/backend/custom/customIVSChannel
ディレクトリが作成されます。 package.json
をみると CDK 1.124.0 が使われているようです。 cdk-stack.ts
にスタックを定義することでカスタムリソースを作成できます。また node_modules
があるのが気になりますね。
今回は IVS のチャネルを作るので package.json
に @aws-cdk/aws-ivs
を追加し、 cdk-stack.ts
で IVS チャネルを作成しましょう。 amplify/backend/custom/customIVSChannel/package.json
は以下のような感じで
{
"name": "custom-resource",
"version": "1.0.0",
"description": "",
"scripts": {
"build": "tsc",
"watch": "tsc -w",
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"@aws-amplify/cli-extensibility-helper": "^2.0.0",
"@aws-cdk/core": "~1.124.0",
"@aws-cdk/aws-ivs": "~1.124.0"
},
"devDependencies": {
"typescript": "^4.2.4"
}
}
amplify/backend/custom/customIVSChannel/cdk-stack.ts
は以下のようにします。
import * as cdk from '@aws-cdk/core';
import * as AmplifyHelpers from '@aws-amplify/cli-extensibility-helper';
import { AmplifyDependentResourcesAttributes } from '../../types/amplify-dependent-resources-ref';
import * as ivs from '@aws-cdk/aws-ivs';
export class cdkStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps, amplifyResourceProps?: AmplifyHelpers.AmplifyResourceProps) {
super(scope, id, props);
/* Do not remove - Amplify CLI automatically injects the current deployment environment in this input parameter */
new cdk.CfnParameter(this, 'env', {
type: 'String',
description: 'Current Amplify CLI env name',
});
const myChannel = new ivs.Channel(this, 'Channel', {
authorized: false
});
}
}
git push
まで)
CI/CD の準備( CodeCommit 作成から amplify push
してもいいですがせっかくなので CI/CD しちゃいましょう。簡単のため Git リポジトリは CodeCommit にしますが GitHub でもいけるはず。
$ aws codecommit create-repository --repository-name amplify-cdk
$ git init
$ git remote add origin https://git-codecommit.us-east-1.amazonaws.com/v1/repos/amplify-cdk
あとは CodeCommit にプッシュしましょう。
$ git add .
$ git commit -m 'initial commit'
$ git push origin master
CI/CD の準備( Amplify Console の設定)
ここからは AWS コンソールで Amplify Console の設定を行います。
CodeCommit を選択
リポジトリは amplify-cdk ブランチは master を選択
ビルド設定は CI/CD の有効化にチェックを入れる
ビルドスクリプトはデフォルトのままで Next をクリック
設定を確認してデプロイする
しばらく待つと CodeCommit からコードをクローンしてきてビルドが始まります。カスタムリソースも無事作成されて IVS のページに行くと以下のようにパブリックチャネルが作成されています。
CDK v2 への移行
私は CDK v2 が Developer Preview になった頃には CDK v1 から v2 に移っていたので CDK v1 を触るのは久しぶりでした。
CDK v1 は 2022 年 6 月 1 日からメンテナンスフェーズに入るので CDK v2 への移行を試してみましょう。
CDK v2 への移行はこのドキュメントに詳しく書かれています。CDK v2 だと ivs や ec2 などの各モジュールが aws-cdk-lib にまとまっているので管理がやりやすくなります。 amplify/backend/custom/customIVSChannel/package.json
は以下のような感じにします。
{
"name": "custom-resource",
"version": "1.0.0",
"description": "",
"scripts": {
"build": "tsc",
"watch": "tsc -w",
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"@aws-amplify/cli-extensibility-helper": "^2.0.0",
"aws-cdk-lib": "2.0.0",
"constructs": "^10.0.0"
},
"devDependencies": {
"typescript": "^4.2.4"
}
}
また CDK v1 だと @aws-cdk/core
に Stack や StackProps, Construct, CfnParameter があったのが CDK v2 だと Construct 以外は aws-cdk-lib
に移動しています。Construct だけ constructs
の中にあります。さらに IVS モジュールの話ですが CDK v2.0.0 の IVS モジュールには L2 Construct がありません。なので L1 Construct を使うことにします。 amplify/backend/custom/customIVSChannel/cdk-stack.ts
はこんな感じで違いがわかるように IVS のチャネルをプライベートに変更しました。
import { Stack, StackProps, CfnParameter } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as AmplifyHelpers from '@aws-amplify/cli-extensibility-helper';
import { AmplifyDependentResourcesAttributes } from '../../types/amplify-dependent-resources-ref';
import * as ivs from 'aws-cdk-lib/aws-ivs';
export class cdkStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps, amplifyResourceProps?: AmplifyHelpers.AmplifyResourceProps) {
super(scope, id, props);
/* Do not remove - Amplify CLI automatically injects the current deployment environment in this input parameter */
new CfnParameter(this, 'env', {
type: 'String',
description: 'Current Amplify CLI env name',
});
const myChannel = new ivs.CfnChannel(this, 'Channel', {
authorized: true
});
}
}
あとは git push
するだけで変更が反映されます。
$ git add amplify/backend/custom/customIVSChannel/cdk-stack.ts amplify/backend/custom/customIVSChannel/package.json
$ git commit -m 'migrate to CDK v2'
$ git push origin master
おわりに
Amplify プロジェクトの中で CDK も使えるようになるとバックエンドの作成がかなり柔軟になりそうです。私ならフロント側からアクセスするリソース ( AppSync とか API Gateway とか)は Amplify CLI で作成して細かい設定は CDK で override する、フロントからアクセスしないようなリソースは CDK のカスタムリソースで作成するかなぁと思いました。
Discussion