これ触ってみました。
インストール
上の公式にもありますが、npmでモジュール追加するだけです。これでcdkコマンドが使えるようになります。
$ npm install -g aws-cdk
使ってみる
架空の要件
何も無いと進めにくいので、架空の要件として、DynamoDBのMyUserテーブルをDev,Prodの2環境作ろうと思います。その際にキャパシティを別々に設定したいです。
開発
プロジェクト作成
まずはプロジェクト作ってみます。後は空のプロジェクトディレクトリに移動して、cdk init
をします。この際に言語を選択しますが、現時点ではTypescriptとJavaが選択可能です。Useful Commandsとしていくつか上がっていますが、それは後で書きます。
- プロジェクトディレクトリを作成
ここで作成したディレクトリ名を利用して、テンプレートが初期化されます。
$ mkdir projdynamo $ cd projdynamo/
- cdkプロジェクトの初期化
$ cdk init app --language typescript Initializing a new git repository... Applying project template app for typescript Executing npm install... npm notice created a lockfile as package-lock.json. You should commit this file. npm WARN projdynamo@0.1.0 No repository field. npm WARN projdynamo@0.1.0 No license field. # Useful commands * `npm run build` compile typescript to js * `npm run watch` watch for changes and compile * `cdk deploy` deploy this stack to your default AWS account/region * `cdk diff` compare deployed stack with current state * `cdk synth` emits the synthesized CloudFormation template
cdk init app
の app
は初期化するテンプレートの名前です。現状ではappとlibが選べるようです。libはライブラリそのものを作るものなので、普通の利用者はappを使うことが多いと思われます。
$ cdk init --list Available templates: * app: Template for a CDK Application └─ cdk init app --language=[java|typescript] * lib: Template for a CDK Construct Library └─ cdk init lib --language=typescript
初期のディレクトリ構造
以下のようなディレクトリ構造になります。 projdynamo.ts
に定義のコードを書いていきます。
├── README.md ├── bin/ │ └── projdynamo.ts ├── cdk.json ├── bin ├── cdk.json ├── node_modules/ ├── package-lock.json ├── package.json └── tsconfig.json
初期状態のスクリプトファイル
公式リポジトリのデモで使われているコードが初期に書かれています。今回はSNSやSQSは必要なくて、DynamoDBを使いたいです。
#!/usr/bin/env node import sns = require('@aws-cdk/aws-sns'); import sqs = require('@aws-cdk/aws-sqs'); import cdk = require('@aws-cdk/cdk'); class ProjdynamoStack extends cdk.Stack { constructor(parent: cdk.App, name: string, props?: cdk.StackProps) { super(parent, name, props); const queue = new sqs.Queue(this, 'ProjdynamoQueue', { visibilityTimeoutSec: 300 }); const topic = new sns.Topic(this, 'ProjdynamoTopic'); topic.subscribeQueue(queue); } } const app = new cdk.App(process.argv); new ProjdynamoStack(app, 'ProjdynamoStack'); process.stdout.write(app.run());
ドキュメント
DynamoDBの使い方を見るためにドキュメントを探します。cdkコマンドは該当のバージョンのドキュメントのURLまで生成してくれます。
$ cdk docs https://awslabs.github.io/aws-cdk/versions/0.8.1/
サービス毎の仕様はここに纏まっています。
https://awslabs.github.io/aws-cdk/versions/0.8.1/reference.html
例えば後で書くDynamoDBならここ。
https://awslabs.github.io/aws-cdk/versions/0.8.1/refs/_aws-cdk_aws-dynamodb.html
aws-cdk使って定義を書いてみる
先述のドキュメントを見ながら開発してみます。
上記のドキュメントにある通り、DynamoDBのモジュールをインポートします。
$ npm i @aws-cdk/aws-dynamodb@0.8.1
これ使って、先述の要件に沿って、上記のコードを少し修正してみました。ツッコミどころはありますが、気にしないでください。
なお、コード書いている際に npm run watch
を立ち上げておくとリアルタイムで静的チェックしてくれます。
#!/usr/bin/env node import dynamodb = require('@aws-cdk/aws-dynamodb') import cdk = require('@aws-cdk/cdk') class ProjdynamoStack extends cdk.Stack { constructor( parent: cdk.App, name: string, env: string, dynamodbProps: dynamodb.TableProps, props?: cdk.StackProps ) { super(parent, name, props) const userTable = new dynamodb.Table(this, `MyUser${env}`, dynamodbProps) userTable.addPartitionKey('id', dynamodb.KeyAttributeType.String) } } const app = new cdk.App(process.argv) new ProjdynamoStack(app, 'ProjdynamoStackDev', 'Dev', { readCapacity: 5, writeCapacity: 5 }) new ProjdynamoStack(app, 'ProjdynamoStackProd', 'Prod', { readCapacity: 10, writeCapacity: 10 }) process.stdout.write(app.run())
書き終わったらビルドします。エラー無く通れば完了。
$ npm run build
スタックのデプロイ
上記のビルドが終わった段階で、cdkコマンドでの作業に移ります。
スタックの一覧
listコマンドで一覧ができます。DevとProdの2スタックが定義されいます。複数スタックが定義されている場合はcdkコマンドの引数にスタック名を渡すことで任意のスタックを操作できるようになります。
$ cdk list -l - name: ProjdynamoStackDev environment: name: 012345678912/ap-northeast-1 account: '012345678912' region: ap-northeast-1 - name: ProjdynamoStackProd environment: name: 012345678912/ap-northeast-1 account: '012345678912' region: ap-northeast-1
デプロイ実行
cdk deploy
コマンドに上記から任意のスタック名を渡せばデプロイが実行されます。
$ cdk deploy ProjdynamoStackDev ⏳ Starting deployment of stack ProjdynamoStackDev... [0/2] Wed Aug 15 2018 20:12:42 GMT+0900 (JST) CREATE_IN_PROGRESS [AWS::CloudFormation::WaitConditionHandle] WaitCondition [0/2] Wed Aug 15 2018 20:12:42 GMT+0900 (JST) CREATE_IN_PROGRESS [AWS::CloudFormation::WaitConditionHandle] WaitCondition Resource creation Initiated [1/2] Wed Aug 15 2018 20:12:43 GMT+0900 (JST) CREATE_COMPLETE [AWS::CloudFormation::WaitConditionHandle] WaitCondition [2/2] Wed Aug 15 2018 20:12:45 GMT+0900 (JST) CREATE_COMPLETE [AWS::CloudFormation::Stack] ProjdynamoStackDev [0/4] Wed Aug 15 2018 20:12:58 GMT+0900 (JST) CREATE_IN_PROGRESS [AWS::CDK::Metadata] CDKMetadata [0/4] Wed Aug 15 2018 20:12:58 GMT+0900 (JST) CREATE_IN_PROGRESS [AWS::DynamoDB::Table] MyUserDev7ABD51C6 [0/4] Wed Aug 15 2018 20:12:58 GMT+0900 (JST) CREATE_IN_PROGRESS [AWS::DynamoDB::Table] MyUserDev7ABD51C6 Resource creation Initiated [0/4] Wed Aug 15 2018 20:13:00 GMT+0900 (JST) CREATE_IN_PROGRESS [AWS::CDK::Metadata] CDKMetadata Resource creation Initiated [1/4] Wed Aug 15 2018 20:13:01 GMT+0900 (JST) CREATE_COMPLETE [AWS::CDK::Metadata] CDKMetadata [2/4] Wed Aug 15 2018 20:13:29 GMT+0900 (JST) CREATE_COMPLETE [AWS::DynamoDB::Table] MyUserDev7ABD51C6 [2/4] Wed Aug 15 2018 20:13:32 GMT+0900 (JST) UPDATE_COMPLETE_CLEANUP_IN_PROGRESS [AWS::CloudFormation::Stack] ProjdynamoStackDev [2/4] Wed Aug 15 2018 20:13:34 GMT+0900 (JST) DELETE_IN_PROGRESS [AWS::CloudFormation::WaitConditionHandle] WaitCondition [3/4] Wed Aug 15 2018 20:13:35 GMT+0900 (JST) DELETE_COMPLETE [AWS::CloudFormation::WaitConditionHandle] WaitCondition [4/4] Wed Aug 15 2018 20:13:35 GMT+0900 (JST) UPDATE_COMPLETE [AWS::CloudFormation::Stack] ProjdynamoStackDev ✅ Deployment of stack ProjdynamoStackDev completed successfully, it has ARN arn:aws:cloudformation:ap-northeast-1:123456789012:stack/ProjdynamoStackDev/1f2afd20-a07c-11e8-9539-50a68669984a
スタックを差分を確認
readCapacityを変えてみました。git diffで確認します。
$ vim bin/projdynamo.ts $ git diff -U0 diff --git a/bin/projdynamo.ts b/bin/projdynamo.ts index 246cf4b..c2bc1e9 100644 --- a/bin/projdynamo.ts +++ b/bin/projdynamo.ts @@ -23 +23 @@ new ProjdynamoStack(app, 'ProjdynamoStackDev', 'Dev', { - readCapacity: 5, + readCapacity: 10,
ビルドします。
$ npm run build
これでcdk diffコマンド打つことで、現行のスタックとの差分を取ってくれます。
$ cdk diff ProjdynamoStackDev [~] 🛠 Updating ProjdynamoStackDev7ABD51C6 (type: AWS::DynamoDB::Table) └─ [~] .ProvisionedThroughput: └─ [~] .ReadCapacityUnits: ├─ [-] Old value: 5 └─ [+] New value: 10
CloudFormationの定義をダンプ
cdk synth
コマンドで実際のCloudFormationの定義のダンプも可能です。
$ cdk synth ProjdynamoStackDev Resources: MyUserDev7ABD51C6: Type: 'AWS::DynamoDB::Table' Properties: KeySchema: - AttributeName: id KeyType: HASH ProvisionedThroughput: ReadCapacityUnits: 5 WriteCapacityUnits: 5 AttributeDefinitions: - AttributeName: id AttributeType: S CDKMetadata: Type: 'AWS::CDK::Metadata' Properties: Modules: '@aws-cdk/aws-dynamodb=0.8.1,@aws-cdk/cdk=0.8.1,@aws-cdk/cx-api=0.8.1,js-base64=2.4.5,projdynamo=0.1.0'
スタックの削除
destroyでスタックの削除も可能です。
$ cdk destroy ProjdynamoStackDev
使ってみての所感
個人的感想も多分に含まれていますが。
良さそうな部分
- 型付けで書けるのでIDEとの連携も含めて書くのが楽。覚えることも少ないと思う。(今回はVSCode使いました)
- YAMLやJSONより見通しが良く感じる
- ライブラリのコード内にコメントがある(関連するCloudFormationの仕様へのリンクなど)のでIDEで定義にジャンプすると関連情報へたどり着きやすい
- !Subや!Refや色々でゴニョゴニョやっていた部分をスマートに書ける
大変そうな部分
- TypescriptかJavaの知識が必須(この分野を使う人にはプログラム苦手意識がある人も多いかも)
- npm等のNode.jsの開発知識が無いと何かあった時に迷いそう
- 良くも悪くも書き方の自由度が大幅に増す。この記事に載せたような適当なコードでもコンパイルしてしまえば動きは一緒になってしまうので、後々のメンテ考えれば、ある程度のルールは必要かも
参考
以下の公式のサンプル見ると早いです。