本連載では、AWS Lambdaを使ったサーバレス処理でのエラーハンドリング方法を解説しています。前回は数の赤い矢印のスコープにおいて、同期型でビジネスエラーが発生することを想定したSpring Cloud Function 3.1以降のLambdaファンクションの実装方法やパッケージ構成について解説しました。
今回はAPI GatewayとLambda実行環境をCloudFormationを使って構築し、同期的にLambdaを呼び出してみます。
なお、API Gatewayおよび、Lambdaをマネジメントコンソール上から手動で構築する場合は、連載「AWSで作るクラウドネイティブアプリケーションの基本」の第2回、第3回と同一です。設定内容はほぼ同じなので、構築に必要な設定要素を理解するにはこちらも参照することをお薦めします。 また、CloudFormationを使った環境構築の説明は割愛しますが、基本的なお作法は連載「AWSで実践! 基盤構築・デプロイ自動化」の第21回以降で解説しているので、適宜参照してください。
LambdaファンクションのCloudFormationテンプレート
AWS LambdaをCloudFormationで構築するときのテンプレートの記述要領については、連載「AWSで実践! 基盤構築・デプロイ自動化」の第42回を参照してください。事前にLambdaをデプロイするためにビルドされたアプリケーションパッケージを配置するS3バケットを作成しておきます。また、Lambdaのテンプレートから参照するので、バケット名やARNをエクスポートします。
AWSTemplateFormatVersion: '2010-09-09'
Description: S3 Bucket for Lambda function template with YAML - S3 Bucket Definition
Resources:
S3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: debugroom-mynavi-sample-lambda-errorhandling-for-deploy
AccessControl: Private
PublicAccessBlockConfiguration:
BlockPublicAcls: True
BlockPublicPolicy: True
IgnorePublicAcls: True
RestrictPublicBuckets: True
Outputs:
S3Bucket:
Description: Lambda deploy S3 bucket name
Value: !Ref S3Bucket
Export:
Name: debugroom-mynavi-sample-lambda-errorhandling-deploy-s3-bucket
S3BucketArn:
Description: Deploy S3 for Lambda bucket arn
Value: !GetAtt S3Bucket.Arn
Export:
Name: debugroom-mynavi-sample-lambda-errorhandling-deploy-s3-bucket-arn
続いて、前回実装したLambdaファンクションをビルドして、このバケットにアップロードしますが、以下のようなスクリプトを実行すると簡易です。Java仮想マシンのルートディレクトリとなるJAVA_HOME環境変数やMavenのビルドコマンドのパスなどは、適宜自分の環境に合わせて書き換えてください。なお、コマンドを実行するためのAWS CLIのインストールや開発端末の認証情報の設定は、連載「AWSで実践! 基盤構築・デプロイ自動化」の第22回で解説した手順に沿って行っておくとよいでしょう。
#!/usr/bin/env bash
export JAVA_HOME=/usr/lib/jvm/java-11-amazon-corretto.x86_64
bucket_name="debugroom-mynavi-sample-lambda-errorhandling-for-deploy"
stack_name="mynavi-sample-deploy-s3-for-lambda-errorhandling"
template_path="cloudformation/1-s3-for-lambda-deploy-cfn.yml"
s3_objectkey="spring-cloud-3-1-lambda-function-0.0.1-SNAPSHOT-aws.jar"
if [ "" == "`aws s3 ls | grep $bucket_name`" ]; then
aws cloudformation deploy --stack-name ${stack_name} --template-file ${template_path} --capabilities CAPABILITY_IAM
fi
cd spring-cloud-3-1-lambda-function
./mvnw clean package
aws s3 cp target/${s3_objectkey} s3://${bucket_name}/
続いて、Lambda実行環境のCloudFormationテンプレートを実装します。
AWSTemplateFormatVersion: '2010-09-09'
#omit
Resources:
LambdaForSyncExecuteBusinessErrorFuntion:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket:
Fn::ImportValue: debugroom-mynavi-sample-lambda-errorhandling-deploy-s3-bucket #(1)
S3Key: spring-cloud-3-1-lambda-function-0.0.1-SNAPSHOT-aws.jar
Handler: org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequest #(2)
FunctionName: mynavi-sample-aws-lambda-errorhandling-sync-business-error
Environment:
Variables:
SPRING_CLOUD_FUNCTION_DEFINITION: syncExecuteBusinessErrorFunction #(3)
MemorySize: 1024
Runtime: java11
Timeout: 120
Role: !GetAtt LambdaRole.Arn #(4)
#omit
LambdaRole:
Type: AWS::IAM::Role
Properties:
Path: /
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
Service: lambda.amazonaws.com
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
#omit
Outputs:
#omit
LambdaForSyncExecuteBusinessErrorFuntion: #(5)
Description: Sync execute Lambda function for occuring business error function.
Value: !Ref LambdaForSyncExecuteBusinessErrorFuntion
Export:
Name: mynavi-sample-lambda-errorhandling-sync-execute-business-error-function-name
LambdaForSyncExecuteBusinessErrorFuntionArn: #(6)
Description: Sync execute Lambda function for occuring business error function.
Value: !GetAtt LambdaForSyncExecuteBusinessErrorFuntion.Arn
Export:
Name: mynavi-sample-lambda-errorhandling-sync-execute-business-error-function-arn
#omit
Lambdaテンプレートのポイントの詳細は以下の通りです。
項番 | 説明 |
---|---|
1 | S3Bucketは上述したデプロイ用のS3を構築したテンプレートでエクスポートしたS3のバケット名をクロススタックリファレンス参照します |
2 | リクエストのハンドラとして、org.springframework.cloud.function.adapter.aws.FunctionInvokerを指定します |
3 | 環境変数SPRING_CLOUD_FUNCTION_DEFINITIONに、前回実装したファンクションのBean名を指定します |
4 | 構築するLambdaファンクションに実行に必要なロールを設定します |
5 | 後述するAPI Gatewayの設定時に必要なLambdaファンクション名をエクスポートしておきます |
6 | 後述するAPI Gatewayの設定時に必要なLambdaファンクションのARNをエクスポートしておきます |
API GatewayのCloudFormationテンプレート
続いて、Lambdaファンクションを呼び出すAPI GatewayのCloudformationテンプレートを実装します。
AWSTemplateFormatVersion: '2010-09-09'
#omit
Resources:
ApiGatewayRestApi: #(1)
Type: "AWS::ApiGateway::RestApi"
Properties:
Name: "mynavi-sample-lambda-errorhandling-rest-api"
Description: "Mynavi sample sync execute function API"
ApiGatewayDeployment: #(2)
Type: "AWS::ApiGateway::Deployment"
DependsOn:
- ApiGatewayBusinessExceptionMethod
Properties:
RestApiId:
Ref: ApiGatewayRestApi
ApiGatewayStage: #(3)
Type: "AWS::ApiGateway::Stage"
Properties:
StageName: "dev"
Description: "dev stage"
RestApiId:
Ref: ApiGatewayRestApi
DeploymentId:
Ref: ApiGatewayDeployment
ApiGatewayModel: #(4)
Type: "AWS::ApiGateway::Model"
Properties:
RestApiId:
Ref: ApiGatewayRestApi
ContentType: "application/json"
Name: SampleSchema
Schema:
"$schema": "http://json-schema.org/draft-04/schema#"
title: SampleResource #(5)
type: object
properties:
message:
type: string
ApiGatewayBusinessExceptionResource: #(6)
Type: "AWS::ApiGateway::Resource"
Properties:
RestApiId:
Ref: ApiGatewayRestApi
ParentId:
Fn::GetAtt:
- ApiGatewayRestApi
- RootResourceId
PathPart: "business-exception-sample-resource"
#omit
ApiGatewayBusinessExceptionMethod: #(7)
Type: "AWS::ApiGateway::Method"
DependsOn: ApiGatewayModel
Properties:
RestApiId:
Ref: ApiGatewayRestApi
ResourceId:
Ref: ApiGatewayBusinessExceptionResource
HttpMethod: "GET"
AuthorizationType: "NONE"
Integration:
Type: "AWS_PROXY" #(8)
Uri: #(9)
Fn::Join:
- ""
- - "arn:aws:apigateway"
- ":"
- Ref: AWS::Region
- ":"
- "lambda:path/2015-03-31/functions/"
- Fn::ImportValue: mynavi-sample-lambda-errorhandling-sync-execute-business-error-function-arn
- "/invocations"
IntegrationHttpMethod: "POST"
IntegrationResponses:
- StatusCode: 400
SelectionPattern: 400
- StatusCode: 200
PassthroughBehavior: WHEN_NO_MATCH
MethodResponses: #(10)
- StatusCode: 200
ResponseModels:
application/json: SampleSchema
- StatusCode: 400
ResponseModels:
application/json: Error
#omit
ApiGatewayUsagePlan: #(11)
Type: AWS::ApiGateway::UsagePlan
Properties:
ApiStages:
- ApiId:
Ref: ApiGatewayRestApi
Stage:
Ref: ApiGatewayStage
Quota:
Limit: 100
Period: DAY
Throttle:
BurstLimit: 10
RateLimit: 2
UsagePlanName: "SampleUsagePlan"
BusinessErrorLambdaPermission: #(12)
Type: "AWS::Lambda::Permission"
Properties:
FunctionName:
Fn::ImportValue: mynavi-sample-lambda-errorhandling-sync-execute-business-error-function-name
Action: "lambda:InvokeFunction"
Principal: "apigateway.amazonaws.com"
API Gatewayテンプレートのポイントの詳細は以下の通りです。
項番 | 説明 |
---|---|
1 | API GatewayでRestAPIを定義します。各プロパティの詳細はAWS::ApiGateway::RestApiを参照してください |
2 | API GatewayでRestAPIをデプロイさせた状態で構築します。各プロパティの詳細は AWS::ApiGateway::Deploymentを参照してください |
3 | API GatewayでRestAPIをデプロイさせるためのステージを定義します。各プロパティの詳細は AWS::ApiGateway::Stageを参照してください。ここでステージは開発用の"dev"を定義しておきます |
4 | API Gateway RestAPIで返却するモデルを定義します。各プロパティの詳細はAWS::ApiGateway::Modelを参照してください |
5 | モデルのスキーマとして、前回実装したリソースクラスSampleResourceおよびそのプロパティを定義します |
6 | API Gatewayが返却するリソースやパスを定義します。各プロパティの詳細はAWS::ApiGateway::Resourceを参照してください |
7 | Rest APIのメソッドを定義します。各プロパティの詳細はAWS::ApiGateway::Methodを参照してください |
8 | API GatewayからLambdaへリクエストを転送する際のリクエストデータの変換方法を統合モデルとして定義します。Spring Cloud Functionでは、「Lambdaプロキシ統合」である設定値"AWS_PROXY"を前提としています。なお、Lambdaプロキシ統合の詳細については、 AWS公式ページ「API Gateway で Lambda プロキシ統合を設定する」 も参照してください |
9 | 実行するLambdaファンクションのURIを定義します。前節のLambdaテンプレートで出力したファンクションのARNをクロススタックリファレンスで参照し、URIをJOIN関数で構築します |
10 | Lambda統合オプションでLambdaから返却されたアウトプットデータをAPI Gatewayでレスポンスデータとして変換する方法を定義します。正常終了時には5で定義したモデルクラスを返却し、ビジネスエラーが発生する400の場合は、デフォルトでAPI Gatewayが用意しているモデルErrorスキーマを用いてマッピングします |
11 | RestAPIのリクエスト量を調整する使用プランを定義します。使用量プランは、APIごとにスロットリングとクォータ制限が適用されます。各プロパティの詳細はAWS::ApiGateway::UsagePlanを参照してください |
12 | API GatewayがLambda関数を呼び出すのに必要な権限を定義します。各プロパティの詳細はAWS::Lambda::Permissionを参照してください |
作成したテンプレートをCLIから実行すると、環境が構築されます。マネジメントコンソール上で、以下のように作成したリソースのメソッドを選択し、赤枠で囲まれたテストを選択してください。
クエリ文字列を指定しない状態で「テスト」ボタンを押下すると、ステータスコード400で返却されます。何かしらの文字列を指定すると、ステータスコード200で正常応答します(なお、初回の実行はLambdaの起動でタイムアウトになるケースもあります)。
* * *
今回は、CloudFormationを使ってAPI GatewayとLambdaを構築し、Lambdaを同期的に呼び出してビジネスエラーを発生させ、エラーに応じてステータスコードが適切にマッピングするように設定する例を解説しました。次回以降は、同じくAPI GatewayとLambdaを使用した同期呼び出しで、システムエラーが発生した際に、CloudWatchに出力されたエラーログを契機として、システム管理者へ通知を行う実装を含めて解説していきます。著者紹介
川畑 光平(KAWABATA Kohei) - NTTデータ
エグゼクティブ ITスペシャリスト ソフトウェアアーキテクト・デジタルテクノロジーストラテジスト(クラウド)
金融機関システム業務アプリケーション開発・システム基盤担当、ソフトウェア開発自動化関連の研究開発を経て、デジタル技術関連の研究開発・推進に従事。
Red Hat Certified Engineer、Pivotal Certified Spring Professional、AWS Certified Solutions Architect Professional等の資格を持ち、アプリケーション基盤・クラウドなど様々な開発プロジェクト支援にも携わる。AWS Top Engineers & Ambassadors選出。
本連載の内容に対するご意見・ご質問は Facebook まで。
April 05, 2021 at 06:00AM
https://ift.tt/3dCVuDm
【連載】AWSで作るクラウドネイティブアプリケーションの応用 [8] AWS Lambdaにおけるサーバレスエラーハンドリング(3) - マイナビニュース
https://ift.tt/35vzQLu
Mesir News Info
Israel News info
Taiwan News Info
Vietnam News and Info
Japan News and Info Update
Bagikan Berita Ini
0 Response to "【連載】AWSで作るクラウドネイティブアプリケーションの応用 [8] AWS Lambdaにおけるサーバレスエラーハンドリング(3) - マイナビニュース"
Post a Comment