AWS Lambda の blank 関数サンプルアプリケーション - AWS Lambda

AWS Lambda の blank 関数サンプルアプリケーション

blank 関数のサンプルアプリケーションは、Lambda API を呼び出す関数を使用し、Lambda の一般的なオペレーションを示すスターター アプリケションです。ロギング、環境変数、AWS X-Ray トレース、レイヤー、単体テスト、AWS SDK の使用を示します。このアプリケーションについて調べてプログラミング言語で Lambda 関数を構築する方法を学習したり、独自のプロジェクトの出発点として使用したりします。


      blank 関数のサンプルアプリケーションのアーキテクチャ。

このサンプルアプリケーションのバリアントは、次の言語で使用できます。

バリアント型

このトピックの例では、Node.js バージョンのコードが強調されていますが、詳細は通常すべてのバリアントに適用できます。

サンプルは、AWS CLI および AWS CloudFormation を使用して数分でデプロイできます。README の指示に従い、ご自分のアカウントでダウンロード、設定、デプロイしてください。

アーキテクチャとハンドラーコード

サンプルアプリケーションは、関数コード、AWS CloudFormation テンプレート、およびサポートリソースで構成されています。サンプルをデプロイするときは、次の AWS のサービスを使用します。

  • AWS Lambda – 関数コードの実行、CloudWatch Logs へのログの送信、X-Ray へのトレースデータの送信を行います。また、この関数は Lambda API を呼び出して、現在のリージョンでのアカウントのクォータと使用状況に関する詳細を取得します。

  • AWS X-Ray– トレースデータの収集、トレースのインデックス作成 (検索用)、サービスマップの生成を行います。

  • Amazon CloudWatch – ログとメトリックを格納します。

  • AWS Identity and Access Management (IAM) – アクセス許可を付与します。

  • Amazon Simple Storage Service (Amazon S3) – デプロイ時に関数のデプロイパッケージを格納します。

  • AWS CloudFormation– アプリケーションリソースを作成し、関数コードをデプロイします。

各サービスには標準料金が適用されます。詳細については、「AWS の料金」を参照してください。

関数コードは、イベントを処理するための基本的なワークフローを示しています。ハンドラーは、入力として Amazon Simple Queue Service (Amazon SQS) イベントを受け取り、そのイベントに含まれるレコードを反復処理して、各メッセージの内容をログ記録します。これは、イベントの内容、コンテキストオブジェクト、環境変数をログ記録します。次に、AWS SDK を呼び出し、レスポンスを Lambda ランタイムに渡します。

blank-nodejs/function/index.js – ハンドラーコード

// Handler exports.handler = async function(event, context) { event.Records.forEach(record => { console.log(record.body) }) console.log('## ENVIRONMENT VARIABLES: ' + serialize(process.env)) console.log('## CONTEXT: ' + serialize(context)) console.log('## EVENT: ' + serialize(event)) return getAccountSettings() } // Use SDK client var getAccountSettings = function(){ return lambda.getAccountSettings().promise() } var serialize = function(object) { return JSON.stringify(object, null, 2) }

ハンドラーの入出力型と非同期プログラミングのサポートは、ランタイムによって異なります。この例のハンドラーメソッドは async です。Node.js では、これはランタイムに promise を返す必要があることを意味します。Lambda ランタイムは、promise が解決されるのを待ち、呼び出し元にレスポンスを返します。関数コードまたは AWS SDK クライアントがエラーを返した場合、ランタイムはエラーを JSON ドキュメントにフォーマットして返します。

サンプルアプリケーションには、イベントを送信する Amazon SQS キューは含まれていませんが、Amazon SQS (event.json) からのイベントを使用して、イベントの処理方法が示されています。アプリケーションに Amazon SQS キューを追加する方法については、「AWS Lambda を Amazon SQS に使用する」を参照してください。

AWS CloudFormation および AWS CLI を使用したデプロイの自動化

サンプルアプリケーションのリソースは AWS CloudFormation テンプレートで定義され、AWS CLI を使用してデプロイされます。プロジェクトには、アプリケーションのセットアップ、デプロイ、呼び出し、および解体のプロセスを自動化する簡単なシェルスクリプトが含まれています。


        空のアプリケーションスタックとサポートリソース。

アプリケーションテンプレートでは、AWS サーバーレスアプリケーションモデル (AWS SAM) リソースタイプを使用してモデルを定義します。AWS SAM は、実行ロール、API、およびその他のリソースの定義を自動化することで、サーバーレスアプリケーションのテンプレート作成を簡素化します。

テンプレートは、アプリケーションスタック内のリソースを定義します。これには、関数およびその実行ロールのほか、関数のライブラリの依存関係を提供する Lambda レイヤーが含まれます。スタックには、AWS CLI がデプロイ中に使用するバケットまたは CloudWatch Logs ロググループは含まれません。

blank-nodejs/template.yml – サーバーレスリソース

AWSTemplateFormatVersion: '2010-09-09' Transform: 'AWS::Serverless-2016-10-31' Description: An AWS Lambda application that calls the Lambda API. Resources: function: Type: AWS::Serverless::Function Properties: Handler: index.handler Runtime: nodejs12.x CodeUri: function/. Description: Call the AWS Lambda API Timeout: 10 # Function's execution role Policies: - AWSLambdaBasicExecutionRole - AWSLambdaReadOnlyAccess - AWSXrayWriteOnlyAccess Tracing: Active Layers: - !Ref libs libs: Type: AWS::Serverless::LayerVersion Properties: LayerName: blank-nodejs-lib Description: Dependencies for the blank sample app. ContentUri: lib/. CompatibleRuntimes: - nodejs12.x

アプリケーションをデプロイすると、AWS CloudFormation は AWS SAM 変換をテンプレートに適用し、AWS::Lambda::FunctionAWS::IAM::Role などの標準タイプの AWS CloudFormation テンプレートを生成します。

例 処理済みテンプレート

{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "An AWS Lambda application that calls the Lambda API.", "Resources": { "function": { "Type": "AWS::Lambda::Function", "Properties": { "Layers": [ { "Ref": "libs32xmpl61b2" } ], "TracingConfig": { "Mode": "Active" }, "Code": { "S3Bucket": "lambda-artifacts-6b000xmpl1e9bf2a", "S3Key": "3d3axmpl473d249d039d2d7a37512db3" }, "Description": "Call the AWS Lambda API", "Tags": [ { "Value": "SAM", "Key": "lambda:createdBy" } ],

この例では、Code プロパティは Amazon S3 バケット内のオブジェクトを指定します。これは、プロジェクトテンプレートの CodeUri プロパティのローカルパスに対応します。

CodeUri: function/.

プロジェクトファイルを Amazon S3 にアップロードするため、デプロイメントスクリプトは AWS CLI コマンドを使用します。cloudformation package コマンドは、テンプレートを前処理して、アーティファクトをアップロードし、ローカルパスを Amazon S3 オブジェクトの場所に置き換えます。cloudformation deploy コマンドは、AWS CloudFormation 変更セット持つ処理済みテンプレートをデプロイします。

blank-nodejs/3-deploy.sh – パッケージングとデプロイ

#!/bin/bash set -eo pipefail ARTIFACT_BUCKET=$(cat bucket-name.txt) aws cloudformation package --template-file template.yml --s3-bucket $ARTIFACT_BUCKET --output-template-file out.yml aws cloudformation deploy --template-file out.yml --stack-name blank-nodejs --capabilities CAPABILITY_NAMED_IAM

このスクリプトを初めて実行すると、blank-nodejs という名前の AWS CloudFormation スタックが作成されます。関数コードまたはテンプレートを変更した場合は、関数コードまたはテンプレートを再度実行してスタックを更新できます。

クリーンアップスクリプト (blank-nodejs/5-cleanup.sh) はスタックを削除し、必要に応じてデプロイバケットと関数ログを削除します。

AWS X-Ray での計測

サンプル関数は、AWS X-Ray でトレースするように構成されています。トレースモードをアクティブに設定すると、Lambda は呼び出しのサブセットのタイミング情報を記録し、X-Ray に送信します。X-Ray はデータを処理して、クライアントノードと 2 つのサービスノードを示すサービスマップを生成します。


        アクティブなトレースを持つ関数のサービスマップ。

最初のサービスノード (AWS::Lambda) は、呼び出しリクエストを検証して関数に送信する Lambda サービスを表します。2 番目のノード AWS::Lambda::Function は、関数自体を表します。

追加の詳細を記録するために、サンプル関数は X-Ray SDK を使用します。関数コードを最小限変更するだけで、X-Ray SDK は AWS SDK を使用した AWS のサービスへの呼び出しに関する詳細を記録します。

blank-nodejs/function/index.js – インストルメンテーション

const AWSXRay = require('aws-xray-sdk-core') const AWS = AWSXRay.captureAWS(require('aws-sdk')) // Create client outside of handler to reuse const lambda = new AWS.Lambda()

AWS SDK クライアントを計測すると、サービスマップにノードが追加され、トレースにさらに詳細が追加されます。この例では、サービスマップに Lambda API を呼び出すサンプル関数が表示され、現在のリージョンでのストレージと同時実行の使用状況に関する詳細を取得しています。


        X-Ray SDK を使用した関数のサービスマップ。

トレースは、関数の初期化、呼び出し、オーバーヘッドのサブセグメントとともに、呼び出しのタイミングの詳細を表示します。呼び出しサブセグメントには、GetAccountSettings API オペレーションに対する AWS SDK 呼び出しのサブセグメントが含まれています。


        X-Ray SDK を使用して関数をトレースします。

X-Ray SDK やその他のライブラリを関数のデプロイパッケージに含めることも、Lambda レイヤーに個別にデプロイすることもできます。Node.js、Ruby、Python の場合、Lambda ランタイムは実行環境に AWS SDK を含めます。

レイヤーを使用した依存関係管理

ライブラリをローカルにインストールし、Lambda にアップロードするデプロイパッケージに含めることができますが、これにはデメリットがあります。ファイルサイズが大きくなるほどデプロイ時間が長くなり、Lambda コンソールで関数コードの変更をテストできなくなる可能性があります。デプロイパッケージを小さく保ち、変更されていない依存関係のアップロードを避けるために、サンプルアプリは Lambda レイヤーを作成し、関数に関連付けます。

blank-nodejs/template.yml – 依存関係レイヤー

Resources: function: Type: AWS::Serverless::Function Properties: Handler: index.handler Runtime: nodejs12.x CodeUri: function/. Description: Call the AWS Lambda API Timeout: 10 # Function's execution role Policies: - AWSLambdaBasicExecutionRole - AWSLambdaReadOnlyAccess - AWSXrayWriteOnlyAccess Tracing: Active Layers: - !Ref libs libs: Type: AWS::Serverless::LayerVersion Properties: LayerName: blank-nodejs-lib Description: Dependencies for the blank sample app. ContentUri: lib/. CompatibleRuntimes: - nodejs12.x

2-build-layer.sh スクリプトは、npm を使用して関数の依存関係をインストールし、Lambda ランタイムに必要な構造を持つフォルダに配置します。

2-build-layer.sh – レイヤーの準備

#!/bin/bash set -eo pipefail mkdir -p lib/nodejs rm -rf node_modules lib/nodejs/node_modules npm install --production mv node_modules lib/nodejs/

サンプルアプリケーションを初めてデプロイすると、AWS CLI によってレイヤーが関数コードとは別にパッケージ化され、両方がデプロイされます。以降のデプロイでは、lib フォルダーの内容が変更された場合にのみレイヤーアーカイブがアップロードされます。