AWS SAMを用いてサーバーレスな環境を自動構築する
ゴール
・AWS Serverless Application Model (SAM)を用いて、サーバーレス構成を自動構築する
・今回は、前回のハンズオンで構築した構成を、SAMで少しずつ作っていきます
- 前回のハンズオンの復習と今回のハンズオンの概要
- AWS SAMの紹介とAWS Cloud9の紹介
- Cloud9のセットアップ + Cloud9で簡単なLambda関数を作成する
- SAMでLambda関数を作成する1
- SAMでLambda関数を作成する2
- SAMでAPI Gatewayのリソースを作成し、Lambda関数と連携させる
- SAMでDynamoDB TBLを作成し、Lambda関数を連携させる
- SAM CLIを使ってみる
- SAM CLIを使ってみる
- クリーンアップ&落穂ひろい
前回のハンズオンの復習
AWS Lambdaの特徴
・サーバーのプロビジョニング/管理なしでプログラムを実行できるサービス
・コードの実行やスケーリングに必要なことは、Lambda側で実施するので、開発者の方はコードを書くことにより集中できる
・リクエストベースの料金体系(実行回数+実行時間)
Amazon API Gatewayの特徴
・サーバーをプロビジョニング/管理することなく、APIを作成・管理できるマネージドサービス
・可用性の担保、スケーリング、APIキー管理といったAPI開発で必要なことをAPI Gatewayに任せることで、開発者はビジネスの差別化につながる作業に集中できる
・REST APIとWebSocketに対応
・リクエストベースの料金体系(REST APIの場合 実行回数+キャッシュメモリ量+データ転送料金)
Amazon DymamoDBの特徴
・フルマーネジド型のNoSQLデータベースサービス
・3つのAvailability Zoneに保存されるので信頼性が高い
・性能要件に応じて、テーブルごとにスループットキャパシティを定義するキャパシティのAuto Scaling、オンデマンドキャパシティといった設定も可能
・ストレージの容量制限がない
・料金体系(設定したRead・Writeキャパシティユニット+ストレージ利用料+オプション機能料金
今回はテンプレート化することでバージョン管理ができるようにする。
AWS CloufFormation
・AWSリソースのモデル化、およびセットアップ
・利用するAWSリソースをテンプレートに記述すると、各リソースのプロビジョニング・設定をAWS CloudFormationが実施する
・AWSリソースに関する記述が、テンプレート(テキストファイル)に集約されるので、現状の把握や変更の追跡が容易に
・YAML形式orJSON形式
・関連リソースはCloudFormationスタックに紐づく形で作成される。スタックを削除すればリソース群をまとめて削除することもできる
AWS Serverless Application Model(SAM)
・サーバーレスアプリケーション構築用のオープンソースフレームワーク
・AWS CloudFormationの拡張機能で、より簡潔にテンプレートを記述可能
・SAMテンプレートもYAML形式もしくはJSON形式で記述できる
・SAM CLIも提供されている
AWS SAMテンプレートの書き方
- リソースタイプを選択
- リソースタイプごとに必要なプロパティを記述
AWS SAM利用の流れ
- SAMテンプレートを記述
- パッケージングする
- デプロイする
ほとんどコマンドで対応する。
AWS Cloud9
・ブラウザのみでコードを記述、実行、デバッグ可能クラウドベースの統合開発環境(IDE)
・複数人でリアルタイムに共同コーディングできるチャット機能を利用し、ペアプログラミングも
・サーバーレスアプリケーションを簡単に構築できる
・ホストされるEC2インスタンス+EBS分の料金
AWS Cloud9のセットアップ
- マネジメントコンソールへログインする
- 東京リージョンで作成
- Cloud9を検索
- Create environment
- 環境名を入力、説明はなしでもOK
- デフォルトの設定で起動する
- AWS Resources
- Lambda Functionの作成
- FunctionNameとApplicationNameの入力
- ランタイムをPythonに設定
- ブループリントをempty-pythonに設定
- API Gatewayなどは設定せずに
- そのほかもデフォルトで設定
- 関数を少し編集
- デプロイ
SAMでLambda関数を作成する1
- Cloud9に戻る
- aws --versionで確認
- コマンドラインでS3バケットを作成
バケット名はユニークにする必要がある
aws s3 mb s://hands-on-serverless-matsumoto
- S3のコンソールで作成を確認
- ディレクトリ等の作成
$ mkdir hands-on-serverless-2
$ cd hands-on-serverless-2
$ mkdir translate-function
$ touch translate-function/translate-function.py
$ touch template.yaml
- translate-function.pyとtemplate.yamlを貼り付け
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
- それぞれのパラメータの確認
- cloudformationのパッケージ化
aws cloudformation package \
--template-file template.yaml \
--s3-bucket *your-backet-name* \
--output-template-file packaged-template.yaml
- cloudformationのdeploy
aws cloudformation deploy \
--template-file ./packaged-template.yaml \
--stack-name hands-on-serverless-2 \
--capabilities CAPABILITY_IAM
- Lambdaで確認する
SAMでLambda関数を作成する
- ファイル内容の修正
- input_textに何かしらの日本語を入力
- yamlファイルにポリシーを追加
Policies:
- TranslateFullAccess
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
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
- パッケージング化
aws cloudformation package \
--template-file template.yaml \
--s3-bucket *your-backet-name* \
--output-template-file packaged-template.yaml
- デプロイ
aws cloudformation deploy \
--template-file ./packaged-template.yaml \
--stack-name hands-on-serverless-2 \
--capabilities CAPABILITY_IAM
- Lambdaコンソールで更新の確認
SAMでAPI Gatewayのリソースを作成しLambda関数と連携させる
- コピペ
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
- パッケージング化
aws cloudformation package \
--template-file template.yaml \
--s3-bucket *your-backet-name* \
--output-template-file packaged-template.yaml
- デプロイ
aws cloudformation deploy \
--template-file ./packaged-template.yaml \
--stack-name hands-on-serverless-2 \
--capabilities CAPABILITY_IAM
-
Lambdaで確認
-
APIのGETメソッドで確認する
SAMでDynamoDBテーブルを作成して、Lambda関数と連携させる
- コピペ
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
- パッケージング化
aws cloudformation package \
--template-file template.yaml \
--s3-bucket *your-backet-name* \
--output-template-file packaged-template.yaml
- デプロイ
aws cloudformation deploy \
--template-file ./packaged-template.yaml \
--stack-name hands-on-serverless-2 \
--capabilities CAPABILITY_IAM
- DynamoDBのテーブル確認
- Lambdaで確認
- APIのGETメソッドで確認する
- DynamoDBの更新確認
SAM CLIを使ってみる(ここは少し構築方法が変わっているので確認する必要があります。)
AWS SAM Command Line Interfaceとは
・AWS SAMをローカル環境で利用する上で、様々な便利な機能を提供するCLI
- 要Dockerインストール
- 現在は一般提供中
・テンプレートを使ってサーバーレスアプリケーションを対話形式で初期化 sam init
・ローカル環境でビルド sam build
・AWS環境へデプロイ sam deploy --guided
・SAMテンプレートの事前検証 sam validate
・LambdaローカルエンドポイントやAPIエンドポイントを起動し、実行のテストが可能
sam local start-lambda / start-api
Cloud9にはSAM CLIがそもそも入っています。
初期化からビルド
sam init
1
9
Project Nameは空欄
キックスターターは1
cd sam-app
sam validate
sam build
sam deploy --guided
Stack Nameは空欄
ap-northeast-1
y
y
y
y
sam local start-lambda
別ターミナルでファンクションの実行をする
aws lambda invoke --function-name "HelloWorldFunction" --endpoint-url "http://127.0.0.1:3001" --no-verify-ssl out.txt
sam local start-api
curl http://http://127.0.0.1:3000/hello
削除
スタックを削除していく
Discussion