Serverless FrameworkとAWS Serverless Application Modelのコマンドをまとめてみた
2018年5月12日追記 AWS SAMにも専用のCLIツールが発表されたようです。最新の情報は各種ドキュメントを参照してください。
はじめに
こんにちは、中山です。
サーバーレス環境を構築する際に何らかのフレームワークを利用されている方は多くいると思います。Serverless FrameworkやApexなどさまざまなフレームワークが存在しており、私も日々これらのツールを利用しています。それぞれ特色がありますが、共通する点として基本的にコミュニティベースで開発されているという側面があります。これだけサーバーレスという技術トレンドの盛り上がりがあるにも関わらず、AWS公式のフレームワークが中々発表されなかったのですが、AWS re:Invent 2016が開催される少し前、ついにAWSから待望のAWS Serverless Application Model(以下AWS SAM)というフレームワーク(正確に言うとサーバーレス環境をAWSで構築する際のモデル)が発表されました。弊社でもすぐにエントリを発表しています。
私もAWS SAMを利用/検証しています。使い勝手としてはServerless Frameworkとかなり近いなという印象です。そのため、Serverless Frameworを利用した経験のある方なら比較的容易に導入できると思います。という訳で、今回は自分の備忘録用途として Serverless FrameworkのあのコマンドはAWS SAMではどのコマンドに対応するのか という点を調べたのでエントリにまとめたいと思います。
概要
Serverless Frameworkには専用のコマンドが用意されています。 serverless
またはそのシンボリックリンクである sls
/ slss
コマンドです(本エントリでは sls
で統一します)。対してAWS SAMの方はどうでしょうか。執筆時点(2016/12/17)ではAWS SAM専用のコマンドは用意されておらず、AWS CLIを利用することが想定されています(強いて言うならAWS SAMと同時に発表された aws cloudfromation package
及び aws cloudformation deploy
ぐらい)。フレームワークではなくあくまで モデル という位置づけのためか、この点は他のフレームワークと大きく異なる点です。そのため、本エントリでは sls
コマンドとAWS CLIの比較という形でまとめます。
Serverless Frameworkのバージョンは現時点の最新バージョンである1.4.0ベースであることにご注意ください。このツールは開発速度が早く、新しいコマンドが導入されたり既存のコマンド結果が変更される可能性が高いです。その点ご了承ください。また、AWS CLIのバージョンは1.11.30を想定しています。
Serverless Frameworkで用意されている各種コマンド及びその概要は sls
コマンド単体で実行することにより確認可能です。
config credentials ............ Configures a new provider profile for the Serverless Framework create ........................ Create new Serverless service install ....................... Install a Serverless service from GitHub deploy ........................ Deploy a Serverless service deploy function ............... Deploy a single function from the service deploy list ................... List deployed version of your Serverless Service invoke ........................ Invoke a deployed function invoke local .................. Invoke function locally info .......................... Display information about the service logs .......................... Output the logs of a deployed function metrics ....................... Show metrics for a specific function remove ........................ Remove Serverless service and all resources rollback ...................... Rollback the Serverless service to a specific deployment slstats ....................... Enable or disable stats
説明が長くなりました。それでは、早速比較していきます。
config credentials
Serverless Frameworkで利用する各種プロバイダ用クレデンシャルを生成するコマンドです。現在時点ではAWSのみに対応しています。実行結果は以下の通りです。
$ sls config credentials \ --provider aws \ --key ******************** \ --secret **************************************** \ --profile test-profile1 Serverless: Setting up AWS... Serverless: Saving your AWS profile in "~/.aws/credentials"... Serverless: Success! Your AWS access keys were stored under the "test-profile1" profile. $ cat ~/.aws/credentials [test-profile1] aws_access_key_id=******************** aws_secret_access_key=****************************************
AWS CLIの場合はみなさん一度は実行したことがある aws configure
ですね。
$ aws configure \ --profile test-profile2 AWS Access Key ID [None]: ******************** AWS Secret Access Key [None]: **************************************** Default region name [None]: ap-northeast-1 Default output format [None]: json $ cat ~/.aws/credentials aws_access_key_id = ******************** aws_secret_access_key = ****************************************
create
このコマンドは各種テンプレートからサービス及びプラグインの雛形を生成します。実行結果は以下の通りです。
$ sls create \ --template aws-python \ --name test-service \ --path test-path1 Serverless: Generating boilerplate... Serverless: Generating boilerplate in "/Users/knakayama/tmp/20161217/create/test-path1" _______ __ | _ .-----.----.--.--.-----.----| .-----.-----.-----. | |___| -__| _| | | -__| _| | -__|__ --|__ --| |____ |_____|__| \___/|_____|__| |__|_____|_____|_____| | | | The Serverless Application Framework | | serverless.com, v1.4.0 -------' Serverless: Successfully generated boilerplate for template: "aws-python" $ tree test-path1 test-path1 ├── handler.py └── serverless.yml 0 directories, 2 files
先程はサービスの生成でしたが、プラグインの場合も同じように雛形となるコードを生成してくれます。
$ sls create \ --template plugin \ --path test-path2 Serverless: Generating boilerplate... Serverless: Generating boilerplate in "/Users/knakayama/tmp/20161217/create/test-path2" _______ __ | _ .-----.----.--.--.-----.----| .-----.-----.-----. | |___| -__| _| | | -__| _| | -__|__ --|__ --| |____ |_____|__| \___/|_____|__| |__|_____|_____|_____| | | | The Serverless Application Framework | | serverless.com, v1.4.0 -------' Serverless: Successfully generated boilerplate for template: "plugin" $ tree test-path2 test-path2 └── index.js 0 directories, 1 file
AWS CLIではAWS SAMの雛形を生成する機能は無いです。幸い、AWS SAMのGitHubリポジトリに多くのサンプル用CloudFormationテンプレートとLambda関数をまとめてくれています。もし雛形が必要であればこれをコピペすればOKです。AWS SAMには現状プラグインという概念がないのでその雛形を生成する機能もありません。
install
このコマンドはGitHubからサービスをカレントディレクトリにダウンロードすることができます。実行結果は以下の通りです。
$ sls install \ --url https://github.com/pmuens/serverless-crud Serverless: Downloading and installing "serverless-crud"... Serverless: Successfully installed service "serverless-crud". $ tree serverless-crud serverless-crud ├── README.md ├── handler.js ├── package.json ├── serverless.yml ├── todos-create.js ├── todos-delete.js ├── todos-read-all.js ├── todos-read-one.js └── todos-update.js 0 directories, 9 files
こちらもAWS CLI単体では提供されていない機能です。AWS SAMの各種コードをGitHubからダウンロードしたいのであれば単純に git clone
で持ってくればいいでしょう。 .git
が不要であれば消せばいいだけです。
deploy
Serverless Frameworkのサービスをデプロイするコマンドです。このフレームワークにより生成されたCloudFormationテンプレートはカレントディレクトリの .serverless
ディレクトリ以下に作成されます。実行結果は以下の通りです。
# CloudFormationテンプレートのみ生成 $ sls deploy \ --noDeploy \ --stage dev \ --region ap-northeast-1 \ --verbose Serverless: Packaging service... Serverless: Did not deploy due to --noDeploy $ tree .serverless .serverless ├── cloudformation-template-create-stack.json ├── cloudformation-template-update-stack.json └── test-service.zip 0 directories, 3 files # 実際にデプロイ $ sls deploy \ --stage dev \ --region ap-northeast-1 \ --verbose Serverless: Creating Stack... Serverless: Checking Stack create progress... CloudFormation - CREATE_IN_PROGRESS - AWS::CloudFormation::Stack - test-service-dev CloudFormation - CREATE_IN_PROGRESS - AWS::S3::Bucket - ServerlessDeploymentBucket CloudFormation - CREATE_IN_PROGRESS - AWS::S3::Bucket - ServerlessDeploymentBucket CloudFormation - CREATE_COMPLETE - AWS::S3::Bucket - ServerlessDeploymentBucket CloudFormation - CREATE_COMPLETE - AWS::CloudFormation::Stack - test-service-dev Serverless: Stack create finished... Serverless: Packaging service... Serverless: Uploading CloudFormation file to S3... Serverless: Uploading service .zip file to S3 (639 B)... Serverless: Updating Stack... Serverless: Checking Stack update progress... CloudFormation - UPDATE_IN_PROGRESS - AWS::CloudFormation::Stack - test-service-dev CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Role - IamRoleLambdaExecution CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Role - IamRoleLambdaExecution CloudFormation - CREATE_COMPLETE - AWS::IAM::Role - IamRoleLambdaExecution CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Policy - IamPolicyLambdaExecution CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Policy - IamPolicyLambdaExecution CloudFormation - CREATE_COMPLETE - AWS::IAM::Policy - IamPolicyLambdaExecution CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Function - HelloLambdaFunction CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Function - HelloLambdaFunction CloudFormation - CREATE_COMPLETE - AWS::Lambda::Function - HelloLambdaFunction CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Version - HelloLambdaVersion6o6Rkvlbaf5HCYTq0tDyUlMHgyTHvO8ZK6RXnh3k1Y CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Version - HelloLambdaVersion6o6Rkvlbaf5HCYTq0tDyUlMHgyTHvO8ZK6RXnh3k1Y CloudFormation - CREATE_COMPLETE - AWS::Lambda::Version - HelloLambdaVersion6o6Rkvlbaf5HCYTq0tDyUlMHgyTHvO8ZK6RXnh3k1Y CloudFormation - UPDATE_COMPLETE_CLEANUP_IN_PROGRESS - AWS::CloudFormation::Stack - test-service-dev CloudFormation - UPDATE_COMPLETE - AWS::CloudFormation::Stack - test-service-dev Serverless: Stack update finished... Service Information service: test-service stage: dev region: ap-northeast-1 api keys: None endpoints: None functions: test-service-dev-hello: arn:aws:lambda:ap-northeast-1:************:function:test-service-dev-hello Stack Outputs HelloLambdaFunctionArn: arn:aws:lambda:ap-northeast-1:************:function:test-service-dev-hello HelloLambdaFunctionQualifiedArn: arn:aws:lambda:ap-northeast-1:************:function:test-service-dev-hello:1 ServerlessDeploymentBucketName: test-service-dev-serverlessdeploymentbucket-29pknictzyf7
テンプレートとアーティファクトの生成及びそのデプロイはAWS SAMのお家芸ですね。 aws cloudformation package
でS3にLambda関数を設置してAWS SAM用CloudFormationを生成(S3上のLambda関数へのパスを追記)、 aws cloudformation deploy
でデプロイという流れです。それぞれ見ていきましょう。
# AWS SAM用CloudFormationの生成 $ aws cloudformation package \ --template-file sam.yml \ --s3-bucket ********************** \ --output-template-file packaged-sam.yml \ --region ap-northeast-1 Uploading to 14f3eb35c3eeeee74943d3e3aea1efb0 4448 / 4448.0 (100.00%) Successfully packaged artifacts and wrote output template to file packaged-sam.yml. Execute the following command to deploy the packaged template aws cloudformation deploy --template-file /Users/knakayama/tmp/20161217/deploy/packaged-sam.yml --stack-name <YOUR STACK NAME> # デプロイ $ aws cloudformation deploy \ --template-file packaged-sam.yml \ --stack-name test-sam \ --capabilities CAPABILITY_IAM \ --region ap-northeast-1 Waiting for changeset to be created.. Waiting for stack create/update to complete Successfully created/updated stack - test-sam
Serverless Frameworkと異なるAWS SAMの特色として以下の点があります。
--kms-key-id
- S3にアップロードするアーティファクトをKMSにより暗号化可能
--parameter-override
- CloudFormationのパラメータをコマンドラインから変更可能
--no-execute-change-set
- スタックのアップデート前にChangeSetを確認できる
- Serverless Frameworkは現状ChangeSetに対応してないのでAWS SAMの利点の一つ
それぞれ以下のように使います。
- KMSによる暗号化
$ aws cloudformation package \ --template-file sam.yml \ --s3-bucket ********************** \ --output-template-file packaged-sam.yml \ --kms-key-id ************************************ \ --region ap-northeast-1 Uploading to 2e7e34d6b2265f4558363875d1200d36 490 / 490.0 (100.00%) Successfully packaged artifacts and wrote output template to file packaged-sam.yml. Execute the following command to deploy the packaged template aws cloudformation deploy --template-file /Users/knakayama/tmp/20161217/deploy/packaged-sam.yml --stack-name <YOUR STACK NAME> $ aws s3api head-object \ --bucket ********************** \ --key 2e7e34d6b2265f4558363875d1200d36 { "AcceptRanges": "bytes", "ContentType": "binary/octet-stream", "LastModified": "Sat, 17 Dec 2016 02:35:25 GMT", "ContentLength": 490, "ETag": "\"53d20f8816e72392468face701662416\"", "ServerSideEncryption": "aws:kms", "SSEKMSKeyId": "arn:aws:kms:ap-northeast-1:************:key/************************************", "Metadata": {} }
- パラメータのオーバーライド
$ cat packaged-sam.yml AWSTemplateFormatVersion: 2010-09-09 Description: AWS SAM Test Parameters: Timeout: Default: 3 Description: Timeout Type: Number Resources: TestFunction: Properties: CodeUri: s3://**********************/015926a9a59bf83ceb0d87aec7c4afbc Handler: handler.hello Runtime: python2.7 Timeout: Ref: Timeout Type: AWS::Serverless::Function Transform: AWS::Serverless-2016-10-31 $ aws cloudformation deploy \ --template-file packaged-sam.yml \ --stack-name test-sam \ --capabilities CAPABILITY_IAM \ --region ap-northeast-1 \ --parameter-overrides Timeout=6 Waiting for changeset to be created.. Waiting for stack create/update to complete Successfully created/updated stack - test-sam $ aws lambda get-function-configuration \ --function-name test-sam-TestFunction-1EXTP41SKWHO9 \ --query 'Timeout' 6
- ChangeSetの取得
$ aws cloudformation deploy \ --template-file packaged-sam.yml \ --stack-name test-sam \ --capabilities CAPABILITY_IAM \ --region ap-northeast-1 \ --parameter-overrides Timeout=5 \ --no-execute-changeset Waiting for changeset to be created.. Changeset created successfully. Run the following command to review changes: aws cloudformation describe-change-set --change-set-name arn:aws:cloudformation:ap-northeast-1:************:changeSet/awscli-cloudformation-package-deploy-1481944875/54effcac-125c-4987-b56d-877b5d960b55 $ aws cloudformation describe-change-set \ --change-set-name arn:aws:cloudformation:ap-northeast-1:************:changeSet/awscli-cloudformation-package-deploy-1481944875/54effcac-125c-4987-b56d-877b5d960b55 { "StackId": "arn:aws:cloudformation:ap-northeast-1:************:stack/test-sam/235ef660-c407-11e6-bc1f-50a686699882", "Status": "CREATE_COMPLETE", "ChangeSetName": "awscli-cloudformation-package-deploy-1481944875", "Description": "Created by AWS CLI at 2016-12-17T03:21:15.992064 UTC", "Parameters": [ { "ParameterValue": "5", "ParameterKey": "Timeout" } ], "Changes": [ { "ResourceChange": { "ResourceType": "AWS::Lambda::Function", "PhysicalResourceId": "test-sam-TestFunction-1EXTP41SKWHO9", "Details": [ { "CausingEntity": "Timeout", "ChangeSource": "ParameterReference", "Evaluation": "Static", "Target": { "Attribute": "Properties", "Name": "Timeout", "RequiresRecreation": "Never" } }, { "ChangeSource": "DirectModification", "Evaluation": "Dynamic", "Target": { "Attribute": "Properties", "Name": "Timeout", "RequiresRecreation": "Never" } } ], "Action": "Modify", "Scope": [ "Properties" ], "LogicalResourceId": "TestFunction", "Replacement": "False" }, "Type": "Resource" } ], "CreationTime": "2016-12-17T03:21:17.075Z", "Capabilities": [ "CAPABILITY_IAM" ], "StackName": "test-sam", "NotificationARNs": [], "ExecutionStatus": "AVAILABLE", "ChangeSetId": "arn:aws:cloudformation:ap-northeast-1:************:changeSet/awscli-cloudformation-package-deploy-1481944875/54effcac-125c-4987-b56d-877b5d960b55" }
deploy function
サービスに関連付けられているLambda関数の中から特定のLambda関数をデプロイするコマンドです。一見 sls deploy
と似た動作をしそうですが、ドキュメントによると異なる動作をするようです。以下に引用します。
The sls deploy function command deploys an individual function without AWS CloudFormation. This command simply swaps out the zip file that your CloudFormation stack is pointing toward. This is a much faster way of deploying changes in code.
CloudFormationが参照するZipを変更するという処理になるので sls deploy
より高速に動作するようですね。実行結果は以下の通りです。
# 現在のLambda関数のSHA256を確認 $ aws lambda get-function-configuration \ --function-name test-service-dev-hello \ --query 'CodeSha256' "yjdQs4sCLKZcCpJ/1f37+6R90gQviLOpDe9hbVtFPdw=" # 特定Lambda関数のみデプロイ $ sls deploy function \ --function hello \ --stage dev \ --region ap-northeast-1 \ --verbose Serverless: Deploying function: hello... Serverless: Packaging function: hello... Serverless: Uploading function: hello (2.47 KB)... Serverless: Successfully deployed function: hello # Lambda関数のSHA256が変更されていることを確認 $ aws lambda get-function-configuration \ --function-name test-service-dev-hello \ --query 'CodeSha256' "+hkvpr4P+dNG2pmSx5+xA69vIeoQbmMhSM3w4MMNV4k="
AWS SAMでは aws lambda update-function-code
を利用することによりLambda関数の参照するコードを差し替えることが可能です。
# 現在のLambda関数のSHA256を確認 $ aws lambda get-function-configuration \ --function-name test-sam-TestFunction-OINPPMS3LCOA \ --query 'CodeSha256' "i3PhQqa9VaKs6ilDgUGrdr0k3upZp5D+0siGE/I6OLk=" # Lambda関数のコードを差し替える $ aws lambda update-function-code \ --function-name test-sam-TestFunction-OINPPMS3LCOA \ --s3-bucket ********************** \ --s3-key cde3868bbec9ab495a18c09299d66865 { "CodeSha256": "6RR+7MnkwfjwD5it8cv1wG/hhKA0bvIFho0Fb9UMpd8=", "FunctionName": "test-sam-TestFunction-OINPPMS3LCOA", "CodeSize": 1041, "MemorySize": 128, "FunctionArn": "arn:aws:lambda:ap-northeast-1:************:function:test-sam-TestFunction-OINPPMS3LCOA", "Version": "$LATEST", "Role": "arn:aws:iam::************:role/test-sam-TestFunctionRole-1T5ZT9L4RQWBG", "Timeout": 3, "LastModified": "2016-12-17T11:21:57.081+0000", "Handler": "handler.hello", "Runtime": "python2.7", "Description": "" }
deploy list
デプロイ済みアーティファクトとその情報を表示するコマンドです。実行結果は以下の通りです。
$ sls deploy list \ --stage dev \ --region ap-northeast-1 \ --verbose Serverless: Listing deployments: Serverless: ------------- Serverless: Timestamp: 1481937983844 Serverless: Datetime: 2016-12-17T01:26:23.844Z Serverless: Files: Serverless: - compiled-cloudformation-template.json Serverless: - test-service.zip
出力は多少異なりますが、AWS SAMの場合はS3バケットをそのまま参照すればほぼ同等の情報は表示できます。
$ aws s3 ls s3://********************** 2016-12-17 12:12:19 996 015926a9a59bf83ceb0d87aec7c4afbc 2016-12-17 12:10:38 1045 0bbe9db183a711f0eedd7083229dd677 2016-12-17 12:07:36 490 2e7e34d6b2265f4558363875d1200d36 2016-12-17 19:27:00 994 317c4060ca5af0f09a4b7dc3bb680162 2016-12-17 19:57:05 1105 4c23686ee9a6bfb95c03c9eb7190d868 2016-12-17 19:56:16 1026 710ed11f0ffbf2c47a14af5d4887b3f3 2016-12-17 19:59:58 1110 c233d40079702ff5ff8d9015284c5a5c 2016-12-17 19:48:03 950 c30589961aed945eff97109809912f92 2016-12-17 12:09:51 1041 cde3868bbec9ab495a18c09299d66865 2016-12-17 20:17:53 1030 f4d11a1161bf72a0e59aff9c93497788
invoke
デプロイ済みのLambda関数を実行するコマンドです。 -t
または --type
でLambda関数の実行方法を指定可能です。デフォルトは RequestResponse
で、その他 Event
または DryRun
を指定できます。実行結果は以下の通りです。
$ sls invoke \ --function hello \ --stage dev \ --region ap-northeast-1 \ --data '{"Message": "Test Message"}' \ --log { "body": "{\"input\": {\"Message\": \"Test Message\"}, \"message\": \"Go Serverless v1.0! Your function executed successfully!\"}", "statusCode": 200 } -------------------------------------------------------------------- START RequestId: a4a4673a-c40f-11e6-97f0-473036194eb9 Version: $LATEST END RequestId: a4a4673a-c40f-11e6-97f0-473036194eb9 REPORT RequestId: a4a4673a-c40f-11e6-97f0-473036194eb9 Duration: 0.25 ms Billed Duration: 100 ms Memory Size: 1024 MB Max Memory Used: 16 MB
AWS SAMの場合は aws lambda invoke
でほぼ同等のことが可能です。ただし注意点が2つあります。一つはLambda関数の実行ログがbase64エンコードで出力されるという点、二つ目はLambda関数の実行結果がファイルに出力することを想定されている、つまりデフォルトで標準出力に表示する訳ではないという点です。
$ aws lambda invoke \ --function-name test-service-dev-hello \ --log-type Tail \ --payload '{"Message": "Test Message"}' \ --region ap-northeast-1 \ outfile { "LogResult": "U1RBUlQgUmVxdWVzdElkOiBkYjIxMjgxYy1jNDExLTExZTYtYjA2My00MWNiYTUwZTM5ZDMgVmVyc2lvbjogJExBVEVTVApFTkQgUmVxdWVzdElkOiBkYjIxMjgxYy1jNDExLTExZTYtYjA2My00MWNiYTUwZTM5ZDMKUkVQT1JUIFJlcXVlc3RJZDogZGIyMTI4MWMtYzQxMS0xMWU2LWIwNjMtNDFjYmE1MGUzOWQzCUR1cmF0aW9uOiAwLjM4IG1zCUJpbGxlZCBEdXJhdGlvbjogMTAwIG1zIAlNZW1vcnkgU2l6ZTogMTAyNCBNQglNYXggTWVtb3J5IFVzZWQ6IDE2IE1CCQo=", "StatusCode": 200 } $ cat outfile {"body": "{\"input\": {\"Message\": \"Test Message\"}, \"message\": \"Go Serverless v1.0! Your function executed successfully!\"}", "statusCode": 200}%
いちいちファイルを指定するのも面倒ですし、ログがbase64エンコードされているのは見づらいです。そういった場合は以下のように修正すればOKです。
$ aws lambda invoke \ --function-name test-service-dev-hello \ --log-type Tail \ --payload '{"Message": "Test Message"}' \ --region ap-northeast-1 \ --query 'LogResult' \ /dev/stdin \ | perl -MMIME::Base64 -ne 'print decode_base64($_)' {"body": "{\"input\": {\"Message\": \"Test Message\"}, \"message\": \"Go Serverless v1.0! Your function executed successfully!\"}", "statusCode": 200}START RequestId: ef886eb5-c412-11e6-a344-c51c45ded01c Version: $LATEST END RequestId: ef886eb5-c412-11e6-a344-c51c45ded01c REPORT RequestId: ef886eb5-c412-11e6-a344-c51c45ded01c Duration: 0.33 ms Billed Duration: 100 ms Memory Size: 1024 MB Max Memory Used: 16 MB
invoke local
Lambda関数をローカル環境でエミュレーションして実行できるコマンドです。現状Node.jsのみ対応しています。ドキュメントを引用します。
This runs your code locally by emulating the AWS Lambda environment. Please keep in mind, it's not a 100% perfect emulation, there may be some differences, but it works for the vast majority of users. We mock the context with simple mock data.
完全に同じ環境という訳ではないようですが、ローカルでLambda関数を実行できるのはかなり便利な機能だと思います。実行結果は以下の通りです。
$ sls invoke local \ --function hello \ --stage dev \ --region ap-northeast-1 \ --data '{"Message": "Test Invoke on local"}' \ --log { awsRequestId: 'id', invokeid: 'id', logGroupName: '/aws/lambda/test-service-dev-hello', logStreamName: '2015/09/22/[HEAD]13370a84ca4ed8b77c427af260', functionVersion: 'HEAD', isDefaultFunctionVersion: true, functionName: 'test-service-dev-hello', memoryLimitInMB: '1024', succeed: [Function: succeed], fail: [Function: fail], done: [Function: done], getRemainingTimeInMillis: [Function: getRemainingTimeInMillis] } { "statusCode": 200, "body": "{\"message\":\"Go Serverless v1.0! Your function executed successfully!\",\"input\":{\"Message\":\"Test Invoke on local\"}}" }
AWS SAM単体ではこういった機能は提供されていません。ashiina/lambda-localなどの外部ツールを利用すれば同等のことは可能です。
info
サービスでデプロイされたLambda関数を表示します。 -v
または --verbose
オプションを指定することによりLambda関数以外のAWSリソースも表示可能です。出力結果は以下の通りです。
$ sls info \ --stage dev \ --region ap-northeast-1 \ --verbose Service Information service: test-service stage: dev region: ap-northeast-1 api keys: None endpoints: None functions: test-service-dev-hello: arn:aws:lambda:ap-northeast-1:************:function:test-service-dev-hello Stack Outputs HelloLambdaFunctionArn: arn:aws:lambda:ap-northeast-1:************:function:test-service-dev-hello HelloLambdaFunctionQualifiedArn: arn:aws:lambda:ap-northeast-1:************:function:test-service-dev-hello:8 ServerlessDeploymentBucketName: test-service-dev-serverlessdeploymentbucket-17ru2k5afzf0j
AWS SAMであれば以下のコマンドで確認可能です。
# スタックで作成されたリソースを全て表示 $ aws cloudformation describe-stack-resources \ --stack-name test-service-dev \ --region ap-northeast-1 { "StackResources": [ { "StackId": "arn:aws:cloudformation:ap-northeast-1:************:stack/test-service-dev/178981e0-c40f-11e6-9798-50a6866998ae", "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::Lambda::Function", "Timestamp": "2016-12-17T04:13:59.215Z", "StackName": "test-service-dev", "PhysicalResourceId": "test-service-dev-hello", "LogicalResourceId": "HelloLambdaFunction" }, { "StackId": "arn:aws:cloudformation:ap-northeast-1:************:stack/test-service-dev/178981e0-c40f-11e6-9798-50a6866998ae", "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::Lambda::Version", "Timestamp": "2016-12-17T04:14:04.764Z", "StackName": "test-service-dev", "PhysicalResourceId": "arn:aws:lambda:ap-northeast-1:************:function:test-service-dev-hello:8", "LogicalResourceId": "HelloLambdaVersionfiJylhhWqgsYsPlPvp6YHrfw4m1A56Vq4s2u2I4g4c0" }, { "StackId": "arn:aws:cloudformation:ap-northeast-1:************:stack/test-service-dev/178981e0-c40f-11e6-9798-50a6866998ae", "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::IAM::Policy", "Timestamp": "2016-12-17T04:13:53.734Z", "StackName": "test-service-dev", "PhysicalResourceId": "test-IamP-RYMM19CZ8FLL", "LogicalResourceId": "IamPolicyLambdaExecution" }, { "StackId": "arn:aws:cloudformation:ap-northeast-1:************:stack/test-service-dev/178981e0-c40f-11e6-9798-50a6866998ae", "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::IAM::Role", "Timestamp": "2016-12-17T04:13:49.275Z", "StackName": "test-service-dev", "PhysicalResourceId": "test-service-dev-ap-northeast-1-lambdaRole", "LogicalResourceId": "IamRoleLambdaExecution" }, { "StackId": "arn:aws:cloudformation:ap-northeast-1:************:stack/test-service-dev/178981e0-c40f-11e6-9798-50a6866998ae", "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::S3::Bucket", "Timestamp": "2016-12-17T04:13:25.136Z", "StackName": "test-service-dev", "PhysicalResourceId": "test-service-dev-serverlessdeploymentbucket-17ru2k5afzf0j", "LogicalResourceId": "ServerlessDeploymentBucket" } ] } # 特定のリソースのみ表示 $ aws cloudformation describe-stack-resource \ --stack-name test-service-dev \ --logical-resource-id HelloLambdaFunction \ --region ap-northeast-1 { "StackResourceDetail": { "StackId": "arn:aws:cloudformation:ap-northeast-1:************:stack/test-service-dev/178981e0-c40f-11e6-9798-50a6866998ae", "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::Lambda::Function", "LastUpdatedTimestamp": "2016-12-17T04:13:59.215Z", "StackName": "test-service-dev", "PhysicalResourceId": "test-service-dev-hello", "Metadata": "{}\n", "LogicalResourceId": "HelloLambdaFunction" } }
logs
特定Lambda関数のCloudWatch Logsに出力された実行ログを標準出力に表示します。 -t
または --tail
でログを出力し続けられるという点が扱いやすいと思います。実行結果は以下の通りです。
$ sls logs \ --function hello \ --stage dev \ --region ap-northeast-1 \ --startTime 1m \ --tail START RequestId: 200810b6-c417-11e6-b063-41cba50e39d3 Version: $LATEST {'body': '{"input": {"Message": "Invoke 1"}, "message": "Go Serverless v1.0! Your function executed successfully!"}', 'statusCode': 200} END RequestId: 200810b6-c417-11e6-b063-41cba50e39d3 REPORT RequestId: 200810b6-c417-11e6-b063-41cba50e39d3 Duration: 0.23 ms Billed Duration: 100 ms Memory Size: 1024 MB Max Memory Used: 15 MB START RequestId: 2dd53c59-c417-11e6-8614-fff3243690ae Version: $LATEST {'body': '{"input": {"Message": "Invoke 2"}, "message": "Go Serverless v1.0! Your function executed successfully!"}', 'statusCode': 200} END RequestId: 2dd53c59-c417-11e6-8614-fff3243690ae REPORT RequestId: 2dd53c59-c417-11e6-8614-fff3243690ae Duration: 0.39 ms Billed Duration: 100 ms Memory Size: 1024 MB Max Memory Used: 15 MB
AWS SAMで同等のことをやる場合は aws logs get-log-events
でOKです。ただし -t
オプションのようなものはデフォルトで用意されていません。そのまま実行すると一時点のログをダンプするだけです。
$ aws logs get-log-events \ --log-group-name /aws/lambda/test-service-dev-hello \ --log-stream-name '2016/12/17/[$LATEST]fa7c9fbf72134771bdf38bb8eab4e17e' { "nextForwardToken": "f/33048960342271083447829681146392450088141425484896075778", "events": [ { "ingestionTime": 1481966471040, "timestamp": 1481966455994, "message": "START RequestId: 1d2bdde5-c43a-11e6-ae32-8f74f28d8d59 Version: $LATEST\n" }, { "ingestionTime": 1481966471040, "timestamp": 1481966455994, "message": "{'body': '{\"input\": {\"Message\": \"Invoke 1\"}, \"message\": \"Go Serverless v1.0! Your function executed successfully!\"}', 'statusCode': 200}\n" }, { "ingestionTime": 1481966471040, "timestamp": 1481966455994, "message": "END RequestId: 1d2bdde5-c43a-11e6-ae32-8f74f28d8d59\n" }, <snip>
もし継続してログを表示し続けたい場合は nextForwardToken
をゴニョゴニョする必要がありそうです。シェルスクリプトにしないとちょっとシンドいですね。。。
metrics
サービスまたは特定のLambda関数メトリクスを表示するコマンドです。実行結果は以下の通りです。
# サービス全体のメトリクスを表示 $ sls metrics \ --stage dev \ --region ap-northeast-1 Service wide metrics December 16, 2016 6:37 PM - December 17, 2016 6:37 PM Invocations: 81 Throttles: 0 Errors: 0 Duration (avg.): 0.83ms # 特定のLambda関数メトリクスを表示 $ sls metrics \ --function hello2 \ --stage dev \ --region ap-northeast-1 test-service-dev-hello2 December 16, 2016 6:37 PM - December 17, 2016 6:37 PM Invocations: 1 Throttles: 0 Errors: 0 Duration (avg.): 0.19ms
AWS SAMでは aws cloudwatch get-metric-statistics
で同等の内容を取得可能です。ただし、 --metric-name
オプションは引数を一つしか指定できないため、同時に複数のメトリクスを表示することはできません。また、出力はデータポイント毎に表示されるため合計値を取得したい場合は --query
でパースしてゴニョゴニョする必要があります。
$ aws cloudwatch get-metric-statistics \ --namespace AWS/Lambda \ --metric-name Invocations \ --start-time "$(date -v1d '+%FT%T%z')" \ --end-time "$(date '+%FT%T%z')" \ --period 3600 \ --statistics Sum \ --dimensions Name=FunctionName,Value=test-service-dev-hello2 { "Datapoints": [ { "Timestamp": "2016-12-17T09:10:00Z", "Sum": 1.0, "Unit": "Count" } ], "Label": "Invocations" }
--dimensions
オプションは同時に複数指定可能なので、がんばればAWS SAMでデプロイしたLambda関数全て(Serverless Frameworkのようにサービスワイドに)メトリクスを表示することは「一応」可能です。
remove
デプロイしたサービスを削除するためのコマンドです。実行結果は以下の通りです。
$ sls remove \ --stage dev \ --region ap-northeast-1 \ --verbose Serverless: Getting all objects in S3 bucket... Serverless: Removing objects in S3 bucket... Serverless: Removing Stack... Serverless: Checking Stack removal progress... CloudFormation - DELETE_IN_PROGRESS - AWS::CloudFormation::Stack - test-service-dev CloudFormation - DELETE_SKIPPED - AWS::Lambda::Version - Hello2LambdaVersionXL8T4q21BMVArjUZnPZ8H8gWpEJGeVoqJjakvY9nZ0 CloudFormation - DELETE_SKIPPED - AWS::Lambda::Version - HelloLambdaVersionXL8T4q21BMVArjUZnPZ8H8gWpEJGeVoqJjakvY9nZ0 CloudFormation - DELETE_IN_PROGRESS - AWS::Lambda::Function - Hello2LambdaFunction CloudFormation - DELETE_IN_PROGRESS - AWS::Lambda::Function - HelloLambdaFunction CloudFormation - DELETE_COMPLETE - AWS::Lambda::Function - Hello2LambdaFunction CloudFormation - DELETE_COMPLETE - AWS::Lambda::Function - HelloLambdaFunction CloudFormation - DELETE_IN_PROGRESS - AWS::S3::Bucket - ServerlessDeploymentBucket CloudFormation - DELETE_IN_PROGRESS - AWS::IAM::Policy - IamPolicyLambdaExecution CloudFormation - DELETE_COMPLETE - AWS::IAM::Policy - IamPolicyLambdaExecution CloudFormation - DELETE_IN_PROGRESS - AWS::IAM::Role - IamRoleLambdaExecution CloudFormation - DELETE_COMPLETE - AWS::IAM::Role - IamRoleLambdaExecution Serverless: Stack removal finished...
AWS SAMの場合は単純にスタックを削除すればOKですね。何も出力してくれないのがちょっと物足りないですが。。。
$ aws cloudformation delete-stack \ --stack-name test-sam \ --region ap-northeast-1
注意点として、AWS SAMでデプロイしたスタックにはアーティファクトを設置するS3バケットが含まれないため、アーティファクト自体は残り続けます。不要な場合は別途 aws s3 rm
などで削除する必要があります。
rollback
デプロイしたサービスを特定のバージョンにロールバックするためのコマンドです。ロールバック可能なバージョンは sls deploy list
で確認できます。コマンド実行後、 sls info
などでバージョンが変更されたことを確認可能です。実行結果は以下の通りです。
# ロールバック可能なバージョンを確認 $ sls deploy list \ --stage dev \ --region ap-northeast-1 Serverless: Listing deployments: Serverless: ------------- Serverless: Timestamp: 1481970768486 Serverless: Datetime: 2016-12-17T10:32:48.486Z Serverless: Files: Serverless: - compiled-cloudformation-template.json Serverless: - test-service.zip Serverless: ------------- Serverless: Timestamp: 1481970854329 Serverless: Datetime: 2016-12-17T10:34:14.329Z Serverless: Files: Serverless: - compiled-cloudformation-template.json Serverless: - test-service.zip # 一つ前のバージョンにロールバック $ sls rollback \ --timestamp 1481970768486 \ --stage dev \ --region ap-northeast-1 \ --verbose Serverless: Updating Stack... Serverless: Checking Stack update progress... CloudFormation - UPDATE_IN_PROGRESS - AWS::CloudFormation::Stack - test-service-dev CloudFormation - UPDATE_IN_PROGRESS - AWS::Lambda::Function - HelloLambdaFunction CloudFormation - UPDATE_COMPLETE - AWS::Lambda::Function - HelloLambdaFunction CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Version - HelloLambdaVersiondlrDajrtLvznrNAJq89sA9kEeYEObNrIRqlkCSMDPOM CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Version - HelloLambdaVersiondlrDajrtLvznrNAJq89sA9kEeYEObNrIRqlkCSMDPOM CloudFormation - CREATE_COMPLETE - AWS::Lambda::Version - HelloLambdaVersiondlrDajrtLvznrNAJq89sA9kEeYEObNrIRqlkCSMDPOM CloudFormation - UPDATE_COMPLETE_CLEANUP_IN_PROGRESS - AWS::CloudFormation::Stack - test-service-dev CloudFormation - DELETE_COMPLETE - AWS::Lambda::Version - HelloLambdaVersionT3pb90H1XG0nldLH7QHVZEW0uh3ma4m8oVIidMnGyYA CloudFormation - UPDATE_COMPLETE - AWS::CloudFormation::Stack - test-service-dev Serverless: Stack update finished...
AWS SAMの場合、Serverless Frameworkのように1つの機能として特定のバージョンにスタックをロールバックさせるという機能は現状提供されていません。似たようなことをしたいのであれば、 aws cloudformation package
で生成されたCloudFormationテンプレートを保存しておき、特定のテンプレートでスタックをアップデートさせるという方法で擬似的にロールバックは可能です。
slstats
Serverless Frameworkの利用状況などを送信するかどうかをスイッチさせるコマンドです。設定ファイルは ~/.serverless
ディレクトリ以下に置かれます。実行結果は以下の通りです。
$ sls slstats \ --enable Serverless: Stats successfully enabled $ sls slstats \ --disable Serverless: Stats successfully disabled
これはServerless Framework特有のものなので、当然ですがAWS SAMにはありません。
まとめ
いかがだったでしょうか。
Serverless FrameworkとAWS SAM(正確にはAWS CLI)のコマンドをまとめてみました。専用のコマンドが用意されている分、やはり扱いやすさと出力の見やすさという点ではServerless Frameworkに分があるという印象が個人的には強いです。AWS SAMが今後発展していくためにはこの部分の整備が必須だなと考えています。例えば、専用のコマンドを用意するのもいいと思いますし、あくまでAWS CLIを利用するのであれば aws sam ...
といった形でネームスペースを分けて専用のサブコマンドを用意して欲しいです。きっとAWSさんならやってくれる!と信じて今後もAWS SAMの動向に注目していきたいと思います!
本エントリがみなさんの参考になったら幸いに思います。