NxでCDKを使いたい
Nxとはnwrl社が開発するモノレポ環境用のビルドツールです。
とにかく高速に動作することを謳っています。
今回はNxでAWS CDKを使うための設定を紹介しようと思います。
環境
- OS
- macOS 13.0.1(22A400)
% node -v
v18.12.1
% npm -v
8.19.2
% yarn -v
1.22.19
"dependencies": {
"@nrwl/next": "15.4.2",
"aws-cdk": "^2.51.1",
"aws-cdk-lib": "^2.51.1",
"constructs": "^10.1.164",
},
"devDependencies": {
"@ago-dev/nx-aws-cdk-v2": "^1.3.1",
"@nrwl/workspace": "15.4.2",
"nx": "15.4.2",
"typescript": "~4.8.2"
}
- サンプルのリポジトリはこちら
やってみる
まずはプラグインをインストールします。
プラグインは以下で検索できます。
cdk
で検索すると、現時点では2つしか存在せず、一つはcdk v1なので、v2で使おうと思ったら実質選択肢は一つしかありません。
これを使わなくても自分でgenerator
等を作れば良いですが、今回はとりあえずこちらを使います。
yarn add -D @ago-dev/nx-aws-cdk-v2
プラグインがインストールできたら、project.json
にコマンドが増えています。
...
targets": {
"deploy": {
"executor": "@ago-dev/nx-aws-cdk-v2:deploy",
"options": {}
},
"destroy": {
"executor": "@ago-dev/nx-aws-cdk-v2:destroy",
"options": {}
},
"bootstrap": {
"executor": "@ago-dev/nx-aws-cdk-v2:bootstrap",
"options": {}
},
"lint": {
"executor": "@nrwl/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["apps/sample-app-cdk/**/*.ts"]
}
},
...
まずはcdk用のprojectを作ってみます。
yarn nx generate @ago-dev/nx-aws-cdk-v2:application sample-app-cdk
sample-appというアプリ用のcdk codeというイメージです。
cdk init
で作ったときと比べると、package.json
がなかったり、bin
がなかったりします。
src
のなかのmain.ts
がエントリポイントになっていて、src/stacks/app-stack.ts
に実際のリソースを定義せよということだと理解したので、こちらに適当にS3バケットとそこにNext.jsのアプリをデプロイする設定を書いてみます。
import { App, RemovalPolicy, Stack, StackProps } from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as s3deploy from 'aws-cdk-lib/aws-s3-deployment';
export class AppStack extends Stack {
constructor(scope: App, id: string, props?: StackProps) {
super(scope, id, props);
const bucket = new s3.Bucket(this, 'Bucket', {
removalPolicy: RemovalPolicy.DESTROY,
});
new s3deploy.BucketDeployment(this, 'BucketDeploy', {
sources: [s3deploy.Source.asset('../sample-app/.next')],
destinationBucket: bucket,
});
}
}
注意点としてはSource.asset('path')
のpath
はこのcdkアプリケーションのプロジェクトルートから見たときの相対パスです。
現状apps/
の下にsample-app
とsample-app-cdk
が横並びになっているので、そこのパスは../sample-app/
になります。
これをデプロイするには以下のコマンドを実行します。
yarn nx deploy sample-app-cdk
これで通常通りデプロイできます。
用意されているコマンド以外のコマンドを使いたいとき
CodePipeline
に載せたかったので、それだとどうしてもsynth
コマンドが使える必要があります。
はじめはpluginを拡張したり、自作する必要があるのかと思っていたんですが、単にコマンドを追加するだけならもっと簡単にできました。
cdkのproject.json
に以下のように追記します。
"targets": {
+ "synth": {
+ "executor": "nx:run-commands",
+ "options": { "command": "cdk synth", "cwd": "apps/sample-app-cdk" }
+ },
"deploy": {
"executor": "@ago-dev/nx-aws-cdk-v2:deploy",
"options": {}
},
"destroy": {
"executor": "@ago-dev/nx-aws-cdk-v2:destroy",
"options": {}
},
executor
にnx:run-commands
を指定して、options
のcommand
に実行したいコマンドを渡してやると、package.json
のscripts
に追加する感覚でスクリプトを追加できます。
(公式ドキュメントを読んでもなかなか理解できなくて、小一時間ハマりました、、、)
あとは同じように
yarn nx synth sample-app-cdk
と実行してやると、無事cdk synth
が行えました🎉
試していないですが、同様のことをすればcdk diff
とかも実行できると思います。
まとめ
Nxに関しては、そもそもGoogleで検索しづらいし(車の記事が出てくる、、、)ドキュメントも分かりづらいし、QiitaやZennでも記事が少なく、結構ハマったときに抜け出しにくいなと思いました。
ただ、cdkはともかくNext.jsのプロジェクトを作ったり共通componentを追加したりする開発体験はとても良かったので、もうちょっと頑張って整えて使っていこうかなと思います💪
Discussion