やったこと
Serverless Frameworkを使って CloudFunctionを動かしてみました。
試した内容は下記の通りです。
- TypeScriptで書けるようにしてみる
- serverless.ymlの設定で環境変数を利用する
- 日本のリージョンにDeployする
実際に利用したコード
https://github.com/selmertsx/study/tree/master/serverless/cloudfunction-sls-sample
前提
上記チュートリアルを実行して、nodejsのコードをdeploy & invokeできるようにしてある前提で話を進めます。
TypeScriptで書けるようにする
https://github.com/prisma/serverless-plugin-typescript
このpluginを利用します。
手順は簡単で、下記の手順を踏むだけで設定可能です
- serverless.yml のpluginsに
serverless-plugin-typescript
を追加する - 指定されたフォーマットでtsconfig.jsonの設定をする
- 既存のコードをTypeScriptに置き換える
- (options) package.jsonのmain fieldを書き換える
plugins:
- serverless-google-cloudfunctions
- serverless-plugin-typescript
// Note: outDir と rootDir optionsを上書きしないこと
{
"compilerOptions": {
"target": "es5",
"outDir": ".build",
"moduleResolution": "node",
"lib": ["es2015"],
"rootDir": "./"
}
}
もし起点となるコードが index.ts でなければ、package.jsonのmain fieldを下記のように書き換える必要があります。
// handler.tsを起点にしたい場合
{
// ...
"main": "handler.js",
// ..
}
serverless.ymlの設定で環境変数を利用する
公式ドキュメントを見ると、ymlやjsとして別のファイルに切り出したり、serverless.dev.ymlのように環境毎にymlを分けたりする方法が書かれています。今回はgitにcommitしたくない設定の管理がしたかったので、違う方法を模索しました。
awsの方のGuideを見てみると、下記のような機能がありました。
o reference environment variables, use the ${env:SOME_VAR} syntax in your serverless.yml configuration file. It is valid to use the empty string in place of SOME_VAR. This looks like "${env:}" and the result of declaring this in your serverless.yml is to embed the complete process.env object (i.e. all the variables defined in your environment).
これについてgoogleでも使えないかと試してみたところ、普通に使えたので今回はそれを利用しました。
service: cloudfunction-sls-sample
provider:
name: google
project: ${env:PROJECT}
日本のリージョンにDeployする
cloud functionsでServerless Frameworkを利用し、regionを何も指定せずにdeployをすると us-central1にdeployがされます。
deploy先のregionをserverless.ymlで設定していきましょう。
deployする先の指定は、serverless-google-cloudfunctionsのv2.0.0 から出来るようになっています。
けれども、sls コマンドでinstallされるversionはv1.2.0なので、pluginのバージョンを上げる必要があります。
"devDependencies": {
"serverless-google-cloudfunctions": "^2.0.0",
"serverless-plugin-typescript": "^1.1.5"
}
その後、serverless.ymlの値を書き換えて実行してみます。
service: cloudfunction-sls-sample
provider:
name: google
region: asia-northeast1
runtime: nodejs8
project: ${env:PROJECT}
実行結果がこちらになります。
$ sls deploy
service: cloudfunction-sls-sample
project: xxx
stage: dev
region: us-central1
Deployed functions
first
https://us-central1-xxx.cloudfunctions.net/http
ぱっと見るとus-central1にdeployされていてギョっとしますが、cliを使って実際にdeployされているregionを確認してみると、ちゃんとasia-northeast1になっていることが確認できます。
gcloud beta functions describe http --region asia-northeast1
availableMemoryMb: 256
entryPoint: http
httpsTrigger:
url: https://asia-northeast1-xxx.cloudfunctions.net/http <==ここをチェック
labels:
goog-dm: sls-cloudfunction-sls-sample-dev
name: projects/xxx/locations/asia-northeast1/functions/http
runtime: nodejs8
serviceAccountEmail: xxx@appspot.gserviceaccount.com
sourceArchiveUrl: gs://sls-cloudfunction-sls-sample-dev-xxx/serverless/cloudfunction-sls-sample/dev/xxx-2018-09-25T10:08:07.390Z/cloudfunction-sls-sample.zip
status: ACTIVE
timeout: 60s
updateTime: '2018
AWS Lambdaと比較した雑感
- localでの動作確認について、lambdaはpluginで提供されているが、cloud functionsはまだない。
- LambdaではTypeScriptテンプレートがあるので、特に何の指定もしなくて良い
- Lambdaは起動するためのeventsが豊富
- cloud functionsはhttpとpub subだけ
- これがcloud functionsのデメリットとなるかは、pub subを触ってみないとなんとも言えない