概要
AWSのコンソールで割と簡単にLambdaの処理とDynamoDBのテーブルを作成したり、編集したりすることができます。
ただ、チームでやるプロジェクトだと、バージョン管理とローカルのテストが重要になってきます。
SAMのCLIを使うと本物のコンソールを使わなくても、ローカルで動作確認もできますし、簡単にAWSにデプロイもできます。
環境の情報
- Windows 10
- Docker for Windows
- Visual Studio Code
- Python 3.7 (他のでも大丈夫だと思います)
プロジェクト作成
プロジェクトフォルダーを作成し、VSCodeで開きます。
Pythonの確認
VSCodeのターミナルは【Ctrl+@】で開けます。
sam-lambda-dynamodb> python -V
Python 3.7.2
pipの更新
sam-lambda-dynamodb> python -m pip install --upgrade pip
仮想環境の作成
仮想環境を作ることで、別の環境で構築する時に、Pythonのインストールされているライブラリーのバージョンを簡単に合わせることができるので、ライブラリーのバージョンの違いで問題になることはなくなります。
sam-lambda-dynamodb> python -m venv venv
sam-lambda-dynamodb> .\venv\Scripts\activate
(venv) sam-lambda-dynamodb>
仮想環境に入っていると、左側に(venv)が表示されます。
activateスクリプトを実行できない場合、管理者として以下のコマンドを実行します。
set-executionpolicy remotesigned
仮想環境の中のpipの更新
(venv) sam-lambda-dynamodb> python -m pip install --upgrade pip
VSCodeのWorkspaceの設定
仮想環境のための設定を入れます。
- VSCODEに「Python」というExtensionをインストールします。
- 「F1」を押し、
>Preferences: Open Workspace Settings
を書きます。 - 「Python: Python Path」の設定を探し、仮想環境のpython.exeのパスを入力します。
- 例:
C:\\Users\\path\\to\\sam-lambda-dynamodb\\venv\\Scripts\\python.exe
- 例:
- 「Python: Venv Path」の設定を探し、仮想環境のベースパスを入力します。
- 例:
C:\\Users\\path\\to\\sam-lambda-dynamodb\\venv
- 例:
- 設定終わると、ワークスペースフォルダーに
.vscode/settings.json
が自動的に作成されます。-
settings.json
の中身は以下のようになります。
-
{
"python.pythonPath": "C:\\Users\\path\\to\\sam-lambda-dynamodb\\venv\\Scripts\\python.exe",
"python.venvPath": "C:\\Users\\path\\to\\sam-lambda-dynamodb\\venv"
}
仮想環境に必要なライブラリーをインストール
(venv) sam-lambda-dynamodb> pip install aws-sam-cli
(venv) sam-lambda-dynamodb> sam --version
SAM CLI, version 0.11.0
(venv) sam-lambda-dynamodb> pip install awscli
(venv) sam-lambda-dynamodb> aws --version
aws-cli/1.16.101 Python/3.7.2 Windows/10 botocore/1.12.91
他の環境でも同じライブラリーのバージョンになるため、requirements.txt
を作成します。
(venv) sam-lambda-dynamodb> pip freeze | Out-File -Encoding UTF8 .\requirements.txt
requirements.txt
からインストールしたい時、このコマンドでできます。
「pip install -r requirements.txt
」
SAMのinit処理を実行
(venv) sam-lambda-dynamodb> sam init --runtime python3.7
こちらのコマンドを実行すると、sam-app
のフォルダーが作成されます。
hello_worldのデフォルトプロジェクトは設定されているので、試してみましょう。
awsの設定
ローカル用のテスト環境なので、内容はあまり重要ではないです。
(venv) sam-lambda-dynamodb> aws configure
AWS Access Key ID [None]: testid
AWS Secret Access Key [None]: testsecret
Default region name [None]: ap-northeast-1
Default output format [None]: json
hello_worldのテンプレートのテスト
-
sam-app
に入り、ビルドを実行
(venv) sam-lambda-dynamodb> cd .\sam-app\
(venv) sam-lambda-dynamodb\sam-app> sam build
- dockerは実行中か確認し、APIを実行
(venv) sam-lambda-dynamodb\sam-app> sam local start-api
- hello_worldのapiを実行
ブラウザーで「localhost:3000/hello」にアクセスします。
画面に{"message": "hello world"}
が表示されたら成功です。
ローカルのDynamoDBの設定
「Ctrl+C」でhello_worldのlambdaを止めます。
DynamoDBをプルします。
(venv) sam-lambda-dynamodb\sam-app> docker pull amazon/dynamodb-local
lambdaとdynamodbは同じネットワークにあると楽なので、dockerのネットワークを作成します。
(venv) sam-lambda-dynamodb\sam-app> docker network create lambda-local
containerを作成し、runします。
(venv) sam-lambda-dynamodb\sam-app> docker run --network lambda-local --name dynamodb -p 8000:8000 amazon/dynamodb-local -jar DynamoDBLocal.jar -sharedDb
runの後は「Ctrl+C」を押します。
PS: 上のコマンドを1回目の時にしか使わないです。次の実行の時「docker start dynamodb
」のコマンドを使います。
DynamoDBのテーブルを作成
- プロジェクトフォルダに「DynamoDB」のフォルダを作成し、AccessTable.jsonのファイルを作成します。
{
"TableName": "Access",
"KeySchema": [
{
"AttributeName": "Path",
"KeyType": "HASH"
},
{
"AttributeName": "Date",
"KeyType": "RANGE"
}
],
"AttributeDefinitions": [
{
"AttributeName": "Path",
"AttributeType": "S"
},
{
"AttributeName": "Date",
"AttributeType": "S"
}
],
"ProvisionedThroughput": {
"ReadCapacityUnits": 2,
"WriteCapacityUnits": 2
}
}
- プロジェクトのルートフォルダーに戻り、テーブルの作成コマンドを実行します。
(venv) sam-lambda-dynamodb\sam-app> cd ..
(venv) sam-lambda-dynamodb> aws dynamodb create-table --cli-input-json file://.\DynamoDB\AccessTable.json --endpoint-url http://localhost:8000
(venv) sam-lambda-dynamodb> aws dynamodb list-tables --endpoint-url http://localhost:8000
{
"TableNames": [
"Access"
]
}
これでテーブルの作成ができました。
「hello_world」のapiを編集
まず、ローカルと本番の接続処理は違うので、ローカルだとわかるようにtemplate.yaml
に環境のパラメーターを追加します。
実際にデプロイをする時パラメーターを上書きできます。
... 略
+Parameters:
+ Env:
+ Type: String
+ Default: local
Globals:
Function:
Timeout: 3
+ Environment:
+ Variables:
+ ENV: !Ref Env
... 略
「hello_world」のフォルダーの中にあるrequirements.txt
にboto3
のライブラリーを追加します。
requests
boto3
「hello_world」のフォルダーの中にあるapp.py
を編集します。
returnの前に以下のコードを追加します。
import json
import boto3
import os
import logging
from datetime import datetime
# ... 略
try:
logger = logging.getLogger()
logger.setLevel(logging.INFO)
session = boto3.session.Session()
awsRegion = session.region_name
paramList = event['queryStringParameters']
client = boto3.client('dynamodb')
# ローカルの場合
if os.environ['ENV'] == 'local':
dynamodb = boto3.resource('dynamodb', region_name = awsRegion, endpoint_url = "http://dynamodb:8000")
# ローカル以外の環境の場合
else:
dynamodb = boto3.resource('dynamodb', region_name = awsRegion)
# テーブルを取得
table = dynamodb.Table('Access')
# 日時の文字列
date = datetime.utcnow().isoformat()
# 登録するアイテムのベース
item = {'Path': event['path'], 'Date': date}
if paramList != None:
for key,value in paramList.items():
item[key] = value
table.put_item(
Item=item
)
except Exception as e:
# Lambdaログにエクセプションの情報を入れる
logger.exception(e)
return {
'statusCode': 500,
'body': json.dumps({
'error_message': str(e)
}),
}
# ... 略
APIを試す
もう一度「sam-app
」に入り、ビルドを実行します。
(venv) sam-lambda-dynamodb> cd .\sam-app\
(venv) sam-lambda-dynamodb\sam-app> sam build
APIをlambda-local
のネットワークで開始します。
(venv) sam-lambda-dynamodb\sam-app> sam local start-api --docker-network lambda-local
ブラウザーでGatewayにアクセスします。(http://localhost:3000/hello?param=test)
成功できたら、以下のコマンドでテーブルのアイテムが見れます。
(venv) sam-lambda-dynamodb> aws dynamodb scan --table-name Access --endpoint-url http://localhost:8000
{
"Items": [
{
"Path": {
"S": "/hello"
},
"param": {
"S": "test"
},
"Date": {
"S": "2019-02-11T03:48:44.017178"
}
}
],
"Count": 1,
"ScannedCount": 1,
"ConsumedCapacity": null
}
これでDynamoDBとLambdaをローカルで使えるようになりました。
その他の情報
- CloudFormationのテンプレートに使える定義をSAMのテンプレートにも使えます。
- git管理をする場合、仮想環境のフォルダーをgitignoreに入れます。
- SAMのテンプレートのドキュメンテーション:
- boto3のDynamoDBのドキュメンテーション:
- このプロジェクトのgit: