Skip to content

Instantly share code, notes, and snippets.

@noid11
Last active June 4, 2022 00:07
Show Gist options
  • Save noid11/2ed2a1c6471daaefcf3cd3d914a3cd8b to your computer and use it in GitHub Desktop.
Save noid11/2ed2a1c6471daaefcf3cd3d914a3cd8b to your computer and use it in GitHub Desktop.
AWS CDK で作成する Lambda 関数を TypeScript で書く方法

これは何?

  • AWS CDK で Lambda 関数を作成する際に TypeScript を使いたい場合どうすれば良いんだろうと思って調べたメモ
  • AWS CDK で Lambda 関数を作成、 CDK App と Lambda 関数は TypeScript でコーディング、 Lambda 関数と CDK App のテストコードを書いて動かした

TOC

CDK プロジェクトのセットアップ

# setup
mkdir my-project && cd my-project
cdk init app --language typescript

# first build
npm run build
cdk ls

# start develop
npm install @aws-cdk/aws-lambda

Lambda 関数を Stack に定義

  • lib/my-project-stack.ts
import * as cdk from '@aws-cdk/core';
import * as lambda from '@aws-cdk/aws-lambda';

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

    const hello = new lambda.Function(this, 'HelloHandler', {
      runtime: lambda.Runtime.NODEJS_12_X,    // execution environment
      code: lambda.Code.fromAsset('lambda'),  // code loaded from "lambda" directory
      handler: 'hello.handler'                // file is "hello", function is "handler"
    });
  }
}

aws-lambda module · AWS CDK
https://docs.aws.amazon.com/cdk/api/latest/docs/aws-lambda-readme.html

Lambda 関数を実装する TypeScript のファイルを作成

mkdir lambda
touch lambda/hello.ts

Lambda 関数を実装

export const handler = async (event: any = {}) : Promise <any> => {
    console.log(event);
    return { statusCode: 200, body: 'Hello world!' };
};

実装した Lambda 関数をローカルで動かしてみる

  • SAM CLI の sam local invoke コマンドを使う
# sam local invoke コマンドでは template ファイルを読み込んで Lambda 関数をローカルで動かすので、 cdk synth で template.yaml を生成する
cdk synth --no-staging > template.yaml

# Lambda 関数をローカルで動かす
# HelloHandler2E4FBA4D は template.yaml における Lambda 関数リソースの識別子
sam local invoke HelloHandler2E4FBA4D --no-event

sam local invoke - AWS サーバーレスアプリケーションモデル
https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-local-invoke.html

SAM CLI - AWS Cloud Development Kit (AWS CDK)
https://docs.aws.amazon.com/cdk/latest/guide/sam.html

  • cdk synth--no-staging オプションって何?
    • アセット群をコピーしないオプションのようだ
$ cdk synth -h
...
  --staging             Copy assets to the output directory (use --no-staging to
                        disable, needed for local debugging the source files
                        with SAM CLI)                  [真偽] [デフォルト: true]

テスト関連のライブラリをインストール

npm install --save-dev jest @types/jest @aws-cdk/assert

Lambda 関数の test コード書くファイル作成

touch test/hello.test.ts

Lambda 関数の test コード書く

  • Lambda 関数のレスポンス内容をテスト
import { handler } from '../lambda/hello';

describe('hello lambda', (): void => {
    test('response Hello world!', async () => {
        const expectedResponse = { statusCode: 200, body: 'Hello world!' };
        const response = await handler();
        expect(response).toEqual(expectedResponse);
    });
});

CDK App Construct のテストコード書く

  • test/my-project.test.ts
    • Stack に Lambda 関数リソースが含まれることをテスト
import { expect as expectCDK, haveResource } from '@aws-cdk/assert';
import * as cdk from '@aws-cdk/core';
import * as lambda from '@aws-cdk/aws-lambda';
import * as MyProject from '../lib/my-project-stack';

test('Stack have Lambda Function', () => {
    const app = new cdk.App();
    const stack = new MyProject.MyProjectStack(app, 'MyTestStack');

    new lambda.Function(stack, 'MyTestStack', {
      runtime: lambda.Runtime.NODEJS_12_X,
      code: lambda.Code.fromAsset('lambda'),
      handler: 'hello.handler'
    });

    expectCDK(stack).to(haveResource('AWS::Lambda::Function'));
});

Testing constructs - AWS Cloud Development Kit (AWS CDK)
https://docs.aws.amazon.com/ja_jp/cdk/latest/guide/testing.html

aws-cdk/packages/@aws-cdk/assert at master · aws/aws-cdk
https://github.com/aws/aws-cdk/tree/master/packages/%40aws-cdk/assert

test 実行

% npm run build
% npm run test

> my-project@0.1.0 test /Users/xxx/workspaces/my-project
> jest

 PASS  test/hello.test.ts
  ● Console

    console.log
      {}

      at Object.<anonymous>.exports.handler (lambda/hello.ts:2:13)

 PASS  test/my-project.test.ts

Test Suites: 2 passed, 2 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        6.071s
Ran all test suites.

デプロイ

cdk diff
cdk deploy

環境

% cdk --version
1.56.0 (build c1c174d)
% sw_vers
ProductName:    Mac OS X
ProductVersion: 10.14.6
BuildVersion:   18G6020

感想

  • aws-lambda-nodejs というのを使うと良い感じにバンドルしてくれるっぽいが、自分の知識では動かすところまで進めなかった
    • cdk synth するときにレスポンスが返ってこなくなるという事象が発生して解決できず

aws-lambda-nodejs module · AWS CDK
https://docs.aws.amazon.com/cdk/api/latest/docs/aws-lambda-nodejs-readme.html

AWS CDKでLambda Function用のTypeScriptのバンドルを簡単に行う | Developers.IO
https://dev.classmethod.jp/articles/easy-bundle-ts-for-lambda/

AWS CDKの'aws-lambda-nodejs'を使ってCDKとLambdaの間の壁を破壊する - Qiita
https://qiita.com/tetsuya-zama/items/600bb0e187e9dead6e68

  • 普通の aws-lambda Construct でも TypeScript がサクッと使えてよかった
  • AWS CDK の TypeScript 公式サンプルがいくつか公開されているので、参考にして経験値をもうちょい積んでいきたい

aws-cdk-examples/typescript at master · aws-samples/aws-cdk-examples
https://github.com/aws-samples/aws-cdk-examples/tree/master/typescript

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment