cdkでDynamoDBをLamdbaのイベントソースに指定する

Lambda関数のイベントソースにDynamoDBを設定する手順をCDKを用いてやってみました。意外とシンプルです。
2020.04.27

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

cdkでLambdaのイベントソースにDynamoDBを設定する必要がありましたが、新規Tableではなく既存のTableを使う場合の方法があまり見当たらず、公式ドキュメントを読みながらの実装となりました。

実際にどうやって書くのか、紆余曲折が多かったこともあり、備忘録含めてまとめてみました。

既存Tableリソースの呼び出し

fromTableNameを利用します。必要なものはTable名です。ARNを用いる方法もありますが、Table名が固定であれば、ARN入力ミスを見越して個人的にはTable名の指定をおすすめします。新規リソースではないため、newは使用しません。

import cdk = require( '@aws-cdk/core' );
import dynamodb = require('@aws-cdk/aws-dynamodb');

export class CdkStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    const exsitsTable = dynamodb.Table.fromTableName(
      this, 'sample table', 'sample_table'
    )
  }
}

Lambdaのイベントソースに指定する

Lambda関数のaddEventSourceに指定します。startingPosition: lambda.StartingPosition.LATESTの指定により、最後に追加されたレコードがLambda関数に届きます。

import cdk = require( '@aws-cdk/core' );
import dynamodb = require('@aws-cdk/aws-dynamodb');
import lambda = require('@aws-cdk/aws-lambda');
import iam = require('@aws-cdk/aws-iam');
 
export class CdkStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    const exsitsTable = dynamodb.Table.fromTableName(
      this, 'sample table', 'sample_table'
    )

    const executionLambdaRole = new iam.Role(this, 'SecureLambdaRole', {
      roleName: 'secureExecutionRole',
      assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
      managedPolicies: [
        iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole'),
      ]
    });

    const exampleFunction = new lambda.Function(this, 'triggerFromDynamoDB', {
      functionName: 'exampleFunction',
      runtime: lambda.Runtime.PYTHON_3_8,
      code: lambda.AssetCode.fromAsset('/path/to/lambda_function'),
      handler: 'function.lambda_hundler',
      timeout: cdk.Duration.seconds(900),
      role: executionLambdaRole,
      environment: {
        TZ: "Asia/Tokyo",
      }
    });

    exampleFunction.addEventSource(
      new DynamoEventSource(exsitsTable, {
        startingPosition: lambda.StartingPosition.LATEST,
      })
    );
  }
}

あとがき

CDKの公式ドキュメントを読むのみでは、イベントソースの扱いがやや分かり辛かったため、とりあえず書いては試すという繰り返しをしていました。実際にはDynamoDB TableからのTrigger動作はすぐに完了し、一番大変だったのはtsファイルのビルドが通るまでの間でした。

aws-lambda-event-sources module · AWS CDK

スタックへの既存リソース流用はDynamoDBのみならず、他のリソースでも可能です。環境変数等をフラグに用いることで新規作成か既存流用等の分岐が出来ることも確認しています。boto3よりもシンプルに扱えるため、コードベースでインフラリソースを管理したい場合には特におすすめです。