TypeScriptのLambda関数
TypeScript Lambda Function ジェネレータは、既存のTypeScriptプロジェクトにLambda関数を追加する機能を提供します。
このジェネレータはAWS CDKまたはTerraformのインフラストラクチャ設定を含む新しいTypeScript Lambdaハンドラを作成します。生成されたハンドラは、AWS Lambda Powertools for TypeScriptを使用して、ロギング、AWS X-Rayトレーシング、CloudWatchメトリクスなどの観測可能性を実現し、AWS Lambda PowertoolsのParserを使用したイベントの型安全性(オプション)を提供します。
TypeScript Lambda関数の生成
Section titled “TypeScript Lambda関数の生成”Lambda関数は2つの方法で生成できます:
- インストール Nx Console VSCode Plugin まだインストールしていない場合
- VSCodeでNxコンソールを開く
- クリック
Generate (UI)
"Common Nx Commands"セクションで - 検索
@aws/nx-plugin - ts#lambda-function
- 必須パラメータを入力
- クリック
Generate
pnpm nx g @aws/nx-plugin:ts#lambda-function
yarn nx g @aws/nx-plugin:ts#lambda-function
npx nx g @aws/nx-plugin:ts#lambda-function
bunx nx g @aws/nx-plugin:ts#lambda-function
変更されるファイルを確認するためにドライランを実行することもできます
pnpm nx g @aws/nx-plugin:ts#lambda-function --dry-run
yarn nx g @aws/nx-plugin:ts#lambda-function --dry-run
npx nx g @aws/nx-plugin:ts#lambda-function --dry-run
bunx nx g @aws/nx-plugin:ts#lambda-function --dry-run
パラメータ | 型 | デフォルト | 説明 |
---|---|---|---|
project 必須 | string | - | The project to add the lambda function to |
functionName 必須 | string | - | The name of the function to add |
functionPath | string | - | Optional subdirectory within the project source directory to add the function to |
eventSource | string | Any | Optional event source schema to use for the lambda function |
iacProvider | string | Inherit | The preferred IaC provider. By default this is inherited from your initial selection. |
ジェネレータの出力
Section titled “ジェネレータの出力”ジェネレータはプロジェクトに以下のファイルを追加します:
Directory<project-name>
Directorysrc/
- <lambda-function>.ts 関数の実装
functionPath
オプションが指定された場合、ジェネレータはプロジェクトのソースディレクトリ内の指定パスにハンドラを追加します:
Directory<project-name>
Directorysrc/
Directory<custom-path>/
- <function-name>.ts 関数の実装
インフラストラクチャ
Section titled “インフラストラクチャ”このジェネレータは選択した iacProvider
に基づいてInfrastructure as Codeを生成するため、packages/common
に関連するCDKコンストラクトまたはTerraformモジュールを含むプロジェクトを作成します。
共通のInfrastructure as Codeプロジェクトは以下の構造を持ちます:
Directorypackages/common/constructs
Directorysrc
Directoryapp/ プロジェクト/ジェネレータ固有のインフラストラクチャ用コンストラクト
- …
Directorycore/
app
内のコンストラクトで再利用される汎用コンストラクト- …
- index.ts
app
からコンストラクトをエクスポートするエントリーポイント
- project.json プロジェクトのビルドターゲットと設定
Directorypackages/common/terraform
Directorysrc
Directoryapp/ プロジェクト/ジェネレータ固有のインフラストラクチャ用Terraformモジュール
- …
Directorycore/
app
内のモジュールで再利用される汎用モジュール- …
- project.json プロジェクトのビルドターゲットと設定
ジェネレータは選択したiacProvider
に基づいて関数をデプロイするためのインフラストラクチャコードを作成します:
ジェネレータはCDKコンストラクトを作成します。このコンストラクトはpackages/common/constructs/src/app/lambda-functions
ディレクトリに配置され、関数のデプロイに使用できます。
ジェネレータはTerraformモジュールを作成します。このモジュールはpackages/common/terraform/src/app/lambda-functions/<function-name>
ディレクトリに配置され、関数のデプロイに使用できます。
メインの関数実装は<function-name>.ts
にあります。以下は実装例です:
import { parser } from '@aws-lambda-powertools/parser/middleware';import { EventBridgeSchema } from '@aws-lambda-powertools/parser/schemas';import middy from '@middy/core';import { Tracer } from '@aws-lambda-powertools/tracer';import { captureLambdaHandler } from '@aws-lambda-powertools/tracer/middleware';import { injectLambdaContext } from '@aws-lambda-powertools/logger/middleware';import { Logger } from '@aws-lambda-powertools/logger';import { Metrics } from '@aws-lambda-powertools/metrics';import { logMetrics } from '@aws-lambda-powertools/metrics/middleware';import { z } from 'zod';
process.env.POWERTOOLS_METRICS_NAMESPACE = 'MyFunction';process.env.POWERTOOLS_SERVICE_NAME = 'MyFunction';
const tracer = new Tracer();const logger = new Logger();const metrics = new Metrics();
export const myFunction = async ( event: z.infer<typeof EventBridgeSchema>,): Promise<void> => { logger.info('Received event', event);
// TODO: 実装を追加};
export const handler = middy() .use(captureLambdaHandler(tracer)) .use(injectLambdaContext(logger)) .use(logMetrics(metrics)) .use(parser({ schema: EventBridgeSchema })) .handler(myFunction);
ジェネレータは以下の機能を自動的に設定します:
- 拡張Lambda機能のためのMiddyミドルウェアスタック
- 観測可能性のためのAWS Lambda Powertools統合
- CloudWatchを使ったメトリクス収集
- パーサーミドルウェアを使用した型安全性
- Rolldownによる最適化されたデプロイパッケージのバンドリング
AWS Lambda Powertoolsによる観測可能性
Section titled “AWS Lambda Powertoolsによる観測可能性”ジェネレータはMiddyミドルウェアを通じた自動コンテキスト注入付きの構造化ロギングを設定します。
export const handler = middy() .use(injectLambdaContext(logger)) .handler(myFunction);
トレーシング
Section titled “トレーシング”AWS X-RayトレーシングはcaptureLambdaHandler
ミドルウェアで自動設定されます。カスタムサブセグメントを追加できます:
const tracer = new Tracer();
export const myFunction = async ( event: z.infer<typeof EventBridgeSchema>,): Promise<void> => { // 新しいサブセグメントを作成 const subsegment = tracer.getSegment()?.addNewSubsegment('custom-operation'); try { // ここにロジックを実装 } catch (error) { subsegment?.addError(error as Error); throw error; } finally { subsegment?.close(); }};
export const handler = middy() .use(captureLambdaHandler(tracer)) .handler(myFunction);
CloudWatchメトリクスはlogMetrics
ミドルウェアでリクエストごとに自動収集されます。カスタムメトリクスを追加できます:
const metrics = new Metrics();
export const myFunction = async ( event: z.infer<typeof EventBridgeSchema>,): Promise<void> => { metrics.addMetric("CustomMetric", MetricUnit.Count, 1); metrics.addMetric("ProcessingTime", MetricUnit.Milliseconds, processingTime);};
export const handler = middy() .use(logMetrics(metrics)) .handler(myFunction);
Lambda関数生成時にeventSource
を選択した場合、関数はAWS Lambda Powertoolsのparser
ミドルウェアで計装されます。例:
export const myFunction = async ( event: z.infer<typeof EventBridgeSchema>,): Promise<void> => { event.detail // <- IDEのオートコンプリートが効く型安全なアクセス};
export const handler = middy() .use(parser({ schema: EventBridgeSchema })) .handler(myFunction);
これにより、コンパイル時の型安全性とランタイムバリデーションが提供されます。
イベントの型指定を希望しない場合、eventSource
にAny
を選択すると、イベントパラメータはany
型になります。
バンドリング
Section titled “バンドリング”ジェネレーターは自動的に Rolldown を使用する bundle
ターゲットを設定します。このターゲットはデプロイメントパッケージの作成に使用されます:
pnpm nx run <project-name>:bundle
yarn nx run <project-name>:bundle
npx nx run <project-name>:bundle
bunx nx run <project-name>:bundle
Rolldownの設定はrolldown.config.ts
に記述され、生成するバンドルごとにエントリを定義します。Rolldownは定義された複数のバンドルを並行して作成する処理を管理します。
関数のデプロイ
Section titled “関数のデプロイ”このジェネレータは選択した iacProvider
に基づいてCDKまたはTerraformのインフラストラクチャーコードを生成します。生成されたコードを使用して関数をデプロイできます。
このジェネレータは common/constructs
フォルダに関数をデプロイするためのCDKコンストラクトを作成します。CDKアプリケーションで以下のように使用できます:
import { MyProjectMyFunction } from ':my-scope/common-constructs';
export class ExampleStack extends Stack { constructor(scope: Construct, id: string) { // スタックに関数を追加 const fn = new MyProjectMyFunction(this, 'MyFunction'); }}
これにより以下が設定されます:
- AWS Lambda関数
- CloudWatchロググループ
- X-Rayトレーシング設定
- CloudWatchメトリクスネームスペース
この関数は任意のLambdaイベントソースのターゲットとして使用できます:
以下の例はEventBridgeを使用してスケジュールでLambda関数を起動するCDKコードを示しています:
import { Rule, Schedule } from 'aws-cdk-lib/aws-events';import { LambdaFunction } from 'aws-cdk-lib/aws-events-targets';import { MyProjectMyFunction } from ':my-scope/common-constructs';
export class ExampleStack extends Stack { constructor(scope: Construct, id: string) { // スタックに関数を追加 const fn = new MyProjectMyFunction(this, 'MyFunction');
// EventBridgeスケジュールルールに関数を追加 const eventRule = new Rule(this, 'MyFunctionScheduleRule', { schedule: Schedule.cron({ minute: '15' }), targets: [new LambdaFunction(fn)], }); }}
このジェネレータは common/terraform
フォルダに関数をデプロイするためのTerraformモジュールを作成します。Terraform設定で以下のように使用できます:
module "my_project_my_function" { source = "../../common/terraform/src/app/lambda-functions/my-project-my-function"
# Lambda関数の環境変数 env = { SOME_VARIABLE = "some value" }
# 追加のIAMポリシーが必要な場合 additional_iam_policy_statements = [ # 関数に必要な追加の権限を記述 ]}
これにより以下が設定されます:
- AWS Lambda関数
- CloudWatchロググループ
- X-Rayトレーシング設定
- CloudWatchメトリクスネームスペース
この関数は任意のLambdaイベントソースのターゲットとして使用できます。以下の例はEventBridgeを使用してスケジュールでLambda関数を起動するTerraformコードを示しています:
# スケジュール実行用EventBridgeルールresource "aws_cloudwatch_event_rule" "my_function_schedule" { name = "my-function-schedule" description = "15分毎に関数を起動" schedule_expression = "cron(15 * * * ? *)"}
# EventBridgeターゲットresource "aws_cloudwatch_event_target" "lambda_target" { rule = aws_cloudwatch_event_rule.my_function_schedule.name target_id = "MyFunctionTarget" arn = module.my_project_my_function.function_arn}
# EventBridgeがLambda関数を起動するための権限resource "aws_lambda_permission" "allow_eventbridge" { statement_id = "AllowExecutionFromEventBridge" action = "lambda:InvokeFunction" function_name = module.my_project_my_function.function_name principal = "events.amazonaws.com" source_arn = aws_cloudwatch_event_rule.my_function_schedule.arn}