最近よく聞く Serverless Framework の Quick Start を試してみた.
v1 系と v0 系 で全然違うデザインになっていて,Quick Start の手順すら違う.試してみた系の記事をいくつか読んでみたけど,結構 v0 系が多く,具体的に言うと serverless project create
で初期化してる手順は v0 系.今回は v1 で試した.
Quick Start
README.md
に書かれている Quick Start をそのまま試してみた.まずは npm でインストールすると,今回は最新の 1.0.0-beta.1.1
がインストールされた.
$ npm install -g serverless@beta $ serverless --version 1.0.0-beta.1.1
次に service を初期化する.ちなみに事前に AWS 側で IAM ユーザーを作成しておく必要があって,今回は指示通りに AdministratorAccess 権限を付与したけど,運用を考えると良くないので,試した後に破棄した.
$ export AWS_ACCESS_KEY_ID=xxx $ export AWS_SECRET_ACCESS_KEY=xxx $ mkdir my-first-service && cd my-first-service $ serverless create --template aws-nodejs Serverless: Creating new Serverless service... _______ __ | _ .-----.----.--.--.-----.----| .-----.-----.-----. | |___| -__| _| | | -__| _| | -__|__ --|__ --| |____ |_____|__| \___/|_____|__| |__|_____|_____|_____| | | | The Serverless Application Framework | | serverless.com, v1.0.0-beta.1.1 -------' Serverless: Successfully created service in the current directory Serverless: with template: "aws-nodejs" Serverless: NOTE: Please update the "service" property in serverless.yml with your service name
Quick Start には書かれていないけど,デフォルトだとバージニアリージョンでリソースが立ち上がってしまうため,serverless.yml
に以下を追記する.そうすると,東京リージョンでリソースが立ち上がるようになる.実は環境変数 AWS_DEFAULT_REGION
も設定して試してみたけど,そこは考慮されてなく,あくまで serverless.yml
の値だけを参照している感じだった.
defaults: region: ap-northeast-1
さっそくデプロイをすると,Stack とあるように CloudFormation を使って,S3 や Lambda を操作していることがわかる.スゴイ…!
$ serverless deploy Serverless: Creating Stack... Serverless: Checking stack creation progress... ................. Serverless: Stack successfully created. Serverless: Zipping service... Serverless: Uploading .zip file to S3... Serverless: Updating Stack... Serverless: Checking stack update progress... ... Serverless: Deployment successful! Service Information service: aws-nodejs stage: dev region: ap-northeast-1 endpoints: None functions: aws-nodejs-dev-hello: arn:aws:lambda:ap-northeast-1:${account-id}:function:aws-nodejs-dev-hello
さらに serverless invoke
で Lambda 関数を実行することができた.
$ serverless invoke --function hello { "message": "Go Serverless v1.0! Your function executed successfully!", "event": {} }
追加で API Gateway もデプロイしてみる
せっかくなら API Gateway もデプロイしてみたいなと思って,Quick Start からは脱線して,serverless.yml
に以下の events を追記した.
functions: hello: handler: handler.hello + events: + - http: + path: hello + method: get
同じようにデプロイをすると,今度は endpoints に URL が入っていた.こんなに簡単に API Gateway を操作できるのか!
$ serverless deploy Serverless: Zipping service... Serverless: Uploading .zip file to S3... Serverless: Updating Stack... Serverless: Checking stack update progress... ..... Serverless: Deployment successful! Service Information service: aws-nodejs stage: dev region: ap-northeast-1 endpoints: GET - https://6po128b3qe.execute-api.ap-northeast-1.amazonaws.com/dev/hello functions: aws-nodejs-dev-hello: arn:aws:lambda:ap-northeast-1:${account-id}:function:aws-nodejs-dev-hello
API を叩いてみたら,普通に返ってきた.
$ curl -s https://6po128b3qe.execute-api.ap-northeast-1.amazonaws.com/dev/hello | jq . { "message": "Go Serverless v1.0! Your function executed successfully!", "event": { "body": {}, "method": "GET", "principalId": "", "headers": { "Accept": "*/*", "CloudFront-Forwarded-Proto": "https", "CloudFront-Is-Desktop-Viewer": "true", "CloudFront-Is-Mobile-Viewer": "false", "CloudFront-Is-SmartTV-Viewer": "false", "CloudFront-Is-Tablet-Viewer": "false", "CloudFront-Viewer-Country": "JP", "Host": "6po128b3qe.execute-api.ap-northeast-1.amazonaws.com", "User-Agent": "curl/7.43.0", "Via": "1.1 159df6785a5f32228becb5f676dbc4f3.cloudfront.net (CloudFront)", "X-Amz-Cf-Id": "1BsBy0g7mLx3VFYL4rBI04m50GiRaYP614wmcW5yH-6mwYc_ZpeaTw==", "X-Forwarded-For": "xxx.xxx.xxx.xxx, xxx.xxx.xxx.xxx", "X-Forwarded-Port": "443", "X-Forwarded-Proto": "https" }, "query": {}, "path": {}, "identity": { "cognitoIdentityPoolId": "", "accountId": "", "cognitoIdentityId": "", "caller": "", "apiKey": "", "sourceIp": "xxx.xxx.xxx.xxx", "cognitoAuthenticationType": "", "cognitoAuthenticationProvider": "", "userArn": "", "userAgent": "curl/7.43.0", "user": "" }, "stageVariables": {} } }
API Gateway の管理コンソールを見たら,ちゃんとリソースが定義されていた.
リソース削除も簡単にできる
リソースが残ってしまう心配もしなくて良くて,remove サブコマンドであっさりと消えてしまった.IAM で AdministratorAccess を与えてたから,実行するときはちょっと怖かったけど.
$ serverless remove Serverless: Getting all objects in S3 bucket... Serverless: Removing objects in S3 bucket... Serverless: Removing Stack... Serverless: Checking stack removal progress... ......... Serverless: Resource removal successful!
という感じに,何もハマることなく,Quick Start を試すことができた.
CloudFormation のスタックを見てみた
最初の serverless deploy
で生成された AWS リソースは以下だった.
- AWS::IAM::Policy
- AWS::IAM::Role
- AWS::S3::Bucket
- AWS::Lambda::Function
適用されていた CloudFormation テンプレートは以下だった.S3 にアップロードされた aws-nodejs-1471105389531.zip
を Lambda にデプロイしていることもわかった.
{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "The AWS CloudFormation template for this Serverless application's resources outside of Lambdas and Api Gateway", "Resources": { "ServerlessDeploymentBucket": { "Type": "AWS::S3::Bucket" }, "IamRoleLambda": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" ] }, "Action": [ "sts:AssumeRole" ] } ] }, "Path": "/" } }, "IamPolicyLambda": { "Type": "AWS::IAM::Policy", "Properties": { "PolicyName": "dev-aws-nodejs-lambda", "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "arn:aws:logs:ap-northeast-1:*:*" } ] }, "Roles": [ { "Ref": "IamRoleLambda" } ] } }, "hello": { "Type": "AWS::Lambda::Function", "Properties": { "Code": { "S3Bucket": { "Ref": "ServerlessDeploymentBucket" }, "S3Key": "aws-nodejs-1471105389531.zip" }, "FunctionName": "aws-nodejs-dev-hello", "Handler": "handler.hello", "MemorySize": 1024, "Role": { "Fn::GetAtt": [ "IamRoleLambda", "Arn" ] }, "Runtime": "nodejs4.3", "Timeout": 6 } } }, "Outputs": { "ServerlessDeploymentBucketName": { "Value": { "Ref": "ServerlessDeploymentBucket" } }, "Function1Arn": { "Description": "Lambda function info", "Value": { "Fn::GetAtt": [ "hello", "Arn" ] } } } }
追加で API Gateway をデプロイした後の serverless deploy
で生成された AWS リソースは以下だった.そのまんまだけど,API Gateway のリソースが追加されていた.
- AWS::ApiGateway::Deployment
- AWS::ApiGateway::Method
- AWS::IAM::Policy
- AWS::IAM::Role
- AWS::ApiGateway::Resource
- AWS::ApiGateway::RestApi
- AWS::S3::Bucket
- AWS::Lambda::Function
- AWS::Lambda::Permission
IAM に関して感じたこと
Quick Start だとしても IAM に AdministratorAccess 権限を与えるのは危険だと感じたけど,ドキュメントには一応理由が書かれていた.絶賛開発中とは言え,もうそれなりに認知されてるフレームワークだし,必要な権限を洗い出すことぐらいはできそうとは思った.AdministratorAccess 権限が与えられてる IAM で aws configure
をしてしまうと,無意識に全ての操作ができてしまうので,上に書いた通り,一時的に環境変数を export して使う方が良さそう.
- 本番環境では権限を絞って欲しい
- 開発が早すぎて,必要な権限を伝えられない
- API Keys は安全に管理して欲しい
Note: In a production environment we recommend reducing the permissions to the IAM User which the Framework uses. Unfortunately, the frameworks functionality is growing so fast, we can’t yet offer you a finite set of permissions it needs. In the interim, ensure that your AWS API Keys are kept in a safe, private location. https://github.com/serverless/serverless/blob/master/docs/guide/provider-account-setup.md
まとめ
Serverless Framework の Quick Start を試してみた.ここまで簡単に Lambda + API Gateway の環境が構築できてしまうと,今までのオペレーションは何だったのかと思ってしまうし,かなり良いのではないかなと思った.実際にドキュメントを見ると,設定可能な項目がたくさんあるし,プラグインもあるらしい.あと,現在は Lambda だけだけど, Azure Functions / Google CloudFunctions / IBM OpenWhisk も対応する予定らしく,クラウドプラットフォームを横断的に使えるフレームワークを目指していることがわかった.スゴイ…!(2回目)
関連記事
この前の「実践 SERVERLESS 勉強会」で知った Apex / Chalice / Flourish など類似の管理ツールもあって,比較できるぐらいには使ってみようと思う.
クラウドインフラ Podcast でも Serverless アーキテクチャの話があって,Serverless Framework のことも言及されていた.個人的にクラウドインフラ Podcast が超勉強になってて,数回聞き直したりしているほどのお気に入り!
あと秋に ServerlessConf Tokyo が開催される!絶対行こうと思ってる :)