@ito_tetsushi

東京・神奈川のサーバーレス / Web / モバイルアプリエンジニア

AWS CDKでCloudWatch EventsでLambdaを定期実行(TypeScript版)

概要

AWS CDK(Cloud Development Kit)は、AWS上のリソースをPython / Java / .NET / TypeScriptを使って構築することができるフレームワークです。 CloudWatch Eventsは、AWS上のサービスの変更に関するイベントをトリガーにして他のアクションを起動できる仕組みを提供します。 また、cronのように定期的にイベントを発行する機能もサポートされています。

動作確認

  • aws-cdk@1.6.1

AWS CDKのCLIをインストール

$ npm i -g aws-cdk

AWS CDKのプロジェクトを作成

# ディレクトリを作成
$ mkdir events

# ディレクトリに移動
$ cd events

# AWS CDKプロジェクトを作成
$ cdk init app --language=typescript

この時点でのディレクトリは以下のようになっています。

$ tree . -I node_modules
.
├── README.md
├── bin
│   └── cognito.ts
├── cdk.json
├── lib
│   └── cognito-stack.ts
├── package-lock.json
├── package.json
└── tsconfig.json

必要なパッケージをインストールする

AWS CDKでは、AWSの各リソースを構築するためのクラスはそれぞれ別パッケージとなっています。 次のコマンドでCloudWatch Events / Lambda / イベントソースとLambda関数の関連付け を構築するためのパッケージをインストールします。

$ npm i @aws-cdk/aws-iam @aws-cdk/aws-lambda @aws-cdk/aws-events @aws-cdk/aws-events-targets

イベントをトリガーにして起動するLambda関数本体を作成する

resources/lambda-function/index.js を以下の内容で作成します。 シンプルにログを出力するだけの関数です。

exports.handler = async events => {
  console.log(event);
  return {};
};

リソースを生成するコードを追加する

定期的にイベントを発行するCloudWatch Eventsの設定と、イベントをトリガーにして起動するLambda関数を作成します。 lib/events-stack.ts を以下のように変更します。

時刻を指定する場合、GMT時刻で指定しなければいけないことに注意してください。 日本だと意図した時間の9時間前の時刻をコードに書けばOKです。

import cdk = require("@aws-cdk/core");
import iam = require("@aws-cdk/aws-iam");
import lambda = require("@aws-cdk/aws-lambda");
import events = require("@aws-cdk/aws-events");
import eventsTargets = require("@aws-cdk/aws-events-targets");

export class EventsStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Lambda関数に付与するIAMロールを生成
    const role = new iam.Role(this, "SampleFunctionRole", {
      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 lambda.Function(this, "SampleFunction", {
      code: lambda.Code.asset("resources/sample-function"),
      handler: "index.handler",
      runtime: lambda.Runtime.NODEJS_10_X,
      role: role
    });

    // 毎日19:00に発火するイベントを生成
    new events.Rule(this, "ScheduleEvent", {
      // 注意:GMTで指定
      schedule: events.Schedule.cron({
        minute: "0",
        hour: "10",
        day: "*",
        month: "*",
        year: "*"
      }),
      targets: [new eventsTargets.LambdaFunction(lambdaFunction)]
    });
  }
}

AWS CDKで構築したリソースをデプロイする

# TypeScriptをコンパイル
$ npx tsc

# リソースをデプロイ
$ npx cdk deploy

リソースを削除する

# リソースを削除する
$ npx cdk destroy