Serverless Framework
Serverless Framework はAWSやAzure, GCPなど各種クラウドプロバイダのサーバーレスコンポーネントのデプロイを管理するOSSのフレームワークです。 例えばAWSではCloudFormationで頑張るよりはるかに学習コストが低く、開発・デプロイ・運用を軽緑化してくれます。 開発も盛んで新機能への追随も早く、プラグインという形で機能が add-on されることもあります。 また、一部プラグインを活用すれば、オフラインでのエミュレーションも可能になり、実際のクラウドへのデプロイをする前に様々なテストを行うこともできます。
serverless framework を試す
- localでどこまでテストできる?したい?と考えた時、やっぱり serverless framework かなとなる: AWSでServerlessの環境をCIするための選択肢を調べたメモ
- serverless framework 使い方勉強
- Serverless アプリケーションをローカルで開発する をみる
- credential, region, stage のデフォルトと選択を追加したかったので、 これ 見てやった。
AWS 開発環境
- secret 等を web console で確認
- ~/.aws 配下に credentials を置く
Node.js の環境整備
project_dir で, node.js, ndenv のインストール (mac 確認済, win, linux 未確認)
cd /path/to/project_dir/
ndenv install v6.10.3
ndenv local v6.10.3
npm install
Serverless Framework の導入
npm install -g serverless
- shell コマンド使うのでパスが通れば良い (上記のような global install, homedirに入れる, project dir に入れて package.json で頑張る, etc.)
cd project_dir
DynamoDB Local, Serverless Offline を使ったローカル開発
- DynamoDB Local の初回インストール.
sls dynamodb install --region <region> --profile <profile> --stage <stage>
- DynamoDB Local の起動
sls dynamodb start --region <region> --profile <profile> --stage <stage>
- 起動しっぱなしにしておく必要がある
- なお、起動のたびに seed (= 初期登録用データ) が登録される. seed は
migrations/***.json
に記述するようにしてる
- Serverless Offline の起動
sls offline --region <region> --profile <profile> --stage <stage>
- 起動しっぱなしにしておく必要がある
この状態で好き勝手に localhost:3000 がAPI Gateway相当になるので、好き勝手 POST,GET,DELETE して開発できるze!
serverless offline 環境特有の注意点
region, profile, stage オプションに注意してデプロイしましょう。 local 開発環境だけであれば本来これらオプションは不要なのですが、商用へのデプロイの際にオプション変えるだけで同じようにデプロイできる利便性を考えた結果、都度オプション指定が必要になっちゃいました。 (default 値も指定可能だがオプション値を意識付けするためあえてやってない)
sls offline が Lambda にリクエストを転送する時,
event.isOffline: true
が付与される。これでいろいろ条件分岐しています- recursive request を抑制する
- ログ出力関数も抑制する
recursive request や log の確認をしたい場合は、この辺の条件分岐を一時変更するようにしてください。 recursive request 先をどこにするかも要注意。
sls remove して sls deploy すると、新しいAPIGWリソースになるため URL が変わる
DynamoDB のスキーマに関わるような変更を加えた場合、 table を削除してから作り直す必要がある場合があります
offline の Lambda が本物の AWS サービスと連携する際の credentials profile の注意点 (2019/09/13)
deploy された Lambda は
serverless.yml
のiamRoleStatements
セクションを見るしかし、 offline ではローカルの
default AWS profile
を見る!However, serverless offline makes use of your local AWS profile credentials to run the lambda functions and that might result in a different set of permissions. By default, the aws-sdk would load credentials for you default AWS profile specified in your configuration file.
対策は2択:
- 環境変数
AWS_PROFILE
を宣言 (しばらくはこれやるしか無いなぁ)AWS_PROFILE=<profile> serverless offline
- 何かしらコードに書く
- 環境変数
この issue で、
sls deploy
みたく--profile
オプション作ってそこから読み込んでほしいという要望が上がっているので僅かな望みをかけて watching: Support for AWS credential profiles
test, coverage
test framework は mocha を採用しています. カバレッジの計測には istanbul
を使っています. 個人的に Ruby でなれた rspec, simple-cov に似ているから使ってるって感じです。
package.json
に以下のように script として登録している"scripts": { "test": "mocha -R spec test/index.test.js", "test-watch": "mocha -wR spec test/index.test.js", "test-cov": "istanbul cover --print both _mocha -- test/index.test.js" }
実行コマンド: scripts に登録しているので簡単
npm run test ※単発実行 npm run test-watch ※変更が保存されるたびに実行 npm run test-cov ※カバレッジ計測
常にテストを走らせながら開発できるので
-w
(watch) は非常に便利ですね。テストの内容
- api を叩いているというより、直接 Lambda 関数の入出力をテストしています。 APIを実際に叩く形式にしてもいいかも。
カバレッジ
- index.html が生成されるのでそれをブラウザで開けば大丈夫
AWS へのデプロイ: APIGW, Lambda, DynamoDB, CloudWatch
その前に: IAM 設定
- cloudFormation 使うがそのままだと権限が足りない。以下のカスタムポリシーをJSONから作って user に割り当てる (ちなみに反映から数秒は待ちが必要). なお、
serverless.yml
に書き込めばいいとも思ったが、 sls deploy 自体が CloudFormation 経由だからだめ.{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "cloudformation:DescribeStacks", "cloudformation:DescribeStackEvents", "cloudformation:DescribeStackResource", "cloudformation:DescribeStackResources", "cloudformation:CreateStack", "cloudformation:ValidateTemplate", "cloudformation:UpdateStack", "cloudformation:GetStackPolicy", "cloudformation:ListChangeSets", "cloudformation:ListStacks", "cloudformation:DeleteStack" ], "Resource": "*" } ] }
- cloudFormation 使うがそのままだと権限が足りない。以下のカスタムポリシーをJSONから作って user に割り当てる (ちなみに反映から数秒は待ちが必要). なお、
いよいよデプロイ。 region, profile, stage オプションに注意してデプロイしましょう。
sls deploy --region <region> --profile <profile> --stage <stage>
CloudFront を使うなら、 origin として指定する APIGW の URL を, デプロイしたものに。
DynamoDB のオートスケーリング
serverless frameworkではデフォルトでは autoscaling を disable してしまう! DynamoDB コンソールから設定していたときは default enabled だったから油断していた…
- 対策: serverless framework でオートスケーリングを有効化する
serverless-dynamodb-autoscaling
を導入する. 公式読めばかんたーん. npm install と serverless.yml の設定だけ。
Lambda の timeout
Lambda 関数の実行タイムアウトはデフォルトでは 6秒. serverless では 2018/06月時点では 3 秒がデフォルト. serverless.yaml で設定可能!
sls rollback
sls deploy list
で戻りたい deployment の timestamp を確認し、sls rollback -t <timestamp>
で rollback する。過去に戻ってしまった後も、そこより新しい deployment は維持されるから心配なく行き来できます。- 完全削除: CloudFormation web console からスタックの削除は、せず、
sls remove
コマンドから消すが吉
API-Gateway のロギング
forum でも盛り上がっていて 、 sls の標準対応が望まれる声が募りつつケース close されていない。 暫定?としてプラグインを書いてくれている人がいるので、それを有りがたく使わせてもらう。
- 手順
- AWS アカウント x リージョンごとに必要な Web コンソールからの設定
- Webコンソールにログイン > リージョン選択 > API Gateway 選択 > 設定
CloudWatch ログのロール ARN
を埋めて保存
- serverless.yml で必要な設定
- Knowledge sharing - Enable cloud watch logs for API Gateway using Serverless を参考に以下を追加:
plugins: - serverless-plugin-stage-variables resources: Resources: ApiGatewayStage: Type: AWS::ApiGateway::Stage Properties: MethodSettings: - DataTraceEnabled: true HttpMethod: "*" LoggingLevel: INFO ResourcePath: "/*" MetricsEnabled: true
- Knowledge sharing - Enable cloud watch logs for API Gateway using Serverless を参考に以下を追加:
- AWS アカウント x リージョンごとに必要な Web コンソールからの設定
デプロイされたサービスの情報を参照 (sls info)
sls info
コマンドで一発やで!$ serverless info Service Information service: my-serverless-service stage: dev region: us-east-1 api keys: myKey: some123valid456api789key1011for1213api1415gateway endpoints: GET - https://dxaynpuzd4.execute-api.us-east-1.amazonaws.com/dev/users functions: my-serverless-service-dev-hello
sls info -v
だと Stack Outputs もついてくるよ$ serverless info --verbose Service Information service: my-serverless-service stage: dev region: us-east-1 api keys: myKey: some123valid456api789key1011for1213api1415gateway endpoints: GET - https://dxaynpuzd4.execute-api.us-east-1.amazonaws.com/dev/users functions: my-serverless-service-dev-hello Stack Outputs CloudFrontUrl: d2d10e2tyk1pei.cloudfront.net ScreenshotBucket: dev-svdgraaf-screenshots ServiceEndpoint: https://12341jc801.execute-api.us-east-1.amazonaws.com/dev ServerlessDeploymentBucketName: lambda-screenshots-dev-serverlessdeploymentbucket-15b7pkc04f98a
API-Gateway の URL 確認
sls info
みろsls 使ってるなら
sls info
見るのが一番だけど、 CloudFormation 管理のものはそちらの API を使っても良い。- ベーシックなコマンド:
aws cloudformation describe-stacks --profile hogehoge --region fugafuga
- endpoint url だけを抽出するには jq コマンドで絞る:
aws cloudformation describe-stacks --profile hogehoge --region fugafuga | jq '.Stacks[].Outputs[] | select(.OutputKey == "ServiceEndpoint") | .OutputValue'
- ベーシックなコマンド:
apigateway を直接見る方法:
get-rest-apis
を打ってid
を確認すれば類推できる。https://{id}.execute-api.{region}.amazonaws.com/{stage}
Lambda のみデプロイする
AWS CloudFormation を通さず Lambda のデプロイのみを行う。 CloudFormation スタックが示す zip ファイルを単純にスワップするだけらしい。
注意
- アップロードは速いが、結局 CloudFormation にとっては整合性が取れなくなってしまうため、商用ではおすすめできない。
- とにかく開発中に早く動かすことを目的とするだけなら有効、という感じらしい… serverless-offline を駆使すればあまり必要なさそうだな。
使い方
コマンド
serverless deploy function -f functionName
オプション
--update-config
or-u
: Lambda 関連の設定のみをプッシュする (handler, timeout or memorySize, etc.)