LoginSignup
5
2

More than 1 year has passed since last update.

AWS LambdaでTypeScriptのコードを動かす最小の構成 with AWS SAM

Posted at

はじめに

AWS Lambdaってお手軽に使えるんでしょ?と思いながら簡単なLambdaを書いたのですが、初心者の私はTypeScriptの知識もないために、デプロイするまでが難しかったです。

AWS SAM CLIを使ってテンプレートから作成するとゴチャゴチャしていて分かりにくいと感じたので、Lambdaとして実行するための必要最小限の構成を手動で作る手順を残しておきます。

開発環境

  • Windows 10
  • Git bash
  • Node v16.18.1 / npm 8.19.2
  • aws-cli/2.9.9 Python/3.9.11 Windows/10 exe/AMD64 prompt/off
  • SAM CLI, version 1.67.0

基本的なセットアップ

SAMでは $ sam init で対話型でテンプレートからプロジェクトを生成することが可能ですが、今回は使わずに一からプロジェクトを作ります。

ちなみに、Windows版のAWS SAM CLIをインストールすると、bashで $ sam を使うためにはひと工夫必要でした。
【AWS】aws-sam-cli をWindowsでbashから使うメモ

早速プロジェクトを作っていきます。

ディレクトリの作成

$ mkdir hello-sam-app
$ cd hello-sam-app
$ mkdir function

SAMテンプレートファイルを作成

$ touch template.yml

Nodeのルートフォルダへ移動して初期化

$ cd function
$ npm init -y
$ npm install esbuild
$ npm install -D @types/node @types/aws-lambda
$ touch index.ts

以上で、このような構成になっています。

hello-sam-app
|--function
|  |--index.ts
|  |--package.json
|--template.yml

SAMはTypeScriptにネイティブ対応しているため、トランスパイラの設定を自分でする必要はないようです。
SAMのテンプレートファイルに適切に記載することで、$ sam build したときにesbuildを使ってトランスパイルしてくれます。
そのため、セットアップの手間はJavaScriptとそれほど変わらないですね。

コードの作成

SAMのテンプレートファイルである template.yml と、
Lambda本体になる index.ts を書きます。

template.yml

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: aws-sam-typescript
  
Globals:
  Function:
    Timeout: 3
    MemorySize: 128
  Api:
    OpenApiVersion: 3.0.3

Resources:
  LambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: function/
      Handler: index.lambdaHandler
      Runtime: nodejs16.x
      Architectures:
        - arm64
      Events:
        HelloApi:
          Type: Api 
          Properties:
            Path: /hello
            Method: get
    Metadata: 
      BuildMethod: esbuild
      BuildProperties:
        Minify: true
        Target: "es2020"
        EntryPoints: 
        - index.ts

リソースとして、API Gatewayを設定したLambdaを指定しています。
SAMを使うとAPI Gatewayや、必要なRole、LogGroupなどは自動生成してくれるそうです。もちろん手動で生成することも可能です。

BuildMethodにesbuildが設定されています。
BuildPropertiesには tsconfig.ts に書かれがちな内容が書かれており、
$ sam build したときのトランスパイラの設定は、ここに書いているものが使われるということですね。
ということは、Lambdaで実行するだけなら tsc も tsconfig.ts も必要ありません。tscで型チェックを行う、jestを使うとなって初めて必要になるようです。

index.ts(こちらはHelloWorldテンプレートで生成される app.ts そのまま)

import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';

export const lambdaHandler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
    let response: APIGatewayProxyResult;
    try {
        response = {
            statusCode: 200,
            body: JSON.stringify({
                message: 'hello world',
            }),
        };
    } catch (err: unknown) {
        console.error(err);
        response = {
            statusCode: 500,
            body: JSON.stringify({
                message: err instanceof Error ? err.message : 'some error happened',
            }),
        };
    }
    return response;
};

これでSAMでデプロイできるプロジェクトになっています。

デプロイ

$ sam build したあとに、
$ sam deploy --guided で、対話型でデプロイを実行します。

この辺は公式チュートリアル/テンプレートを使ってやった方が分かりやすいと思います。

おわりに

SAMのテンプレートからTypeScriptのHelloWorldプロジェクトを生成して試行錯誤していたんですが、初心者には複雑すぎて混乱したため、必要最小限の構成まで削ぎ落としてみました。
実用には当然、リンタやテストは入れなければいけないですし、そうするとテンプレートから作るものと同じような構成になると思います。が、一度はテンプレートを使わずに手を動かしたほうが理解が深まると改めて感じました。

乱雑な記事ですが、なにかの参考になれば幸いです。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2