2020-12-05

AWS CDK + SAM CLI で Lambda 関数をローカルで動かす

この記事は AWS その2 Advent Calendar 2020 の 5 日目の記事です。前回は @gsy0911 さんによるreInvent2020で発表されたLambdaContainerをCDKで実装してみるです。

CDK で定義した API Gateway + Lambda をローカルで実行する話です。

基本的にはこのあたりの焼き直しなのですが、自分や同僚の環境だとこの手順ではうまくいかなかったので改めてうまくいった手順を記しておこうと思います。

尚以下の方法でも HTTP API(ApiGatewayV2)は認識してくれません。Lambda 単体(sam local invoke コマンド)なら HTTP API を利用していても問題なく動きます。

サンプル

一応例として以下のような定義を想定することとします。

index.ts

import * as apigateway from '@aws-cdk/aws-apigateway';
import * as cdk from '@aws-cdk/core';
import * as lambda from '@aws-cdk/aws-lambda';

class MyStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string) {
    super(scope, id);

    const handler = new lambda.Function(this, 'Func', {
      runtime: lambda.Runtime.NODEJS_12_X,
      handler: 'index.handler',
      code: lambda.Code.fromAsset('lambda-handler'),
    });

    const api = new apigateway.RestApi(this, 'Api');
    api.root.addMethod('GET', new apigateway.LambdaIntegration(handler));
  }
}

new MyStack(new cdk.App(), 'MyStack');

lambda-handler/index.js

exports.handler = async () => {
  return {
    statusCode: 200,
    body: 'Hello, World!',
  };
};

上記の例をそのまま試したい場合は acomagu/cdk-sam-local-example から clone することができます。

ちなみに、lambda 関数のコードの定義に fromInline を使っていたりすると動かなかったりします。

1. テンプレートファイル/アーティファクトの生成

$ npx cdk synth MyStack

--no-staging は要らないです。デプロイ時同様にアセットを cdk.out 内に作成します。

また、出力されるテンプレートも使いません(cdk.out 内に同様のものが書き出されるのでそれを使います)。

スタック間に依存がありエラーが出る場合は -e を指定してみてください。

2. 実行

$ cd cdk.out && sam local start-api -t MyStack.template.json

これで出てくる localhost の URL をブラウザで開くと API Gateway + Lambda がローカルで動くのが確認できると思います。何かエラーが発生した場合はターミナルの方に出ます。

まとめ

クラメソ等の記事との差異