やったこと
Serverless Frameworkを使って CloudFunctionを動かしてみました。 試した内容は下記の通りです。
- TypeScriptで書けるようにしてみる
- serverless.ymlの設定で環境変数を利用する
- 日本のリージョンにDeployする
実際に利用したコード https://github.com/selmertsx/study/tree/master/serverless/cloudfunction-sls-sample
前提
https://serverless.com/framework/docs/providers/google/guide/quick-start/
上記チュートリアルを実行して、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の設定で環境変数を利用する
https://serverless.com/framework/docs/providers/google/guide/variables/
公式ドキュメントを見ると、ymlやjsとして別のファイルに切り出したり、serverless.dev.ymlのように環境毎にymlを分けたりする方法が書かれています。今回はgitにcommitしたくないコードの管理がしたかったので、ちょっとその用途とは違うため別の方法を模索しました。
https://serverless.com/framework/docs/providers/aws/guide/variables/
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を触ってみないとなんとも言えない
コミットチャンス
- deploy後に表示されるリージョンと、実際にdeployされるリージョンが異なる
- googleのvariables部分にて、${env:SOME_VAR} の説明がない
- serverless frameworkのドキュメントちょいちょいリンク切れてる
宿題
- credentialsや環境変数をcode buildなどから扱えるようにしたい
- cloud functionに渡す権限を、もっとちゃんと整理したい