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