AWS CDKまとめ、TIPS


概要

2019年7月にAWS CDKがGA(generally available)になり、気になっている方も多いのではないかと思います。私は最近AWS CDKをがっつり使い始めたので、入門知識から勘所までまとめていきたいと思います。周りのエンジニアの感想をきてみても「めちゃめちゃいい」という意見が多かったので、是非みなさん一度試してみてください。

ちなみに、個々のリソースの記述方法に関しては色々な記事が出ているので省略し、本記事は概観とTIPSを記載します。

AWS CDKとは

  • AWSインフラをコード化するツール
  • 真の意味で抽象化されたIaCが実現可能
  • 基本的にTypeScriptで記述します。Pythonなどでも記述できますが、内部的にはnode.jsを起動しています。
  • CDKの実行時は、コードからCloudFormationテンプレートを作成して実行しますので、動作がブラックボックス化しにくいのも魅力です。
  • その他AWS DevDayの資料などによくまとめて頂いています。

hello world

$ npm i -g aws-cdk // cdkコマンドをインストール
$ mkdir hello-cdk
$ cd hello-cdk
$ cdk init sample-app --language=typescript

これでアプリの雛形が生成されました。

ファイル階層

結構シンプルです。

helle-cdk
|-- bin libで定義したスタックを読み込んで初期化します
|-- lib スタックごとにファイルを分けて定義を記載します。
|-- test
|-- cdk.json
|-- tsconfig.json
|-- jest.config.js

cdk.jsonにはdeploy時の動作が記載されています。

{
  "app": "npx ts-node bin/hello.ts"
}

ts-nodeというtscやwebpackなどでコンパイルせずに'node'のように実行するツールを使用して、bin/hello.tsを実行しています。

デプロイ

$ cdk deploy

また

$ cdk synth

でCloudFormationテンプレートを生成します

開発

開発の進め方を説明します。

前提知識

コンストラクタ

最初の生成されたlib/hello-stack.tsはこんな感じです。

lib/hello-stack.ts
export class HelloStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const queue = new sqs.Queue(this, 'HelloQueue', {
      visibilityTimeout: cdk.Duration.seconds(300)
    });

    const topic = new sns.Topic(this, 'HelloTopic');

    topic.addSubscription(new subs.SqsSubscription(queue));
  }
}

例えば、SNS Queueはnew sqs.Queue...で生成しています。コンストラクタの引数は基本的に 1 this(cdk.Stack), 2 id: string, 3 パラメータです。ちなみに、この時に動かすコンストラクタをhight-levelコンストラクトと言います。これは、オールインワンパッケージのようなもので、デフォルトの設定とか、普通そうするだろうというベストプラクティス設定とか、デフォルトのIAMポリシーとか諸々を含んだものです。そのため、visibilityTimeoutしか指定していませんが、しっかりと設定されたSQS::Queueが生成されます。

一方 low-level コンストラクトも存在し、クラス名の先頭に必ず'Cfn'付きます。これはCloudFormationと一対一で対応するプロパティーを提供します。試しにsqs.CfnQueueのパラメータに設定する'visibilityTimeout'の定義をみてみると、以下の通りに記載されており、一対一対応しているCloudFormationテンプレートのプロパティーへのリンクが記載されています。(超親切)

/**
* `AWS::SQS::Queue.VisibilityTimeout`
* @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sqs-queues.html#aws-sqs-queue-visiblitytimeout
*/
readonly visibilityTimeout?: number;

High-levelコンストラクトはlow-levelコンストラクトを組み合わせて実装されています。両者の使いわけとして、基本はhigh-levelの方を使用しますが、対応していない新しいリソースの設定や、細かな設定をする際はやむなくlow-levelコンストラクトを使用する必要がある場合があります。

ドキュメントの見方

公式のドキュメントを参照します。
AWS CDK · AWS CDK Reference Documentation
左ナビにリソースの分類がずらっと並んでいますので、必要な部分を参照します。初めて使用するリソースに関しては 'overview' を確認するとわかりやすく、コードレベルでざっくりと使用方法が書かれています。

スクリーンショット 2019-11-16 17.45.51.png

その後、Constructsから必要なリソースの詳細を確認してください。

TIPS

書き方は複数通り存在する

複数のリソース間の依存関係を定義する時は、書き方が複数存在することが多いです。例えば、S3にトリガイベントを設置する時は、S3にトリガイベントを定義することもできるし、S3で呼び出すLambdaのイベントソースにS3を指定することもできます。なので、方法に迷った際はあまりこだわらず、どちらの思考が分かりやすいかをアプリケーションに合わせて判断するのが良いかと思います。

必要なリソースは自分で追加する

今回のハンズオンではインストールされていないリソースが多数あります。必要なものは

npm i --save @aws-cdk/aws-lambda

などで、インストールしてください。
その際、私の環境の問題かもしれませんが、型エラーが発生する場合があります。その場合は以下のコマンドを実行すると解決します。

cd node_modules/@aws-cdk
rm -rf */node_modules

バグは多い

まだ2019年7月にgaになったばかりですので、明らかにバグと言える症状には割とすぐに遭遇するし、Issueも多数上がっているのが現状です。
しかし、割と細かい設定まで十分実用的なレベルで非常に使いやすいツールなので、全てをコード上に表現しきりたいという過激派思想とうまく 折り合いをつけながら、できる範囲で使用をしていくのが良いかなと思っています。