AWS LambdaにTypeScriptで最小単位の関数をデプロイする手順

最小単位でLambdaにTypeScriptの関数をデプロイします。
とりあえずLambdaを試したい用の記録です。

やりたいこと

  • TypeScriptで書いた関数をlambdaにデプロイ

やらないこと

  • Node.jsおよびnpmのインストール
    • Nodeとnpmは既にインストール済みである状態でLambda関数の作成を行います。
  • TypeScriptとNodeおよびnpmの基本的な知識の説明
  • ユーザ作成
  • IAMロールの作成
    • Lmabdaはデフォルトの権限を使用します。したがって専用のIAMロール(特定の実行権限しか与えない)は作成しません。
  • VPCの構築
    • VPC(仮想ネットワーク)の作成は行いません。同様にセキュリティグループの作成も行いません。
  • APIGatewayの構築
    • APIGatewayの構築は行いません。したがって、HTTPのリクエストによる関数の実行は行えません。
    • 関数の実行はAWSGUI上からテストイベントの呼び出しで実行します。
  • node_modulesのデプロイ
    • 最小単位のデプロイを行うため、モジュールのデプロイは行いません。
  • 自動デプロイ
    • コマンド一つでLambdaの自動デプロイなどのかっこいいことは行いません。
    • 愚直に手でビルドを行い、Lambdaには手動でGUIからデプロイを行います。

実行環境

  • OS: Windows 10
  • Node:14.16.0
  • npm: 6.14.11

Lambda関数の作成

Lambda関数の作成を行います。
最低限の設定で作成するため、詳細な設定は以下のドキュメントを参照してください。

Node.js による Lambda 関数のビルド - AWS Lambda

  1. AWS マネジメントコンソールのヘッダにLambdaを入力して、AWS Lambdaのページに移動
  2. 「関数の作成」を選択
  3. 作成する関数を設定
    • オプション:一から作成
    • 関数名: lambda-example
    • ランタイム:Node.js 14.x
    • 実行ロール:基本的な Lambda アクセス権限で新しいロールを作成(デフォルト)
    • 詳細設定:不要(全て空欄)

f:id:m-daichi1219:20210314194724p:plain

最後に「関数の作成」を選択すると、Lambda関数が作成されます。

デプロイするプログラムの作成

プロジェクト作成

ローカル環境にLmabdaにデプロイするプロジェクトを作成します。
任意の場所にフォルダを作成してください。

本記事ではlambda-exampleフォルダを作成しました。
また、以下の操作は全てlambda-exampleフォルダをCurrentとして実行しています。

環境構築

npm の初期設定

作成済みのプロジェクトフォルダをCurrentにして、コマンドラインnpm initを実行します。 実行後にpackage.jsonの設定が問われます。今回は以下のような設定を行っています。

package name: (lambda-example)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)

TypeScriptの設定

作成済みのプロジェクトフォルダをCurrentにして、コマンドラインnpm i typescriptを実行します。
TypeScriptのインストール後、プロジェクトフォルダ直下にtsconfig.jsonファイルを作成します。

tsconfig.jsonの記載はtsconfig.jsonの全オプションを理解する(随時追加中) - Qiitaなどを参考に適宜行ってください。
今回は以下のようなファイルを作成しました。

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es2015",
    "noImplicitAny": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "outDir": "./build",
    "allowJs": true
  },
  "include": ["./src/index.ts"]
}

定義ファイルのインストール

作成済みのプロジェクトフォルダをCurrentにして、コマンドラインで以下のコマンドを実行します。
インストールする定義はnodeとlambdaの定義ファイルです。

npm i @types/node
npm i @types/aws-lambda

Lambda関数の作成

プロジェクトフォルダ配下にsrcフォルダを作成します。
srcフォルダ配下にindex.tsファイルを作成して、以下の内容で保存します。

import * as lambda from "aws-lambda";

exports.handler = (
  event: any,
  context: lambda.Context,
  callback: lambda.Callback
): void => {
  console.log("hello world");
};

なお、上記のプログラムはLambda関数のエントリーポイントとなるハンドラーです。
Lambda関数はハンドラーから必ず実行されます。
詳細はNode.js の AWS Lambda 関数ハンドラー - AWS Lambdaを参照してください。

この時点で以下のようなフォルダ構造になっています。

f:id:m-daichi1219:20210314210237p:plain

Lambda関数のデプロイ

TypeScriptのトランスパイル

TypeScriptをJavaScriptにトランスパイルするためのtscコマンドをpackage.jsonに追加します。
package.json内のscript"tsc": ".\\node_modules\\.bin\\tsc"を設定します。

なお、現在の時点でpackage.jsonは以下の状態になっています。

{
  "name": "lambda-example",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "tsc": ".\\node_modules\\.bin\\tsc"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@types/aws-lambda": "^8.10.72",
    "@types/node": "^14.14.34",
    "TypeScript": "^4.2.3"
  }
}

package.jsonの設定後、npm run tscを実行します。
コマンドの実行後にトランスパイルされたindex.jsファイルが出力されます。
今回の例ではlambda-example/build/index.jsに出力されています。

プログラムのデプロイ

トランスパイルしたindex.jsを任意の方法でzipに圧縮します。
Node.jsでLambda関数をデプロイする場合にはファイルが配置されるフォルダ階層が正しい位置に存在しないと、実行することができません。
したがって、jsファイルのみzipに圧縮します。
詳細は.zip ファイルアーカイブで Node.js Lambda 関数をデプロイする - AWS Lambdaを参照してください。

AWS Lambdaのページに移動して、事前に作成したLambdaを選択します。
アップロード元を選択して、先ほど作成したindex.zipのアップロードします。

f:id:m-daichi1219:20210314213145p:plain

f:id:m-daichi1219:20210314213005p:plain

テストタブから呼び出しを選択

f:id:m-daichi1219:20210314213335p:plain

実行結果にhello worldが出力されていれば成功です。

完成したプロジェクト: GitHub - m-daichi1219/lambda-example at lambda-init

発展

  • デプロイするプログラムにnode_modulesを含める場合には以下の方法があります
    • トランスパイルするindex.jsnode_modulesをバンドル(1fileにモジュールも全て記載してビルド)する
    • Lambda layerを使用する