Serverless Framework on AWS入門
プロジェクトの作成
まずは、serverlessコマンド(slsコマンド)のインストール。$ npm install -g serverless
$ serverless -v
Framework Core: 2.70.0
Plugin: 5.5.2
SDK: 4.3.0
Components: 3.18.1
$ sls -v
Framework Core: 2.70.0
Plugin: 5.5.2
SDK: 4.3.0
Components: 3.18.1
IAMユーザーの作成
serverlessコマンドでAWSに操作を行うためのIAMユーザーを作成。IAMに与える権限は公式ガイドによさそうなサンプルがあったのでこれを拝借してポリシーを作成。
作成したIAMをserverlessコマンドに設定します。
要はAWS CLIでプロファイルを設定するのと同じことです。
# デフォルトプロファイルに設定
$ serverless config credentials --provider aws --key 1234 --secret 5678
# 名前を付けてプロファイル設定
$ serverless config credentials --provider aws --key 1234 --secret 5678 --profile serverless --overwrite
# 作成したプロファイルはAWS CLIと共用
$ aws s3 ls --profile serverless
サービスの作成
デプロイの単位であるサービスを作成します。今回はPython3のテンプレートを使って作成します。
$ serverless create --template aws-python3 --name MyServerlessService --path MyServerlessService
$ cd MyServerlessService/
$ ls -a
. .. .npmignore handler.py serverless.yml
「.npmignore」はNPMパッケージを公開するときに使うものなので割愛。
import json
def hello(event, context):
body = {
"message": "Go Serverless v1.0! Your function executed successfully!",
"input": event
}
response = {
"statusCode": 200,
"body": json.dumps(body)
}
return response
# Use this code if you don't use the http event with the LAMBDA-PROXY
# integration
"""
return {
"message": "Go Serverless v1.0! Your function executed successfully!",
"event": event
}
"""
# Welcome to Serverless!
#
# This file is the main config file for your service.
# It's very minimal at this point and uses default values.
# You can always add more config options for more control.
# We've included some commented out config examples here.
# Just uncomment any of them to get that config option.
#
# For full config options, check the docs:
# docs.serverless.com
#
# Happy Coding!
service: MyServerlessService
# app and org for use with dashboard.serverless.com
#app: your-app-name
#org: your-org-name
# You can pin your service to only deploy with a specific Serverless version
# Check out our docs for more details
frameworkVersion: '2'
provider:
name: aws
runtime: python3.8
lambdaHashingVersion: 20201221
# you can overwrite defaults here
# stage: dev
# region: us-east-1
# you can add statements to the Lambda function's IAM Role here
# iam:
# role:
# statements:
# - Effect: "Allow"
# Action:
# - "s3:ListBucket"
# Resource: { "Fn::Join" : ["", ["arn:aws:s3:::", { "Ref" : "ServerlessDeploymentBucket" } ] ] }
# - Effect: "Allow"
# Action:
# - "s3:PutObject"
# Resource:
# Fn::Join:
# - ""
# - - "arn:aws:s3:::"
# - "Ref" : "ServerlessDeploymentBucket"
# - "/*"
# you can define service wide environment variables here
# environment:
# variable1: value1
# you can add packaging information here
#package:
# patterns:
# - '!exclude-me.py'
# - '!exclude-me-dir/**'
# - include-me.py
# - include-me-dir/**
functions:
hello:
handler: handler.hello
# The following are a few example events you can configure
# NOTE: Please make sure to change your handler code to work with those events
# Check the event documentation for details
# events:
# - httpApi:
# path: /users/create
# method: get
# - websocket: $connect
# - s3: ${env:BUCKET}
# - schedule: rate(10 minutes)
# - sns: greeter-topic
# - stream: arn:aws:dynamodb:region:XXXXXX:table/foo/stream/1970-01-01T00:00:00.000
# - alexaSkill: amzn1.ask.skill.xx-xx-xx-xx
# - alexaSmartHome: amzn1.ask.skill.xx-xx-xx-xx
# - iot:
# sql: "SELECT * FROM 'some_topic'"
# - cloudwatchEvent:
# event:
# source:
# - "aws.ec2"
# detail-type:
# - "EC2 Instance State-change Notification"
# detail:
# state:
# - pending
# - cloudwatchLog: '/aws/lambda/hello'
# - cognitoUserPool:
# pool: MyUserPool
# trigger: PreSignUp
# - alb:
# listenerArn: arn:aws:elasticloadbalancing:us-east-1:XXXXXX:listener/app/my-load-balancer/50dc6c495c0c9188/
# priority: 1
# conditions:
# host: example.com
# path: /hello
# Define function environment variables here
# environment:
# variable2: value2
# you can add CloudFormation resource templates here
#resources:
# Resources:
# NewResource:
# Type: AWS::S3::Bucket
# Properties:
# BucketName: my-new-bucket
# Outputs:
# NewOutput:
# Description: "Description for the output"
# Value: "Some output value"
サービスのデプロイ
設定を紐解きつつ「serverless.yml」を修正してみる。# サービス名
service: MyServerlessService
# Serverlessフレームワークのバージョン
frameworkVersion: '2'
# サービスのプロバイダ
provider:
name: aws
runtime: python3.8
lambdaHashingVersion: 20201221
stage: api # API Gatewayのステージ名
region: ap-northeast-1 # デプロイリージョン
# Lambdaが使用するIAMロール
iamRoleStatements:
- Effect: "Allow"
Action:
- "s3:ListBucket"
Resource: { "Fn::Join" : ["", ["arn:aws:s3:::", { "Ref" : "ServerlessDeploymentBucket" } ] ] }
- Effect: "Allow"
Action:
- "logs:CreateLogGroup"
- "logs:CreateLogStream"
- "logs:PutLogEvents"
Resource: "*"
# Lambdaの設定
functions:
hello:
handler: handler.hello
timeout: 29
events:
# API Gateway(REST)の紐づけ
- http:
path: /hello
method: get
integration: lambda_proxy # Lambdaプロキシ統合の利用
# Lambda環境変数
environment:
TZ: Asia/Tokyo
デプロイの実行
defaultプロファイルで実行しないよう、プロファイルを指定して実行。# --verboseオプションで詳細なデプロイの経過が見れる
$ serverless deploy --verbose --aws-profile serverless
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Ensuring that deployment bucket exists
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service MyServerlessService.zip file to S3 (641 B)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
~~~中略~~~
CloudFormation - UPDATE_COMPLETE_CLEANUP_IN_PROGRESS - AWS::CloudFormation::Stack - MyServerlessService-api
CloudFormation - UPDATE_COMPLETE - AWS::CloudFormation::Stack - MyServerlessService-api
Serverless: Stack update finished...
Service Information
service: MyServerlessService
stage: api
region: ap-northeast-1
stack: MyServerlessService-api
resources: 11
api keys:
None
endpoints:
GET - https://XXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/api/hello
functions:
hello: MyServerlessService-api-hello
layers:
None
# 得られたエンドポイントにアクセス
$ curl https://XXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/api/hello
{"message": "Go Serverless v1.0! Your function executed successfully!", "input": {"resource": "/hello", "path": "/hello"~~~
更新するときも同じコマンドを再実行すればOK。
サービスの削除
$ serverless remove --verbose --aws-profile serverless
Serverless: Getting all objects in S3 bucket...
Serverless: Removing objects in S3 bucket...
Serverless: Removing Stack...
Serverless: Checking Stack delete progress...
CloudFormation - DELETE_IN_PROGRESS - AWS::CloudFormation::Stack - MyServerlessService-api
~~中略~~~
CloudFormation - DELETE_IN_PROGRESS - AWS::Logs::LogGroup - HelloLogGroup
Serverless: Stack delete finished...
Serverless: Stack delete finished...
内部的にはCloudFormationスタックを削除しているだけなのでServerlessコマンド外で作ったものに関しては関与できなさそうです。
取り急ぎ基本的なことは理解できたので、ここからさらに複雑なものを作っていくにはどうすればいいかってところを学んでいきたいと思います。
ディスカッション
コメント一覧
まだ、コメントがありません