AWSサーバーレスアプリケーションモデルの概要
1. 概要
our previous articleでは、RESTエンドポイント用のAPI Gateway、ビジネスロジック用のAWS Lambda、およびデータベースとしてのDynamoDBを使用して、AWSにフルスタックサーバーレスアプリケーションをすでに実装しています。
ただし、展開は多くの手動の手順で構成されており、複雑さが増し、環境の数が増えると手間がかかる場合があります。
このチュートリアルでは、AWS Serverless Application Model (SAM), which enables a template-based description and automated deployment of serverless applications on AWSの使用方法について説明します。
詳細については、次のトピックを見ていきます。
-
サーバーレスアプリケーションモデル(SAM)の基礎と、基盤となるCloudFormationの基礎
-
SAMテンプレート構文を使用したサーバーレスアプリケーションの定義
-
CloudFormation CLIを使用したアプリケーションの自動展開
2. 基本
previouslyで説明したように、AWSでは、API Gateway、Lambda関数、DynamoDBを使用して、完全にサーバーレスのアプリケーションを実装できます。 間違いなく、それはパフォーマンス、コスト、およびスケーラビリティに関してすでに多くの利点を提供します。
ただし、現時点では、各関数の作成、コードのアップロード、DynamoDBテーブルの作成、IAMロールの作成、APIおよびAPI構造の作成など、AWSコンソールで多くの手動手順が必要になるという欠点があります
複雑なアプリケーションの場合、テスト、ステージング、本番などの複数の環境では、その労力は急速に増大します。
これは一般にAWS上のアプリケーションのCloudFormationであり、特にサーバーレスアプリケーション専用のサーバーレスアプリケーションモデル(SAM)が登場します。
2.1. AWS CloudFormation
CloudFormationは、AWSインフラストラクチャリソースを自動プロビジョニングするためのAWSサービスです。 ユーザーがブループリント(テンプレートと呼ばれる)で必要なすべてのリソースを定義し、AWSがプロビジョニングと構成を処理します。
CloudFormationとSAMを理解するには、次の用語と概念が不可欠です。
A template is a description of an application、実行時にどのように構造化するか。 必要なリソースのセットと、これらのリソースの構成方法を定義できます。 CloudFormationは、テンプレートを定義し、JSONおよびYAMLをフォーマットとしてサポートするための共通言語を提供します。
Resources are the building blocks in CloudFormation.リソースには、RestApi、RestApiのステージ、バッチジョブ、DynamoDBテーブル、EC2インスタンス、ネットワークインターフェイス、IAMロールなど、何でもかまいません。 The official documentationは現在、CloudFormationの約300のリソースタイプを一覧表示しています。
A stack is the instantiation of a template. CloudFormationは、スタックのプロビジョニングと構成を処理します。
2.2. サーバーレスアプリケーションモデル(SAM)
多くの場合、強力なツールの使用は非常に複雑で扱いにくくなる可能性がありますが、これはCloudFormationの場合にも当てはまります。
AmazonがServerless Application Model(SAM)を導入したのはそのためです。 SAM started with the claim to provide a clean and straightforward syntax for defining serverless applications. Currently, it has only three resource types, which are Lambda functions, DynamoDB tables, and APIs。
SAMはCloudFormationテンプレート構文に基づいているため、単純なSAM構文を使用してテンプレートを定義でき、CloudFormationはそのテンプレートをさらに処理します。
詳細については、at the official GitHub repositoryおよびAWS documentation内をご覧ください。
3. 前提条件
次のチュートリアルでは、AWSアカウントが必要です。 A free tier accountで十分です。
さらに、AWS CLIinstalledが必要です。
最後に、リージョンにS3バケットが必要です。これは、AWS CLIから次のコマンドを使用して作成できます。
$>aws s3 mb s3://example-sam-bucket
以下ではチュートリアルでexample-sam-bucketを使用していますが、バケット名は一意である必要があるため、名前を選択する必要があることに注意してください。
デモアプリケーションとして、Using AWS Lambda with API Gatewayのコードを使用します。
4. テンプレートの作成
このセクションでは、SAMテンプレートを作成します。
個々のリソースを定義する前に、まず全体的な構造を確認します。
4.1. テンプレートの構造
まず、テンプレートの全体的な構造を見てみましょう。
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: example Serverless Application Model example
Resources:
PersonTable:
Type: AWS::Serverless::SimpleTable
Properties:
# Define table properties here
StorePersonFunction:
Type: AWS::Serverless::Function
Properties:
# Define function properties here
GetPersonByHTTPParamFunction:
Type: AWS::Serverless::Function
Properties:
# Define function properties here
MyApi:
Type: AWS::Serverless::Api
Properties:
# Define API properties here
ご覧のとおり、テンプレートはヘッダーと本文で構成されています。
ヘッダーは、CloudFormationテンプレートのバージョン(AWSTemplateFormatVersion)とSAMテンプレートのバージョン(Transform)を指定します。 Descriptionを指定することもできます。
本体はリソースのセットで構成されます。各リソースには、名前、リソースType、およびPropertiesのセットがあります。
SAM仕様は現在、AWS::Serverless::Api、AWS::Serverless::Function、およびAWS::Serverless::SimpleTableの3つのタイプをサポートしています。
example applicationをデプロイするため、テンプレート本体に1つのSimpleTable、2つのFunctions、および1つのApiを定義する必要があります。
4.2. DynamoDBテーブル定義
今すぐDynamoDBテーブルを定義しましょう:
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: example Serverless Application Model example
Resources:
PersonTable:
Type: AWS::Serverless::SimpleTable
Properties:
PrimaryKey:
Name: id
Type: Number
TableName: Person
SimpleTableには、テーブル名と、idと呼ばれ、この場合はタイプNumber の主キーの2つのプロパティを定義するだけで済みます。
サポートされているSimpleTableプロパティの完全なリストは、in the official specificationにあります。
注:主キーを使用してテーブルにアクセスするだけなので、AWS::Serverless::SimpleTableで十分です。 より複雑な要件の場合は、代わりにネイティブのCloudFormationタイプAWS::DynamoDB::Tableを使用できます。
4.3. ラムダ関数の定義
次に、2つの関数を定義しましょう。
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: example Serverless Application Model example
Resources:
StorePersonFunction:
Type: AWS::Serverless::Function
Properties:
Handler: com.example.lambda.apigateway.APIDemoHandler::handleRequest
Runtime: java8
Timeout: 15
MemorySize: 512
CodeUri: ../target/aws-lambda-0.1.0-SNAPSHOT.jar
Policies: DynamoDBCrudPolicy
Environment:
Variables:
TABLE_NAME: !Ref PersonTable
Events:
StoreApi:
Type: Api
Properties:
Path: /persons
Method: PUT
RestApiId:
Ref: MyApi
GetPersonByHTTPParamFunction:
Type: AWS::Serverless::Function
Properties:
Handler: com.example.lambda.apigateway.APIDemoHandler::handleGetByParam
Runtime: java8
Timeout: 15
MemorySize: 512
CodeUri: ../target/aws-lambda-0.1.0-SNAPSHOT.jar
Policies: DynamoDBReadPolicy
Environment:
Variables:
TABLE_NAME: !Ref PersonTable
Events:
GetByPathApi:
Type: Api
Properties:
Path: /persons/{id}
Method: GET
RestApiId:
Ref: MyApi
GetByQueryApi:
Type: Api
Properties:
Path: /persons
Method: GET
RestApiId:
Ref: MyApi
ご覧のとおり、各関数には同じプロパティがあります。
Handler defines the logic of the function. Javaを使用しているため、メソッド名に関連するパッケージを含むクラス名です。
Runtime defines how the function was implemented、この場合はJava8です。
AWSが実行を終了する前のTimeout defines how long the execution of the code may take at most。
MemorySizedefines the size of the assigned memory in MB. AWSはCPUリソースをMemorySizeに比例して割り当てることを知っておくことが重要です。 そのため、CPUを集中的に使用する関数の場合、関数がそれほど多くのメモリを必要としない場合でも、MemorySizeを増やす必要がある場合があります。
CodeUridefines the location of the function code.現在、ローカルワークスペースのターゲットフォルダーを参照しています。 後でCloudFormationを使用して関数をアップロードすると、S3オブジェクトへの参照を含む更新されたファイルが取得されます。
Policiescan hold a set of AWS-managed IAM policies or SAM-specific policy templates.StorePersonFunctionにはSAM固有のポリシーDynamoDBCrudPolicyを使用し、GetPersonByPathParamFunctionとGetPersonByQueryParamFunctionにはDynamoDBReadPolicyを使用します。
Environmentdefines environment properties at runtime.DynamoDBテーブルの名前を保持するために環境変数を使用します。
Eventscan hold a set of AWS events, which shall be able to trigger the function.この場合、タイプApiのEventを定義します。 path、HTTPMethod、およびRestApiIdの一意の組み合わせにより、関数がAPIのメソッドにリンクされます。これについては次のセクションで定義します。
サポートされているFunctionプロパティの完全なリストは、in the official specificationにあります。
4.4. SwaggerファイルとしてのAPI定義
DynamoDBテーブルと関数を定義したら、APIを定義できるようになりました。
最初の可能性は、Swagger形式を使用してAPIをインラインで定義することです。
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: example Serverless Application Model example
Resources:
MyApi:
Type: AWS::Serverless::Api
Properties:
StageName: test
EndpointConfiguration: REGIONAL
DefinitionBody:
swagger: "2.0"
info:
title: "TestAPI"
paths:
/persons:
get:
parameters:
- name: "id"
in: "query"
required: true
type: "string"
x-amazon-apigateway-request-validator: "Validate query string parameters and\
\ headers"
x-amazon-apigateway-integration:
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetPersonByHTTPParamFunction.Arn}/invocations
responses: {}
httpMethod: "POST"
type: "aws_proxy"
put:
x-amazon-apigateway-integration:
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${StorePersonFunction.Arn}/invocations
responses: {}
httpMethod: "POST"
type: "aws_proxy"
/persons/{id}:
get:
parameters:
- name: "id"
in: "path"
required: true
type: "string"
responses: {}
x-amazon-apigateway-integration:
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetPersonByHTTPParamFunction.Arn}/invocations
responses: {}
httpMethod: "POST"
type: "aws_proxy"
x-amazon-apigateway-request-validators:
Validate query string parameters and headers:
validateRequestParameters: true
validateRequestBody: false
Api には3つのプロパティがあります。StageNameはAPIのステージを定義し、EndpointConfigurationはAPIがリージョナルかエッジ最適化かを定義し、DefinitionBody はAPIの実際の構造を含みます。
DefinitionBodyでは、3つのパラメータを定義します。swagger versionを“2.0”、info:title:を“TestAPI”、および一連のpathsです。 。
ご覧のとおり、pathsはAPI構造を表しており、手動でbeforeを定義する必要がありました。 Swaggerのpathsは、AWSコンソールのリソースに相当します。 そのように、各pathには、AWSコンソールのメソッドと同等の1つ以上のHTTP動詞を含めることができます。
各メソッドには、1つ以上のパラメーターと要求検証ツールを含めることができます。
最もエキサイティングな部分は、属性x-amazon-apigateway-integrationです。これは、SwaggerのAWS固有の拡張機能です。
uriは、呼び出すLambda関数を指定します。
responsesは、関数によって返される応答を変換する方法のルールを指定します。 Lambda Proxy Integrationを使用しているため、特定のルールは必要ありません。
typeは、Lambdaプロキシ統合を使用することを定義します。したがって、httpMethodを“POST”に設定する必要があります。これは、Lambda関数が期待するものです。
サポートされているApiプロパティの完全なリストは、in the official specificationにあります。
4.5. 暗黙のAPI定義
2番目のオプションは、Functionリソース内で暗黙的にAPIを定義することです。
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: example Serverless Application Model Example with Implicit API Definition
Globals:
Api:
EndpointConfiguration: REGIONAL
Name: "TestAPI"
Resources:
StorePersonFunction:
Type: AWS::Serverless::Function
Properties:
Handler: com.example.lambda.apigateway.APIDemoHandler::handleRequest
Runtime: java8
Timeout: 15
MemorySize: 512
CodeUri: ../target/aws-lambda-0.1.0-SNAPSHOT.jar
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref PersonTable
Environment:
Variables:
TABLE_NAME: !Ref PersonTable
Events:
StoreApi:
Type: Api
Properties:
Path: /persons
Method: PUT
GetPersonByHTTPParamFunction:
Type: AWS::Serverless::Function
Properties:
Handler: com.example.lambda.apigateway.APIDemoHandler::handleGetByParam
Runtime: java8
Timeout: 15
MemorySize: 512
CodeUri: ../target/aws-lambda-0.1.0-SNAPSHOT.jar
Policies:
- DynamoDBReadPolicy:
TableName: !Ref PersonTable
Environment:
Variables:
TABLE_NAME: !Ref PersonTable
Events:
GetByPathApi:
Type: Api
Properties:
Path: /persons/{id}
Method: GET
GetByQueryApi:
Type: Api
Properties:
Path: /persons
Method: GET
ご覧のとおり、テンプレートは少し異なります。AWS::Serverless::Api resourceはもうありません。
ただし、CloudFormationはタイプApiのEvents属性を暗黙の定義として受け取り、とにかくAPIを作成します。 アプリケーションをテストするとすぐに、Swaggerを使用してAPIを明示的に定義した場合と同じように動作することがわかります。
さらに、Globalsセクションがあり、APIの名前を定義できます。また、エンドポイントはリージョナルである必要があります。
1つの制限のみが発生します。APIを暗黙的に定義する場合、ステージ名を設定できません。 これが、AWSがいずれにせよProdと呼ばれるステージを作成する理由です。
5. 展開とテスト
テンプレートを作成したら、展開とテストに進むことができます。
このため、実際のデプロイをトリガーする前に、関数コードをS3にアップロードします。
最終的に、HTTPクライアントを使用してアプリケーションをテストできます。
5.1. S3へのコードのアップロード
最初のステップでは、機能コードをS3にアップロードする必要があります。
AWS CLIを介してCloudFormationを呼び出すことでこれを行うことができます。
$> aws cloudformation package --template-file ./sam-templates/template.yml --s3-bucket example-sam-bucket --output-template-file ./sam-templates/packaged-template.yml
このコマンドを使用して、CloudFormationをトリガーし、CodeUri:で指定された関数コードを取得してS3にアップロードします。 CloudFormationは、CodeUri:がS3オブジェクトを指すようになったことを除いて、同じコンテンツを持つpackaged-template.ymlファイルを作成します。
CLI出力を見てみましょう。
Uploading to 4b445c195c24d05d8a9eee4cd07f34d0 92702076 / 92702076.0 (100.00%)
Successfully packaged artifacts and wrote output template to file packaged-template.yml.
Execute the following command to deploy the packaged template
aws cloudformation deploy --template-file c:\zz_workspace\tutorials\aws-lambda\sam-templates\packaged-template.yml --stack-name
5.2. 展開
これで、実際の展開をトリガーできます。
$> aws cloudformation deploy --template-file ./sam-templates/packaged-template.yml --stack-name example-sam-stack --capabilities CAPABILITY_IAM
スタックにはIAMロール(DynamoDBテーブルにアクセスするための関数のロールなど)も必要なので、–capabilities parameterを指定して明示的に確認する必要があります。
CLI出力は次のようになります。
Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - example-sam-stack
5.3. 展開レビュー
展開後、結果を確認できます。
$> aws cloudformation describe-stack-resources --stack-name example-sam-stack
CloudFormationは、スタックの一部であるすべてのリソースをリストします。
5.4. Test
最後に、任意のHTTPクライアントを使用してアプリケーションをテストできます。
これらのテストに使用できるいくつかのサンプルcURLコマンドを見てみましょう。
StorePersonFunction:
$> curl -X PUT 'https://0skaqfgdw4.execute-api.eu-central-1.amazonaws.com/test/persons' \
-H 'content-type: application/json' \
-d '{"id": 1, "name": "John Doe"}'
GetPersonByPathParamFunction:
$> curl -X GET 'https://0skaqfgdw4.execute-api.eu-central-1.amazonaws.com/test/persons/1' \
-H 'content-type: application/json'
GetPersonByQueryParamFunction:
$> curl -X GET 'https://0skaqfgdw4.execute-api.eu-central-1.amazonaws.com/test/persons?id=1' \
-H 'content-type: application/json'
5.5. 掃除
最後に、スタックと含まれているすべてのリソースを削除することでクリーンアップできます。
aws cloudformation delete-stack --stack-name example-sam-stack
6. 結論
この記事では、AWS Serverless Application Model(SAM)について説明しました。これにより、AWSでのサーバーレスアプリケーションのテンプレートベースの説明と自動展開が可能になります。
詳細については、次のトピックについて説明しました。
-
サーバーレスアプリケーションモデル(SAM)の基礎と、基盤となるCloudFormation
-
SAMテンプレート構文を使用したサーバーレスアプリケーションの定義
-
CloudFormation CLIを使用したアプリケーションの自動展開
いつものように、この記事のすべてのコードはon GitHubで利用できます。