CDK を 1 ファイルで実行する
わたしは普段CDKを使っているのですが、まれにツールとして人に配りたいときがあります。
たとえば、ワークショップの実施なんかで初期構築をしたい時などです。
ここで問題になるのが、CDKをどうやって配布するかということです。
CloudFormationテンプレートなら1枚わたせばいいのですが、CDKだと基本的にはそうはいきません。
今回はDeno (TypeScript) を使い、cdk initで出てきたテンプレートから魔改造していきます。
① cdk init
最初にCDKのテンプレートを導入します。今回cdkコマンドはnpx経由で使っています。
npx cdk init app --language typescript
実行すると以下のようにファイルが沢山できあがります。

なお、今回は run-cdk-single-fileというプロジェクト名にしています。
② ファイルを整理する
ここからファイルをザクザクと消していきます。
まずはbinとlib以外のファイルを全て消します。

デフォルトでは、bin/run-cdk-single-file.tsの中身は以下のようになっています(読まなくていいです)。
#!/usr/bin/env node
import * as cdk from 'aws-cdk-lib/core';
import { RunCdkSingleFileStack } from '../lib/run-cdk-single-file-stack';
const app = new cdk.App();
new RunCdkSingleFileStack(app, 'RunCdkSingleFileStack', {
/* If you don't specify 'env', this stack will be environment-agnostic.
* Account/Region-dependent features and context lookups will not work,
* but a single synthesized template can be deployed anywhere. */
/* Uncomment the next line to specialize this stack for the AWS Account
* and Region that are implied by the current CLI configuration. */
// env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION },
/* Uncomment the next line if you know exactly what Account and Region you
* want to deploy the stack to. */
// env: { account: '123456789012', region: 'us-east-1' },
/* For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html */
});
また、lib/run-cdk-single-file-stack.tsは以下のようになっています(こちらも読まなくていいです)。
import * as cdk from 'aws-cdk-lib/core';
import { Construct } from 'constructs';
// import * as sqs from 'aws-cdk-lib/aws-sqs';
export class RunCdkSingleFileStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// The code that defines your stack goes here
// example resource
// const queue = new sqs.Queue(this, 'RunCdkSingleFileQueue', {
// visibilityTimeout: cdk.Duration.seconds(300)
// });
}
}
ここから
- 上記のファイルを一つにまとめる
- インポートパスに
npm:というプレフィックスをつけDeno対応する - Deno用のシバンをつける (権限は
-Aとして一旦全許可にしてます) - コメントアウトされているSQSのコードを復活させる
- コメントアウトされているenvのコードを復活させる
ということをします。これをルートディレクトリのrun-cdk-single-file.tsとします。
#! /usr/bin/env -S deno run -A
import * as cdk from "npm:aws-cdk-lib/core";
import { Construct } from "npm:constructs";
import * as sqs from "npm:aws-cdk-lib/aws-sqs";
export class RunCdkSingleFileStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
new sqs.Queue(this, "RunCdkSingleFileQueue", {
visibilityTimeout: cdk.Duration.seconds(300),
});
}
}
const app = new cdk.App();
new RunCdkSingleFileStack(app, "RunCdkSingleFileStack", {
env: {
account: Deno.env.get("CDK_DEFAULT_ACCOUNT"),
region: Deno.env.get("CDK_DEFAULT_REGION"),
},
});
③ CDKを実行する
※以下を実際に実行する場合は、ターミナルにAWS認証情報をセットするところから始めてください。
まず、tsファイルを実行するために、chmodを実行します:
chmod +x ./run-cdk-single-file.ts
次に、CDKを実行するのが初めての環境では、cdk bootstrapを実行する必要があります。
今回の場合はこうです:
# -a でCDKのアプリケーションを指定できる
npx cdk bootstrap -a ./run-cdk-single-file.ts
成功したら、実際にデプロイしてみましょう:
npx cdk deploy -a ./run-cdk-single-file.ts

CloudFormationで確認すると、実際にデプロイされているのがわかります!嬉しい!

④ Denoがなくても動かしたい
現在の実行方法ではローカルにDenoがあるマシンでしか実行できません。
そこで試してみたいのが、deno compileです。このコマンドを実行すると、Deno自身が同梱されたファイル(run-cdk-single-file)が出来上がります:
deno compile -A ./run-cdk-single-file.ts

ここでできたファイルを使って、再度Deployを実行します:
npx cdk deploy -a ./run-cdk-single-file

感想
これで、配布しやすいCDKが出来上がったのではないでしょうか?
本来はnpx cdkコマンドも同梱できると素晴らしいのですが…それはまたいずれ!