はじめに
前回、AWS公式のハンズオンシリーズの中から、翻訳 Web API の構築を通して、サーバーレスアーキテクチャの基本を学ぶハンズオンを実施しました。
参考:AWSハンズオン実践メモ 〜サーバーレスアーキテクチャで翻訳 Web API を構築する〜
今回は、前回のハンズオンで構築した翻訳 Web API をAWS Serverless Application Model (AWS SAM)を用いてテンプレートから構築します。
AWS Serverless Application Model (AWS SAM)とは、サーバーレスアプリケーション構築用のオープンソースフレームワークです。簡単に言うと、サーバレスな構成を作ることに特化した Cloudformation のテンプレートになります。
本記事は自身のハンズオン学習メモとして投稿します。
目次
ハンズオンの目的
- AWS Serverless Application Model (AWS SAM)を用いて、サーバーレス構成を自動構築する
前回の Serverless #1 で構築した翻訳 Web API を AWS Serverless Application Model (AWS SAM) を用いてテンプレートから構築します。前回のハンズオンでは全ての工程を手作業で(マネージメントコンソール上で)構築していきました。今回のハンズオンではこの構築作業をテンプレート化し、作成したテンプレートから AWS リソースを構築していきます。テンプレート化することで、そのテンプレートをバージョン管理できるようになる、チーム内でレビューがしやすくなる、といった利点があり、プロダクト開発をより効率的に進めることができます。
(https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-hands-on/ より引用)
本編
Cloud9 のセットアップ+Cloud9 で簡単な Lambda 関数を作成する
- Cloud9で環境を作成
- Cloud9からLambdaを作成&編集
SAM で Lambda 関数を作成する①
AM を利用するための事前準備を行い、Lambda 関数の設定情報を SAM テンプレートに記載していく。
- translate-function.pyを作成
import json
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def lambda_handler(event, context):
logger.info(event)
return {
'statusCode': 200,
'body': json.dumps('Hello Hands on world!')
}
- template.yamlを作成
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: AWS Hands-on for Beginners - Serverless 2
Resources:
TranslateLambda:
Type: AWS::Serverless::Function
Properties:
FunctionName: translate-function-2
CodeUri: ./translate-function
Handler: translate-function.lambda_handler
Runtime: python3.7
Timeout: 5
MemorySize: 256
- 作成したファイルをパッケージング
aws cloudformation package \
--template-file template.yaml \
--s3-bucket 20200714handsonserverless \
--output-template-file packaged-template.yaml
このコマンドで、S3 にファイルがアップロードされ、そのファイルのUri が --template-file で指定したテンプレートに書き足され、--output-template-file で指定したファイル名で出力される。
- デプロイ
aws cloudformation deploy \
--template-file ./packaged-template.yaml \
--stack-name hands-on-serverless-2 \
--capabilities CAPABILITY_IAM
パッケージで書き出したテンプレートファイルを元に、AWS CLI の CloudFormation の deployコマンドを叩く。これで、テンプレートに記述されている通りのリソースが構築される。
SAM で Lambda 関数を作成する②
SAM テンプレートファイルをアップデートし、Lambda 関数から別の AWS サービスを呼び出せるよう IAM 設定を修正。
- translate-function.pyを編集
import json
import boto3
translate = boto3.client('translate')
def lambda_handler(event, context):
input_text = "こんにちは"
response = translate.translate_text(
Text=input_text,
SourceLanguageCode='ja',
TargetLanguageCode='en'
)
output_text = response.get('TranslatedText')
return {
'statusCode': 200,
'body': json.dumps({
'output_text': output_text
})
}
- template.yamlを編集(Policies: - TranslateFullAccessを追加)
- 作成したファイルをパッケージング(先程と同様)
- デプロイ(先程と同様)
SAM で API Gateway のリソースを作成し、Lambda 関数と連携させる
API Gateway リソースを作成する際の設定を SAM テンプレートに記載し、外部からリクエストを受け付けられる Web API を構築する。
- translate-function.pyを編集
import json
import boto3
translate = boto3.client(service_name='translate')
def lambda_handler(event, context):
input_text = event['queryStringParameters']['input_text']
response = translate.translate_text(
Text=input_text,
SourceLanguageCode="ja",
TargetLanguageCode="en"
)
output_text = response.get('TranslatedText')
return {
'statusCode': 200,
'body': json.dumps({
'output_text': output_text
}),
'isBase64Encoded': False,
'headers': {}
}
- template.yamlを編集
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: AWS Hands-on for Beginners - Serverless 2
Resources:
TranslateLambda:
Type: AWS::Serverless::Function
Properties:
FunctionName: translate-function-2
CodeUri: ./translate-function
Handler: translate-function.lambda_handler
Runtime: python3.7
Timeout: 5
MemorySize: 256
Policies:
- TranslateFullAccess
Events:
GetApi:
Type: Api
Properties:
Path: /translate
Method: get
RestApiId: !Ref TranslateAPI
TranslateAPI:
Type: AWS::Serverless::Api
Properties:
Name: translate-api-2
StageName: dev
EndpointConfiguration: REGIONAL
- 作成したファイルをパッケージング(先程と同様)
- デプロイ(先程と同様)
以下のようにクエリ部分にリクエストを入力し送信すると、翻訳結果が返却される。
SAM で DynamoDB TBL を作成し、Lambda 関数を連携させる
DynamoDB テーブルを作成する際の設定情報を SAM テンプレートに記載する。また、Lambda 関数側の記載も修正し、DynamoDB に翻訳リクエストの履歴情報を書き込めるようにする。
- translate-function.pyを編集
import json
import boto3
import datetime
translate = boto3.client(service_name='translate')
dynamodb_translate_history_tbl = boto3.resource('dynamodb').Table('translate-history-2')
def lambda_handler(event, context):
input_text = event['queryStringParameters']['input_text']
response = translate.translate_text(
Text=input_text,
SourceLanguageCode="ja",
TargetLanguageCode="en"
)
output_text = response.get('TranslatedText')
dynamodb_translate_history_tbl.put_item(
Item = {
"timestamp": datetime.datetime.now().strftime("%Y%m%d%H%M%S"),
"input": input_text,
"output": output_text
}
)
return {
'statusCode': 200,
'body': json.dumps({
'output_text': output_text
}),
'isBase64Encoded': False,
'headers': {}
}
- template.yamlを編集
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: AWS Hands-on for Beginners - Serverless 2
Resources:
TranslateLambda:
Type: AWS::Serverless::Function
Properties:
FunctionName: translate-function-2
CodeUri: ./translate-function
Handler: translate-function.lambda_handler
Runtime: python3.7
Timeout: 5
MemorySize: 256
Policies:
- TranslateFullAccess
- AmazonDynamoDBFullAccess
Events:
GetApi:
Type: Api
Properties:
Path: /translate
Method: get
RestApiId: !Ref TranslateAPI
TranslateAPI:
Type: AWS::Serverless::Api
Properties:
Name: translate-api-2
StageName: dev
EndpointConfiguration: REGIONAL
TranslateDynamoDbTbl:
Type: AWS::Serverless::SimpleTable
Properties:
TableName: translate-history-2
PrimaryKey:
Name: timestamp
Type: String
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
- 作成したファイルをパッケージング(先程と同様)
- デプロイ(先程と同様)
以下のように翻訳結果がdynamoDBに蓄積される。
作成した AWS リソースの削除
CloudFormationのスタックを削除すると関連するリソースが全て削除される。
#おわりに
今回はSAMを利用し、IaaCでサーバーレスアーキテクチャを構築した。
プロジェクトにおいてAWSで設計・構築する際はCloudFormationを使っていく事になると思うので、記法や管理方法についても学習したい。
#参考
[新ツール] AWS Serverless Application Model (AWS SAM) を使ってサーバーレスアプリケーションを構築する