要約
- Denoを使うことでNodeなしにAWS CDKを動作できる!
- これによりnpmツールチェーンのセットアップ、管理の手間から開放される!(…かも?)
- これはDenoのnpmサポートが強化されたため可能になった
まずは動かしてみましょう
-
Denoをインストールします
CDKアプリケーションコードの型チェックをする場合Deno v1.28.2以上である必要があります -
以下の2ファイルを用意します
Denoの設定ファイルであるdeno.jsonc
です。主にタスクランナーの設定がしてあります。// deno.jsonc { "tasks": { "cdk": "deno run --allow-all npm:aws-cdk --app 'deno run --allow-all main.ts'", "test": "deno test --allow-all", "ci": "deno fmt --check && deno lint && deno task test" }, "lint": { "files": { "exclude": ["cdk.out"] } }, "fmt": { "files": { "exclude": ["cdk.out"] } } }
CDKアプリケーションコードです。シンプルなリソースであるロググループを作成しています。
// main.ts import cdk from "npm:aws-cdk-lib"; const app = new cdk.App(); export const stack = new cdk.Stack(app, "DenoCdkStack"); new cdk.aws_logs.LogGroup(stack, "DenoCdkLogGroup");
-
ターミナルから実行します
Denoのタスクランナー経由で実行するためdeno task cdk <CDKサブコマンド>
で呼び出します。deno task cdk synth
実行結果(クリックして展開)
Task cdk deno run --allow-all npm:aws-cdk --app 'deno run --allow-all main.ts' "synth" Resources: DenoCdkLogGroup24F7F268: Type: AWS::Logs::LogGroup Properties: RetentionInDays: 731 UpdateReplacePolicy: Retain DeletionPolicy: Retain Metadata: aws:cdk:path: DenoCdkStack/DenoCdkLogGroup/Resource CDKMetadata: Type: AWS::CDK::Metadata Properties: Analytics: v2:deflate64:H4sIAAAAAAAA/zPSMzXQM1BMLC/WTU7J1s3JTNKrDi5JTM7WAQrF5+SnF+tV++SnuxfllxboOKflwdi1IE5QanF+aVFyKojtnJ+XklmSmZ9Xq5OXn5Kql1WsX2ZopmdoDjQ9qzgzU7eoNK8kMzdVLwhCAwCBVnBAeQAAAA== Metadata: aws:cdk:path: DenoCdkStack/CDKMetadata/Default Condition: CDKMetadataAvailable Conditions: CDKMetadataAvailable: Fn::Or: - Fn::Or: - Fn::Equals: - Ref: AWS::Region - af-south-1 - Fn::Equals: - Ref: AWS::Region - ap-east-1 - Fn::Equals: - Ref: AWS::Region - ap-northeast-1 - Fn::Equals: - Ref: AWS::Region - ap-northeast-2 - Fn::Equals: - Ref: AWS::Region - ap-south-1 - Fn::Equals: - Ref: AWS::Region - ap-southeast-1 - Fn::Equals: - Ref: AWS::Region - ap-southeast-2 - Fn::Equals: - Ref: AWS::Region - ca-central-1 - Fn::Equals: - Ref: AWS::Region - cn-north-1 - Fn::Equals: - Ref: AWS::Region - cn-northwest-1 - Fn::Or: - Fn::Equals: - Ref: AWS::Region - eu-central-1 - Fn::Equals: - Ref: AWS::Region - eu-north-1 - Fn::Equals: - Ref: AWS::Region - eu-south-1 - Fn::Equals: - Ref: AWS::Region - eu-west-1 - Fn::Equals: - Ref: AWS::Region - eu-west-2 - Fn::Equals: - Ref: AWS::Region - eu-west-3 - Fn::Equals: - Ref: AWS::Region - me-south-1 - Fn::Equals: - Ref: AWS::Region - sa-east-1 - Fn::Equals: - Ref: AWS::Region - us-east-1 - Fn::Equals: - Ref: AWS::Region - us-east-2 - Fn::Or: - Fn::Equals: - Ref: AWS::Region - us-west-1 - Fn::Equals: - Ref: AWS::Region - us-west-2 Parameters: BootstrapVersion: Type: AWS::SSM::Parameter::Value<String> Default: /cdk-bootstrap/hnb659fds/version Description: Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip] Rules: CheckBootstrapVersion: Assertions: - Assert: Fn::Not: - Fn::Contains: - - "1" - "2" - "3" - "4" - "5" - Ref: BootstrapVersion AssertDescription: CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI.
動きました!🎉
テストも追加する場合
- 以下のテストコードを配置します
スナップショットテスト機能を使ったCloudFormationテンプレート全体のチェックをします。// main.test.ts import { assertSnapshot } from "https://deno.land/std@0.167.0/testing/snapshot.ts"; import { Template } from "npm:aws-cdk-lib/assertions"; import { stack } from "./main.ts"; Deno.test("Snapshot Test", async (t) => { await assertSnapshot(t, Template.fromStack(stack).toJSON()); });
- ターミナルから実行します
初回でスナップショットが作成されていないので、まずは作成します。
完了後に__snapshots__/main.test.ts.snap
が生成されます。スナップショットを更新しない場合(変更がないことを確信している)はdeno task test -- --update
--update
オプションなしで実行します。
Snapshotと差分がある場合はテスト失敗になります。deno task test
- CI環境でフォーマッター、リンター、テストのチェックを行う場合のために
ci
タスクも定義してありますdeno task ci
何がうれしいのか?
一言でいうとNodeとnpmエコシステムの複雑さが一掃されるという点に付きます。
上記の手順の通り設定ファイルはDenoのdeno.jsonc
しか設定していません!
それなのに型チェックやフォーマッター、リンター、テストフレームワーク、必要なモノが全て揃った環境が手に入ります。
更にVSCode + Denoプラグインの環境を用意するだけで、コード補完や型チェックができる環境が出来上がります。
Node + npmでリンター、フォーマッター、テスト環境を揃えた場合
Denoを使わない場合
- TypeScript, ts-node (TypeScript)
- npm or yarn or pnpm (パッケージマネージャ)
- Prettier (フォーマッター)
- ESLint (リンター)
- Jest (テストフレームワーク)
これらの設定がそれぞれ必要です。(IDEがある場合更にそれぞれのプラグインの設定も必要)
これらのバージョン、トレンド、ベストプラクティスも刻一刻と変化/進化しており追随するのは大変です。(特にTypeScript用の設定が難しくてよくわからずハマりがち)
特にこの記事を読んで頂いているCDKを扱うような方々はAWSインフラがメインであることがほとんどのはずです。
re:Inventの新サービスや機能1を追っかけるだけでも大変なのに、
「npmとyarnどれがいい?yarnのメジャーバージョンアップするべき?」とか
「ESLintとPrettierの推奨組み合わせ方法が変わった」2とか正直追っかけてらんないし、やりたくないですよね?
私はやりたくないです😊
Denoの動向
これが可能になったのはごく最近Deno v1.28からnpm指定子をサポートするようになったためです。
これにより多くのnpmパッケージがDeno上で動作するようになりました。
GA当初のバージョンではCDKアプリケーションコードのタイプチェックがうまく行かない問題がありましたが、DenoリポジトリにIssueを報告して直してもらっています。
かつてのDenoでは
Denoは従来、npmパッケージを動かすにはCDN側でESMに変換しESMとして実行するという方式をとっていました。
過去の記事ではその方式で試していましたが、DenoのCDN側の不安定さやDenoのnode互換性の不足によりCDK CLIが動かなかったり、タイムアウトしたりで残念ながら実戦投入できるレベルではありませんでした。
これらの記事は本記事とは別の方法であるため、混同しないようご注意下さい。
注意点
もちろん現状使っているNode + CDKの環境をDenoにすぐ移行できるとは限りません。
おそらくNodeプロジェクト構成を前提としているCDKのNodeJsFunctionクラスなどの実装は動かないでしょう。
また、ESLintは柔軟なプラグイン機構によりルールを追加することができますが、Denoのリンターはそういった機構がなさそうなため、移行する際はチェックできないルールがあるかもしれません。(個人的にはCDKアプリケーションコードにそこまで厳密なチェックが必要とも思わないですが…)
他にも単純には移行できない部分もあるかと思うので、きちんと検証の上自己責任でご利用ください。
またDenoのパーミッションが簡略化のため全許可になっておりますので気になる場合修正ください。
追記
deno task cdk deploy
が動きませんでしたすみません…
まだ完全移行の道は長そうです…
追記2
以下のバージョンでdeno task cdk deploy
も動作することを確認しました
バージョン | |
---|---|
Deno | 1.37.2 |
AWS CDK | 2.102.0 |