Open8

AWS CDK + TypeScriptで構成管理できる環境を作る

okomeworldokomeworld

aws-cdkをグローバルにインストールする

npm i -g aws-cdk

最初git管理することを考えてディレクトリ作ってから諸々init(gitとかnpmとか)してcdk initを実行しようとしてみたところ、その辺りひっくるめてcdk initで生成するようだったので、とりあえずグローバルに持つようにした

okomeworldokomeworld

プロジェクトディレクトリ作って cdk init を実行する

mkdir cdk-sample && cd $_;
cdk init app --language typescript

appの部分がよくわからなかったので軽く調べてみたところ、初期化時のファイル構成テンプレートが複数あって cdk init すると一覧が表示されるらしい

$ cdk init
Available templates:
* app: Template for a CDK Application
   └─ cdk init app --language=[csharp|fsharp|go|java|javascript|python|typescript]
* lib: Template for a CDK Construct Library
   └─ cdk init lib --language=typescript
* sample-app: Example CDK Application with some constructs
   └─ cdk init sample-app --language=[csharp|fsharp|java|javascript|python|typescript]

↑の三種類についても軽く検索かけてみたけど、詳しく説明してくれてそうなドキュメントに出会えなかったのでとりあえず app を選択しておく(appが基本的な構成になっているらしい)

cdk init したらInitial commitまでしてくれてたけど、package-lock.jsonだけ取り残されていたのでそれもInitial commitに入れてしまうことにした

git add .
git commit --amend
okomeworldokomeworld

構成管理の環境は整った

今回、Lambda関数を定期実行させてみたいと思っているので、それもcdkでデプロイしてみる

ということで、必要なモジュールをインストール

npm i -S @aws-cdk/events @aws-cdk/events-targets @aws-cdk/aws-iam @aws-cdk/aws-lambda-nodejs
  • events は定期実行するためのCloudWatchEvent設定を定義するためのモジュール
  • events-targets はCloudWatchEventで発火するリソース対象(今回はLambda関数)を定義するためのモジュール
  • aws-iam はIAM定義のため。根塊はCloudWatchのログにとりあえず何か吐き出す関数を動かして見るのでその権限を割り当てるために使う
  • aws-lambda-nodejs は任意のコードファイルを指定してLambda関数として扱えるようにするモジュール。従来なら @aws-cdk/aws-lambda を使うようだが、こいつを使えばTypeScriptで書いたコードを勝手にトランスパイルしてLambda関数化してくれるらしい
okomeworldokomeworld

適当にコード書いて構成設定の追加までやってみる

まずLambda関数として扱うファイルを作成(コードの中身は省略)

mkdir -p lambda/handlers
touch lambda/handlers/hello.ts # ここにLambda関数として実行するコードを書く
okomeworldokomeworld

lib/cdk-sample-stack.ts に定義を追記すれば構築してくれるらしいので書いてみる

diff --git a/lib/cdk-sample-stack.ts b/lib/cdk-sample-stack.ts
index 17b6a40..128b98b 100644
--- a/lib/cdk-sample-stack.ts
+++ b/lib/cdk-sample-stack.ts
@@ -1,9 +1,43 @@
 import * as cdk from '@aws-cdk/core';
+import * as iam from '@aws-cdk/aws-iam';
+import { NodejsFunction } from '@aws-cdk/aws-lambda-nodejs';
+import { Rule, Schedule } from '@aws-cdk/aws-events';
+import { Duration } from '@aws-cdk/core';
+import { LambdaFunction } from '@aws-cdk/aws-events-targets';
 
 export class CdkSampleStack extends cdk.Stack {
   constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
     super(scope, id, props);
 
-    // The code that defines your stack goes here
+    // Lmabda関数に付与するIAMロールを生成
+    const role = new iam.Role(this, 'HelloFunctionRole', {
+      assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
+      path: '/service-role/',
+      inlinePolicies: {
+        CloudWatchWritePolicy: new iam.PolicyDocument({
+          statements: [
+            new iam.PolicyStatement({
+              actions: [
+                'logs:CreateLogGroup',
+                'logs:CreateLogStream',
+                'logs:PutLogEvents',
+              ],
+              resources: ['*'],
+            })
+          ]
+        })
+      }
+    });
+
+    // Lambda関数を生成
+    const lambdaFunction = new NodejsFunction(this, 'hello', {
+      entry: 'lambda/handlers/hello.ts',
+    });
+
+    // 1分おきに実行してみる
+    new Rule(this, 'ScheduledHelloEvent', {
+      schedule: Schedule.rate(Duration.minutes(1)),
+      targets: [new LambdaFunction(lambdaFunction)]
+    });
   }
 }

この辺は↓の記事を参考にさせてもらった

https://itotetsu.hatenablog.com/entry/cloudwatch-events-via-aws-cdk#必要なパッケージをインストールする

okomeworldokomeworld

デプロイしてみる

初回構築時には cdk bootstrap を実行する必要があるらしいので実行する

npx cdk boottrap

すごく早く処理が終わった感がある。もしかしたらどっかのタイミングで既に実行されていたのかもしれない。

続けて cdk deploy を実行

npx cdk deploy

本当にdeployするかい?的なこと聞かれるのでyを押して実行。暫く待つ。ターミナルに出てくるログがamplifyと比べると見やすい

okomeworldokomeworld

deploy完了後、スタック等諸々チェック。

もしかしたらTypeScriptのトランスパイルは別途実行してあげないといけなかったりするのかなーとか思ってたけどほんとに全部やってくれてた。ので1分おきにちゃんとログを吐いてくれていた。すごい。

okomeworldokomeworld

ここまでの所感

  • 思ってより簡単だった。Amplifyより親切さを感じる
  • 構成定義は結局CloudFunctionに準じてる感があるので、jsonを空で書ける必要はないけどどういったものがあるのかの学習は必要そう
    • ただTypeScriptで書けるので、ある程度覚えればVSCodeのサジェストなどで補助してもらえるので、少なくともjson書くよりはつらくないし学習しやすいと思う
  • aws cliのアカウント設定でデプロイされると思ってたけどリージョンがus-east-1になってた(設定は東京リージョン)。bin/cdk-sample-stack.ts にそれっぽい設定例がコメントアウトされていたので、そこを修正して上げる必要があるのかもしれない

思ったよりスムーズにできてよかった。今後は関数をローカル実行できるようにしていきたい。これは別のスクラップでやろうと思う。