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