chaliceはAWSの公式ツール。api gatewayとlambdaを pythonのflaskライクな書き方で定義できる
設定ファイルよりもpythonを書くのが楽な人には使いやすそう
色々機能を試してみたのでトピックごとにメモしておく
環境
- python: 3.7
- chalice: 1.12.0
インストールコマンド
python3 -m pip install chalice
プロジェクト作成コマンド
.chalice
chalice new-project helloworld
lambda関数の作成
redshiftのクエリ結果をs3にuploadする処理を作る
リポジトリにも全体のスクリプトを上げている
デコレータを付ける。lambda関数名はnameで指定できる
@app.lambda_function(name='redshift_to_s3')
def main(event, context) -> None:
query = load_query()
res = exec_query(query)
dataframe_to_s3(res, filename=OutputFileName, output_s3_path=S3Path)
各種イベントをトリガーにすることもできる
cron実行(5分ごと)
@events.schedule('cron(*/5 * * * ? *)')
s3 uploadイベント
@app.on_s3_event(bucket='bucket_name')
sqsイベント
@app.on_sqs_message(queue='queue-name')
環境変数の設定
.chalice/config.json
↓のように
environment_variables
config.json
{
"version": "2.0",
"app_name": "redshift_to_s3",
"stages": {
"dev": {
"lambda_functions": {
"main": {
"lambda_timeout": 600,
"subnet_ids": ["subnet-xxxx"],
"security_group_ids": ["sg-xxxx", "sg-xxxx"]
}
},
"manage_iam_role": false,
"iam_role_arn": "arn:aws:iam::xxxx:role/lambda-role",
"environment_variables": {
"CLUSTER_ENDPOINT": "xxxx.xxxx.ap-northeast-1.redshift.amazonaws.com",
"CLUSTER_IDENTIFIER": "xxxx",
"DB_PORT": "5439",
"DB_NAME": "db",
"DB_USER": "redshift_user",
"QUERY_PATH": "sql/test.sql",
"S3_BUCKET": "bucket",
"S3_PATH": "unload/path",
"OUTPUT_FILENAME": "test"
}
}
}
}
stagesごとに記述でき、デプロイする時に変えることができる
chalice deploy --stage dev
外部ファイルの追加
./chalicelib
モジュールならば
from chalicelib.module import func
ファイルならば
import os
filepath = os.path.join(
os.path.dirname(__file__), 'chalicelib', filename)
などとすれば取得できる
デプロイ&削除
各種リソースの作成と削除をしてくれる
chalice deploy
Creating deployment package.
Creating lambda function: dev-hello-name
chalice delete
Deleting function: arn:aws:lambda:ap-northeast-1:xxxx:function:dev-hello-name
おまけ
policyの自動生成
chaliceは、boto3で定義、実行したメソッドを読んで、iam policyを自動生成してくれる
生成するiam policyを↓cliで確認することもできる
chalice gen-policy --filename ./chalicelib/sagemaker.py
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sagemaker:CreateEndpoint",
"sagemaker:CreateEndpointConfig",
"sagemaker:DeleteEndpoint",
"sagemaker:UpdateEndpoint"
],
"Resource": [
"*"
],
"Sid": "xxxxxxx"
}
]
}
指定したスクリプト。sagemakerにモデルをデプロイしたりするスクリプト
sagemaker.py
import os
import boto3
import json
import time
from chalice import Blueprint, BadRequestError
endpoint = Blueprint(__name__)
client = boto3.client('sagemaker')
@endpoint.route('/config/{name}', methods=['POST'])
def create_endpoint_config(name):
body = endpoint.current_request.json_body
if 'ModelName' not in body:
raise BadRequestError('Missing model name in request body')
model_name = body['ModelName']
instance_type = 'ml.t2.medium'
instance_count = 1
if 'InstanceType' in body:
instance_type = body['InstanceType']
if 'InstanceCount' in body:
instance_count = body['InstanceCount']
response = client.create_endpoint_config(
EndpointConfigName=name,
ProductionVariants=[{
'InstanceType': instance_type,
'InitialInstanceCount': instance_count,
'InitialVariantWeight': 1,
'ModelName': model_name,
'VariantName': 'AllTraffic'}]
)
print("create endpoint Config Arn: " + response['EndpointConfigArn'])
return {'response': {'arn': response['EndpointConfigArn']}}
# deploy & hosting
@endpoint.route('/{name}', methods=['POST'])
def create_endpoint(name):
body = endpoint.current_request.json_body
if 'EndpointConfigName' not in body:
raise BadRequestError('Missing endpoint config name in request body')
response = client.create_endpoint(
EndpointName=name,
EndpointConfigName=body['EndpointConfigName']
)
print('create endpoint arn:', response['EndpointArn'])
return {'response': {'arn': response['EndpointArn']}}
@endpoint.route('/{name}', methods=['PUT'])
def update_endpoint(name):
body = endpoint.current_request.json_body
if 'EndpointConfigName' not in body:
raise BadRequestError('Missing endpoint config name in request body')
response = client.update_endpoint(
EndpointName=name,
EndpointConfigName=body['EndpointConfigName']
)
print(response)
return {'response': response}
@endpoint.route('/{name}', methods=['DELETE'])
def delete_endpoint(name):
response = client.delete_endpoint(
EndpointName=name
)
return {'response': response}
SAM用package生成
AWS SAMというサーバレス用のフレームワーク用のファイル群が生成させる AWS サーバーレスアプリケーションモデル (AWS SAM) の使用 - AWS Lambda
chalice package output
ls ./output/
deployment.zip sam.json
ソースファイル群(deployment.zip)と作成されるリソースの設定ファイル(sam.json)が生成される