Serverless Frameworkのデプロイ周りを調べたのでまとめる

はじめに

Serverless Frameworkのデプロイ周りについてまとめた。内容は公式ドキュメントを元にしている。

Serverless Frameworkでは様々な対象にデプロイが可能だが、本記事ではAWSへのデプロイについて取り扱う。

また、本記事では以下の記事のhello-worldアプリを使っている。

gkuga.hatenablog.com

Serverless Frameworkのデプロイ

Serverless Frameworkでは、クラウドインフラの設定をserverless.ymlに書く。これはCLIにより1つのAWS CloudFormationテンプレートへと変換される。デプロイメントの時もこのCloudFormationを使う。

デプロイ方法にはchangesetsdirectの2種類がある。serverless.ymlのproviderに指定する。changesetsはリソースの変更前に何が変更されるかわかる仕組みだが、serverless frameworkで挙動がよくわからなかった。changesetsを指定してデプロイしてみたが、Change Setのリソースは作られたようだが、変更がある時にデプロイを一度止める方法はわからなかった。ドキュメントに書いてあったがdirectが推奨なようだ。

provider:
  name: aws
  deploymentMethod: direct

詳しくはCloudFormationのChange Setを利用したスタックの更新直接のスタック更新を参照。

serverless deploy

deployコマンドでdeploymentMethodに指定した方法でデプロイがされる。--verbose, -vでデプロイの詳細が見れる。

$ serverless deploy --verbose

Deploying hello-world to stage dev (us-east-1)

Packaging
Excluding development dependencies for service package
Retrieving CloudFormation stack

No changes to deploy. Deployment skipped. (6s)

Improve API performance – monitor it with the Serverless Dashboard: run "serverless"

ここではDeployment skippedと表示されたが、私が既にデプロイを実行していたので、以下の機能が動作したようだ。

Serverless fetches the hashes for all files of the previous deployment (if any) and compares them against the hashes of the local files. Serverless terminates the deployment process if all file hashes are the same.

デプロイされたリソースのハッシュと、デプロイしようとするリソースのハッシュが違う時のみデプロイされる。

package

packageコマンドにより関数はzip化され、serverless.ymlはAWS CloudFormationテンプレートへと変換される。serverless deployではまずpackageが実行されて、その生成物がデプロイされるようになっている。生成物は.serverlessディレクトリに格納される。また、生成されたものはserverless deploy --package .serverlessによりデプロイ可能である。

$ serverless package

Packaging hello-world for stage dev (us-east-1)

✔ Service packaged (0s)
$ ls .serverless
cloudformation-template-create-stack.json hello-world.zip
cloudformation-template-update-stack.json serverless-state.json
$ serverless deploy --package .serverless

Deploying hello-world to stage dev (us-east-1)

No changes to deploy. Deployment skipped. (6s)

関数のみのデプロイ

serverless deploy --function <関数名>とすると関数のみをデプロイできる。これはCloudFormationを使わず直接Lambdaにアップロードするためより早くデプロイができる。CloudFormationを使わない分、整合性が担保されないため、開発時に使うことが想定されている。

$ serverless deploy --function hello

Deploying function hello to stage dev (us-east-1)

Code did not change. Function deployment skipped. (0s)
Configuration did not change. Configuration update skipped. (0s)

また、serverless deploy function -f functionNameというコマンドもある。違いについてドキュメントに記述を見つけられなかったが恐らく同じだろう。

ステージ

ステージという概念があり、dev, stag, prodなどデプロイ先の環境を分けるのに使う。今までのデプロイでは何も指定していなかったが、デフォルトでdevステージとus-east-1リージョンにデプロイされる。環境とリージョンはserverless.ymlで指定するかコマンドラインからも指定できる。

$ serverless deploy --stage production --region ap-northeast-1

Deploying hello-world to stage production (ap-northeast-1)

✔ Service deployed to stack hello-world-production (106s)

endpoint: GET - https://xxxxx.execute-api.ap-northeast-1.amazonaws.com/
functions:
  hello: hello-world-production-hello (7.2 kB)

デプロイメントの情報

デプロイされたものの情報一覧が見たいと思って関連コマンドを探した。

いずれもステージとリージョンを指定するので、全ての一覧を取得したい場合はどうすればいいのだろうか。

おわりに

packageコマンドを使えば、デプロイに必要なものが生成されるのでCIとCDを分けるのに使えそうだ。